From: Kern Sibbald Date: Sun, 7 Sep 2008 07:27:10 +0000 (+0000) Subject: Remove tokyocabinet -- not used X-Git-Tag: Release-7.0.0~4169 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=3571e9bf4d93f5b3df5e3d9d0cf99bbfb3fc30d1;p=bacula%2Fbacula Remove tokyocabinet -- not used git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7556 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/lib/tokyocabinet/COPYING b/bacula/src/lib/tokyocabinet/COPYING deleted file mode 100644 index b1e3f5a263..0000000000 --- a/bacula/src/lib/tokyocabinet/COPYING +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -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 this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser 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 Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey 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 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 2.1 of the License, or (at your option) any later version. - - 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/bacula/src/lib/tokyocabinet/ChangeLog b/bacula/src/lib/tokyocabinet/ChangeLog deleted file mode 100644 index 4e8298e3ad..0000000000 --- a/bacula/src/lib/tokyocabinet/ChangeLog +++ /dev/null @@ -1,418 +0,0 @@ -2008-04-22 Mikio Hirabayashi - - * tcbdb.c (tcbdbcmpdecimal, tcbdbcmpint32, tcbdbcmpint64): bugs of overflow were fixed. - - - Release: 1.2.5 - -2008-04-13 Mikio Hirabayashi - - * tcbdb.c (tcbdbopenimpl): comparison function checking was added. - - * tcadb.c (tcadbopen): "capnum" option is now supported for B+ tree. - - - Release: 1.2.4 - -2008-04-07 Mikio Hirabayashi - - * tcutil.c (tcregexmatch, tcregexreplace, tcglobpat): new functions. - - * tcbdb.c (tcbdbcmpfunc, tcbdbcmpop): new functions. - - * tcbdb.c (tcbdboptimizeimpl): leaf size limitation is now implemented. - - * tcbdb.c (tcbdbsetcapnum): new function. - - - Release: 1.2.3 - -2008-03-19 Mikio Hirabayashi - - * tcutil.c (tcmapnew2): "calloc" is now used. - - * tcbdb.c (tcbdbputimpl): algorithm to divide large leaves was modified. - - - Release: 1.2.2 - -2008-03-13 Mikio Hirabayashi - - * tcutil.c (tclistelemcmp, tclistelemcmpci): bugs about multibyte ordering were fixed. - - * tcutil.c (tclistsortex): new function. - - * tcbdb.c (tcbdbsetecode): new function. - - * tcadb.c (tcadbopen): "c", "t", "e", and "w" options were added. - - - Release: 1.2.1 - -2008-02-18 Mikio Hirabayashi - - * tcmdb.c (tcmdbfwmkeys, tcmdbfwmkeys2): new functions. - - * tchdb.c (tchdbfwmkeys, tchdbfwmkeys2): new functions. - - * tcbdb.c (tcbdbfwmkeys, tcbdbfwmkeys2): new functions instead of "tcbdbrange3". - - * tcadb.c (tcadbfwmkeys, tcadbfwmkeys2): new functions. - - * tcbdb.c (tcbdbrangeimpl): a bug related to mutex operation was fixed. - - - The library version was bumped up for some binary packages. - - - Release: 1.2.0 - -2008-02-15 Mikio Hirabayashi - - * tcutil.c (tcbwtsortchrcount): time efficiency was improved. - - - The library version was bumped up for some binary packages. - - - Release: 1.1.15 - -2008-02-05 Mikio Hirabayashi - - * tcatest.c (runwicked, procwicked): new functions. - - - Release: 1.1.14 - -2008-01-30 Mikio Hirabayashi - - * tcutil.c (tctime): measure unit was changed to in seconds. - - * tchdb.c (tchdbcopy): shared lock is now used. - - * tcadb.c (tcadbsync, tcadbcopy): new functions. - - - Release: 1.1.13 - -2008-01-23 Mikio Hirabayashi - - * tcbdb.c (tcbdbleafkill, tcbdbnodesubidx): new functions. - - * tcbtest.c (runqueue, procqueue): new functions. - - - Release: 1.1.12 - -2008-01-20 Mikio Hirabayashi - - * tcutil.c (tcmapmsiz, tcmdbmsiz, tcadbsize): new functions. - - * tcutil.c (tcglobalmutexshared): new function. - - * tcutil.c (tcglobalmutexinit, tcglobalmutexdestroy): new functions. - - * tcutil.c (tcreadfile): a bug related to the size assignment was fixed. - - * tcadb.c (tcadbopen): "capsiz" parameter was added. - - - Release: 1.1.11 - -2008-01-17 Mikio Hirabayashi - - * tcutil.c (tclistshift, tclistshift2): memory alignment was improved. - - * tcutil.c (tcvxstrprintf): a bug related to format of long long integer was fixed. - - - Release: 1.1.10 - -2008-01-10 Mikio Hirabayashi - - * tcutil.c (tcmdbvsiz, tcmdbvsiz2): new functions. - - * tcutil.c (tcmdbiternext): a bug related to handling sparse map was fixed. - - * tcadb.h, tcadb.c: new files. - - * tcatest.c, tcadb.c: new files. - - - Release: 1.1.9 - -2008-01-03 Mikio Hirabayashi - - * tcutil.c (tcstrutftoucs, tcstrucstoutf, tcstrjoin): new function. - - * tcutil.c (tcstrdist, tcstrdistutf): new function. - - - Release: 1.1.8 - -2007-12-28 Mikio Hirabayashi - - * myconf.h: some header includings were removed for environments not conforming to C99. - - * tcutil.c (tctccalendar, tcdatestrwww, tcdatestrhttp): new functions. - - * tcutil.c (tcmapaddint): new function. - - * tcucodec.c (rundate, procdate): new functions. - - - Release: 1.1.7 - -2007-12-24 Mikio Hirabayashi - - * tchdb.c (tcseekread, tcseekwrite): pread and pwrite were to be used. - - - Release: 1.1.6 - -2007-12-21 Mikio Hirabayashi - - * tcutil.c (tcmdbnew, tcmdbput, tcmdbget): concurrency was improved. - - * tcutil.c (tcmapcutfront, tcmdbcutfront): new functions. - - * tchdb.c (tchdbasyncimpl): large deferred buffer was to be flushed. - - * tcumttest.c: new file. - - - Release: 1.1.5 - -2007-12-19 Mikio Hirabayashi - - * tcutil.c (tclrand, tcdrand, tcdrandnd): new functions. - - * tchdb.c (tchdbcacheadjust): count checking was removed. - - * tchmttest.c (myrandnd): new function. - - * tcbmttest.c (myrandnd): new function. - - - Release: 1.1.4 - -2007-12-10 Mikio Hirabayashi - - * tcutil.c (tcglobalmutexlock): the type of the global mutex was changed to rwlock. - - * tchdb.c (tchdbsetmutex, tchdbopenimpl): multiple reading file descriptors were added. - - * tchmttest.c (runtypical, proctypical): reading ratio assignment was added. - - * tcbmttest.c (runtypical, proctypical): reading ratio assignment was added. - - - Release: 1.1.3 - -2007-12-08 Mikio Hirabayashi - - * tcutil.c (tcmpoolput): mutex for operations was added. - - - Release: 1.1.2 - -2007-12-08 Mikio Hirabayashi - - * tcutil.c (tcberencode, tcberdecode): new functions. - - * tcbdb.c (tcbdbleafload): speed was improved. - - - Release: 1.1.1 - -2007-12-07 Mikio Hirabayashi - - * tchdb.c (tchdbsetcache): new function. - - * tchmttest.c (procwrite, procread): random mode was added. - - * tcbmttest.c (procwrite, procread): random mode was added. - - - Release: 1.1.0 - -2007-12-01 Mikio Hirabayashi - - * tchmgr.c (procget): a bug related to the open omode was fixed. - - * tchdb.c (tchdbreadrec): a bug related to overflow on 32-bit environment was fixed. - - * tchdb.c (tchdbgetbucket): the type of the return value was changed. - - * tcbdb.c (tcbdbcurfirst, tcbdbcurnext): cache adjustment was to be performed. - - * tcbdb.c (tcbdbrange, tcbdbrange2, tcbdbrange3): new functions. - - * tchmgr.c (proclist): "-m" option was added. - - * tchmgr.c (procimporttsv): new function. - - * tcbmgr.c (proclist): "-m", "-rb", and "-rp" options were added. - - * tcbmgr.c (procimporttsv): new function. - - - Release: 1.0.9 - -2007-11-28 Mikio Hirabayashi - - * tchmttest.c (threadtypical): a test case was added. - - * tchdb.c (tchdbfbpmerge): a bug related to iterator was fixed. - - * tcbdb.c (tcbdbgetimpl): a bug related to concurrent cache cleaning was fixed. - - - Release: 1.0.8 - -2007-11-20 Mikio Hirabayashi - - * tchdb.c (tchdblockmethod): a bug related to R/W lock was fixed. - - * tcbdb.c (tcbdblockmethod): a bug related to R/W lock was fixed. - - * tchdb.c, tcbdb.c: locking functions were re-imlemented as macros. - - * tchmttest.c, tcbmttest.c: test cases of typical operations were added. - - * tokyocabinet.idl: methods handling list parameters were added. - - - Release: 1.0.7 - -2007-11-15 Mikio Hirabayashi - - * tcbdb.c (tcbdboptimize): the default behaviour of bnum was changed. - - - Release: 1.0.6 - -2007-11-10 Mikio Hirabayashi - - * tcutil.c (tcrealpath, tccopyfile): new functions. - - * tchdb.c (tchdbcopy): new function. - - * tcbdb.c (tcbdbcopy): new function. - - - Release: 1.0.5 - -2007-11-10 Mikio Hirabayashi - - * tcbdb.c (tcbdbtune): comparing functions were optimized with macros. - - * tcbdb.c (tcbdbsetlsmax): new function. - - * myconf.c, tcutil.c, tchdb.c, tcbdb.c: code cleanup and optimization. - - - Release: 1.0.4 - -2007-11-08 Mikio Hirabayashi - - * tcbdb.c (tcbdbleafsave, tcbdbleafload): warnings on 64-bit system were cleared. - - * configure.in: 64-bit offset mode for 32-bit system was added. - - * Makefile.in: Mac OS X is now supported. - - - Release: 1.0.3 - -2007-11-01 Mikio Hirabayashi - - * tcbdb.c (tcbdbdel): a bug that opened database was not closed was fixed. - - * tcbdb.c (tcbdbcurout): a bug of deleting always the first value was fixed. - - * tcbdb.c (tcbdbopenimpl): a potential bug of not initializing meta data was fixed. - - * tcutil.h, tchdb.h, tcbdb.h: wrapped in C linkage block for C++. - - * tokyocabinet.idl: definition of constants were added. - - - commands for performance test were added. - - - Release: 1.0.2 - -2007-10-28 Mikio Hirabayashi - - * tcbdb.c (tchdboptimize): a bug related to custom comparison function was fixed. - - * tcbdb.c (tcbdbleafsave): empty pages was to be removed for time space efficiency. - - * tcbdb.c (tcbdbputdup3): new function. - - * tchdb.c (tchdbvanish): new function. - - * tcbdb.c (tcbdbvanish): new function. - - * tokyocabinet.idl: new file. - - - Release: 1.0.1 - -2007-10-24 Mikio Hirabayashi - - * tokyocabinet.pc.in: new file. - - - document files were fulfilled. - - - Release: 1.0.0 - -2007-10-15 Mikio Hirabayashi - - * tcbdb.c (tchdbtranbegin): locking mode was aolished. - - * tcbdb.c (tcbdbsetcmpfunc): new function. - - - Release: 0.4.1 - -2007-10-11 Mikio Hirabayashi - - * tchdb.c (tchdbopenimpl): database corruption was to be handled automatically. - - * tcbdb.c, tcbtest.c, tcbmttest.c, tcbmgr.c: new files. - - - Release: 0.4.0 - -2007-09-09 Mikio Hirabayashi - - * tchdb.c (tchdbsetmutex, tchdblockobj, tchdbunlockobj): new functions. - - * tchmttest.c: new file. - - - Release: 0.3.4 - -2007-09-05 Mikio Hirabayashi - - * tchdb.c (tchdbopen): TCBS compression mode is now supported. - - - Release: 0.3.3 - -2007-09-01 Mikio Hirabayashi - - * tchdb.c (tcbsencode, tcbsdecode): new functions. - - - Release: 0.3.2 - -2007-08-25 Mikio Hirabayashi - - * tchdb.c (tcpackencode, tcpackdecode): new functions. - - * tchdb.c (tcbwtencode, tcbwtdecode): new functions. - - - Release: 0.3.1 - -2007-08-22 Mikio Hirabayashi - - * tchdb.c (tchdbputasync, tchdbputasync2): new functions. - - - Release: 0.3.0 - -2007-08-18 Mikio Hirabayashi - - * tchdb.c (tchdboptimize): a bug causing data corruption was fixed. - - - Release: 0.2.8 - -2007-08-15 Mikio Hirabayashi - - * tchdb.c (tchdboptimize): new function. - - - Release: 0.2.7 - -2007-08-14 Mikio Hirabayashi - - * tchdb.c (tchdbsavefbp, tchdbloadfbp): a bug related to 64-bit support was fixed. - - * tchdb.c (tchdbreadrec, tchdbwriterec): a bug related to 64-bit support was fixed. - - - Release: 0.2.6 - -2007-08-13 Mikio Hirabayashi - - * tchdb.c (tchdbsavefbp, tchdbloadfbp): new functions. - - - Release: 0.2.5 - -2007-08-12 Mikio Hirabayashi - - - The initial version. - - - Release: 0.2.4 - diff --git a/bacula/src/lib/tokyocabinet/Makefile.in b/bacula/src/lib/tokyocabinet/Makefile.in deleted file mode 100644 index 8e757fa100..0000000000 --- a/bacula/src/lib/tokyocabinet/Makefile.in +++ /dev/null @@ -1,512 +0,0 @@ -# Makefile for Tokyo Cabinet - - - -#================================================================ -# Setting Variables -#================================================================ - - -# Generic settings -SHELL = @SHELL@ - -# Package information -PACKAGE = @PACKAGE_NAME@ -VERSION = @PACKAGE_VERSION@ -PACKAGEDIR = $(PACKAGE)-$(VERSION) -PACKAGETGZ = $(PACKAGE)-$(VERSION).tar.gz -LIBVER = @MYLIBVER@ -LIBREV = @MYLIBREV@ -FORMATVER = @MYFORMATVER@ - -# Targets -HEADERFILES = @MYHEADERFILES@ -LIBRARYFILES = @MYLIBRARYFILES@ -LIBOBJFILES = @MYLIBOBJFILES@ -COMMANDFILES = @MYCOMMANDFILES@ -MAN1FILES = @MYMAN1FILES@ -MAN3FILES = @MYMAN3FILES@ -DOCUMENTFILES = @MYDOCUMENTFILES@ -PCFILES = @MYPCFILES@ - -# Install destinations -prefix = @prefix@ -exec_prefix = @exec_prefix@ -datarootdir = @datarootdir@ -INCLUDEDIR = @includedir@ -LIBDIR = @libdir@ -BINDIR = @bindir@ -LIBEXECDIR = @libexecdir@ -DATADIR = @datadir@/$(PACKAGE) -MAN1DIR = @mandir@/man1 -MAN3DIR = @mandir@/man3 -PCDIR = @libdir@/pkgconfig -DESTDIR = - -# Building configuration -CC = @CC@ -CPPFLAGS = @MYCPPFLAGS@ \ - -D_TC_PREFIX="\"$(prefix)\"" -D_TC_INCLUDEDIR="\"$(INCLUDEDIR)\"" \ - -D_TC_LIBDIR="\"$(LIBDIR)\"" -D_TC_BINDIR="\"$(BINDIR)\"" -D_TC_LIBEXECDIR="\"$(LIBEXECDIR)\"" \ - -D_TC_APPINC="\"-I$(INCLUDEDIR)\"" -D_TC_APPLIBS="\"-L$(LIBDIR) -ltokyocabinet @LIBS@\"" -CFLAGS = @MYCFLAGS@ -LDFLAGS = @MYLDFLAGS@ -LIBS = @LIBS@ -LDENV = LD_RUN_PATH=/lib:/usr/lib:$(LIBDIR):$(HOME)/lib:/usr/local/lib:@MYRUNPATH@:. -RUNENV = @MYLDLIBPATHENV@=.:/lib:/usr/lib:$(LIBDIR):$(HOME)/lib:/usr/local/lib:@MYRUNPATH@ -POSTCMD = @MYPOSTCMD@ -NO_ECHO = @ - - -#================================================================ -# Suffix rules -#================================================================ - - -.SUFFIXES : -.SUFFIXES : .c .o - -.c.o : - @echo "Compiling $<" - $(NO_ECHO)$(CC) -c $(CPPFLAGS) $(CFLAGS) $< - - - -#================================================================ -# Actions -#================================================================ - -all: $(LIBRARYFILES) - -not-all : $(LIBRARYFILES) $(COMMANDFILES) - @$(POSTCMD) - @printf '\n' - @printf '#================================================================\n' - @printf '# Ready to install.\n' - @printf '#================================================================\n' - - -clean : - rm -rf $(LIBRARYFILES) $(LIBOBJFILES) $(COMMANDFILES) \ - *.o a.out check.in check.out gmon.out leak.log casket casket-* casket.* *~ hoge moge - - -version : - vernum=`expr $(LIBVER)00 + $(LIBREV)` ; \ - sed -e 's/_TC_VERSION.*/_TC_VERSION "$(VERSION)"/' \ - -e "s/_TC_LIBVER.*/_TC_LIBVER $$vernum/" \ - -e 's/_TC_FORMATVER.*/_TC_FORMATVER "$(FORMATVER)"/' tcutil.h > tcutil.h~ - [ -f tcutil.h~ ] && mv -f tcutil.h~ tcutil.h - -untabify : - ls *.c *.h *.idl | while read name ; \ - do \ - sed -e 's/\t/ /g' -e 's/ *$$//' $$name > $$name~; \ - [ -f $$name~ ] && mv -f $$name~ $$name ; \ - done - -install: - -install-strip: - -uninstall: - -do-notinstall : - mkdir -p $(DESTDIR)$(INCLUDEDIR) - cp -Rf $(HEADERFILES) $(DESTDIR)$(INCLUDEDIR) - mkdir -p $(DESTDIR)$(LIBDIR) - cp -Rf $(LIBRARYFILES) $(DESTDIR)$(LIBDIR) - mkdir -p $(DESTDIR)$(BINDIR) - cp -Rf $(COMMANDFILES) $(DESTDIR)$(BINDIR) - mkdir -p $(DESTDIR)$(DATADIR) - cp -Rf $(DOCUMENTFILES) $(DESTDIR)$(DATADIR) - mkdir -p $(DESTDIR)$(MAN1DIR) - cd man && cp -Rf $(MAN1FILES) $(DESTDIR)$(MAN1DIR) - mkdir -p $(DESTDIR)$(MAN3DIR) - cd man && cp -Rf $(MAN3FILES) $(DESTDIR)$(MAN3DIR) - mkdir -p $(DESTDIR)$(PCDIR) - cp -Rf $(PCFILES) $(DESTDIR)$(PCDIR) - @printf '\n' - @printf '#================================================================\n' - @printf '# Thanks for using Tokyo Cabinet.\n' - @printf '#================================================================\n' - - -do-notinstall-strip : - make DESTDIR=$(DESTDIR) install - cd $(DESTDIR)$(BINDIR) && strip $(MYCOMMANDS) - - -do-notuninstall : - cd $(DESTDIR)$(INCLUDEDIR) && rm -f $(HEADERFILES) - cd $(DESTDIR)$(LIBDIR) && rm -f $(LIBRARYFILES) - cd $(DESTDIR)$(BINDIR) && rm -f $(COMMANDFILES) - cd $(DESTDIR)$(MAN1DIR) && rm -f $(MAN1FILES) - cd $(DESTDIR)$(MAN3DIR) && rm -f $(MAN3FILES) - rm -rf $(DESTDIR)$(DATADIR) - cd $(DESTDIR)$(PCDIR) && rm -f $(PCFILES) - - -dist : - make version - make untabify - make distclean - cd .. && tar cvf - $(PACKAGEDIR) | gzip -c > $(PACKAGETGZ) - sync ; sync - - -distclean : clean - rm -rf Makefile tokyocabinet.pc config.cache config.log config.status autom4te.cache - - -check : - rm -rf casket* - $(RUNENV) $(RUNCMD) ./tcamgr version - $(RUNENV) $(RUNCMD) ./tcutest xstr 50000 - $(RUNENV) $(RUNCMD) ./tcutest list 50000 - $(RUNENV) $(RUNCMD) ./tcutest map 50000 - $(RUNENV) $(RUNCMD) ./tcutest mdb 50000 - $(RUNENV) $(RUNCMD) ./tcutest misc 500 - $(RUNENV) $(RUNCMD) ./tcutest wicked 50000 - $(RUNENV) $(RUNCMD) ./tcumttest combo 5 50000 500 - $(RUNENV) $(RUNCMD) ./tcumttest combo -rnd 5 50000 500 - $(RUNENV) $(RUNCMD) ./tchmttest typical casket 5 50000 5000 - $(RUNENV) $(RUNCMD) ./tchmttest typical -rr 1000 casket 5 50000 5000 - $(RUNENV) $(RUNCMD) ./tchmttest typical -rc 50000 -nc casket 5 50000 5000 - $(RUNENV) $(RUNCMD) ./tcucodec url Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec url -d check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec base Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec base -d check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec quote Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec quote -d check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec mime Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec mime -d check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec pack -bwt Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec pack -d -bwt check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec tcbs Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec tcbs -d check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec zlib Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec zlib -d check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec xml Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec xml -d check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec ucs Makefile > check.in - $(RUNENV) $(RUNCMD) ./tcucodec ucs -d check.in > check.out - $(RUNENV) $(RUNCMD) ./tcucodec date -ds '1978-02-11T18:05:30+09:00' -rf > check.out - $(RUNENV) $(RUNCMD) ./tcucodec conf - $(RUNENV) $(RUNCMD) ./tchtest write casket 50000 5000 5 5 - $(RUNENV) $(RUNCMD) ./tchtest read casket - $(RUNENV) $(RUNCMD) ./tchtest remove casket - $(RUNENV) $(RUNCMD) ./tchtest write -mt -tl -td -rc 50 casket 50000 5000 5 5 - $(RUNENV) $(RUNCMD) ./tchtest read -mt -nb -rc 50 casket - $(RUNENV) $(RUNCMD) ./tchtest remove -mt -rc 50 casket - $(RUNENV) $(RUNCMD) ./tchtest write -as -tb -rc 50 casket 50000 50000 5 5 - $(RUNENV) $(RUNCMD) ./tchtest read -nl -rc 50 casket - $(RUNENV) $(RUNCMD) ./tchtest remove -rc 50 casket - $(RUNENV) $(RUNCMD) ./tchtest rcat -pn 500 casket 50000 5000 5 5 - $(RUNENV) $(RUNCMD) ./tchtest rcat -tl -td -pn 5000 casket 50000 500 5 15 - $(RUNENV) $(RUNCMD) ./tchtest rcat -nl -pn 500 -rl casket 5000 500 5 5 - $(RUNENV) $(RUNCMD) ./tchtest rcat -tb -pn 500 casket 5000 500 5 5 - $(RUNENV) $(RUNCMD) ./tchmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tchmgr list -pv -fm 1 -px casket > check.out - $(RUNENV) $(RUNCMD) ./tchtest misc casket 5000 - $(RUNENV) $(RUNCMD) ./tchtest misc -tl -td casket 5000 - $(RUNENV) $(RUNCMD) ./tchtest misc -mt -tb casket 500 - $(RUNENV) $(RUNCMD) ./tchtest wicked casket 50000 - $(RUNENV) $(RUNCMD) ./tchtest wicked -tl -td casket 50000 - $(RUNENV) $(RUNCMD) ./tchtest wicked -mt -tb casket 5000 - $(RUNENV) $(RUNCMD) ./tchmttest write -tl casket 5 5000 500 5 - $(RUNENV) $(RUNCMD) ./tchmttest read casket 5 - $(RUNENV) $(RUNCMD) ./tchmttest read -rnd casket 5 - $(RUNENV) $(RUNCMD) ./tchmttest remove casket 5 - $(RUNENV) $(RUNCMD) ./tchmttest wicked -nc casket 5 5000 - $(RUNENV) $(RUNCMD) ./tchmttest wicked -tl -td casket 5 5000 - $(RUNENV) $(RUNCMD) ./tchmttest wicked -tb casket 5 5000 - $(RUNENV) $(RUNCMD) ./tchmttest typical casket 5 50000 5000 - $(RUNENV) $(RUNCMD) ./tchmttest typical -rr 1000 casket 5 50000 5000 - $(RUNENV) $(RUNCMD) ./tchmttest typical -tl -rc 50000 -nc casket 5 50000 5000 - $(RUNENV) $(RUNCMD) ./tchmgr create casket 3 1 1 - $(RUNENV) $(RUNCMD) ./tchmgr inform casket - $(RUNENV) $(RUNCMD) ./tchmgr put casket one first - $(RUNENV) $(RUNCMD) ./tchmgr put casket two second - $(RUNENV) $(RUNCMD) ./tchmgr put -dk casket three third - $(RUNENV) $(RUNCMD) ./tchmgr put -dc casket three third - $(RUNENV) $(RUNCMD) ./tchmgr put -dc casket three third - $(RUNENV) $(RUNCMD) ./tchmgr put -dc casket three third - $(RUNENV) $(RUNCMD) ./tchmgr put casket four fourth - $(RUNENV) $(RUNCMD) ./tchmgr put -dk casket five fifth - $(RUNENV) $(RUNCMD) ./tchmgr out casket one - $(RUNENV) $(RUNCMD) ./tchmgr out casket two - $(RUNENV) $(RUNCMD) ./tchmgr get casket three > check.out - $(RUNENV) $(RUNCMD) ./tchmgr get casket four > check.out - $(RUNENV) $(RUNCMD) ./tchmgr get casket five > check.out - $(RUNENV) $(RUNCMD) ./tchmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tchmgr optimize casket - $(RUNENV) $(RUNCMD) ./tchmgr put -dc casket three third - $(RUNENV) $(RUNCMD) ./tchmgr get casket three > check.out - $(RUNENV) $(RUNCMD) ./tchmgr get casket four > check.out - $(RUNENV) $(RUNCMD) ./tchmgr get casket five > check.out - $(RUNENV) $(RUNCMD) ./tchmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tcbtest write casket 50000 5 5 5000 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest read casket - $(RUNENV) $(RUNCMD) ./tcbtest remove casket - $(RUNENV) $(RUNCMD) ./tcbmgr list -rb 00001000 00002000 casket > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr list -fm 000001 casket > check.out - $(RUNENV) $(RUNCMD) ./tcbtest write -mt -tl -td -ls 1024 casket 50000 5000 5000 5000 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest read -mt -nb casket - $(RUNENV) $(RUNCMD) ./tcbtest remove -mt casket - $(RUNENV) $(RUNCMD) ./tcbtest write -tb casket 50000 5 5 50000 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest read -nl casket - $(RUNENV) $(RUNCMD) ./tcbtest remove casket - $(RUNENV) $(RUNCMD) ./tcbtest rcat -lc 5 -nc 5 -pn 500 casket 50000 5 5 5000 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest rcat -tl -td -pn 5000 casket 50000 5 5 500 5 15 - $(RUNENV) $(RUNCMD) ./tcbtest rcat -nl -pn 5000 -rl casket 15000 5 5 500 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest rcat -ca 1000 -tb -pn 5000 casket 15000 5 5 500 5 5 - $(RUNENV) $(RUNCMD) ./tcbmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tcbtest queue casket 15000 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest misc casket 5000 - $(RUNENV) $(RUNCMD) ./tcbtest misc -tl -td casket 5000 - $(RUNENV) $(RUNCMD) ./tcbtest misc -mt -tb casket 500 - $(RUNENV) $(RUNCMD) ./tcbtest wicked casket 50000 - $(RUNENV) $(RUNCMD) ./tcbtest wicked -tl -td casket 50000 - $(RUNENV) $(RUNCMD) ./tcbtest wicked -mt -tb casket 5000 - $(RUNENV) $(RUNCMD) ./tcbtest write -cd -lc 5 -nc 5 casket 5000 5 5 5 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest read -cd -lc 5 -nc 5 casket - $(RUNENV) $(RUNCMD) ./tcbtest remove -cd -lc 5 -nc 5 casket - $(RUNENV) $(RUNCMD) ./tcbmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tcbtest write -ci -td -lc 5 -nc 5 casket 5000 5 5 5 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest read -ci -lc 5 -nc 5 casket - $(RUNENV) $(RUNCMD) ./tcbtest remove -ci -lc 5 -nc 5 casket - $(RUNENV) $(RUNCMD) ./tcbmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tcbtest write -cj -tb -lc 5 -nc 5 casket 5000 5 5 5 5 5 - $(RUNENV) $(RUNCMD) ./tcbtest read -cj -lc 5 -nc 5 casket - $(RUNENV) $(RUNCMD) ./tcbtest remove -cj -lc 5 -nc 5 casket - $(RUNENV) $(RUNCMD) ./tcbmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tcbmttest write -tl casket 5 5000 5 5 500 5 - $(RUNENV) $(RUNCMD) ./tcbmttest read casket 5 - $(RUNENV) $(RUNCMD) ./tcbmttest read -rnd casket 5 - $(RUNENV) $(RUNCMD) ./tcbmttest remove casket 5 - $(RUNENV) $(RUNCMD) ./tcbmttest wicked -nc casket 5 5000 - $(RUNENV) $(RUNCMD) ./tcbmttest wicked -tl -td casket 5 5000 - $(RUNENV) $(RUNCMD) ./tchmttest wicked -tb casket 5 5000 - $(RUNENV) $(RUNCMD) ./tcbmttest typical casket 5 50000 5 5 - $(RUNENV) $(RUNCMD) ./tcbmttest typical -rr 1000 casket 5 50000 5 5 - $(RUNENV) $(RUNCMD) ./tcbmttest typical -tl -nc casket 5 50000 5 5 - $(RUNENV) $(RUNCMD) ./tcbmgr create casket 4 4 3 1 1 - $(RUNENV) $(RUNCMD) ./tcbmgr inform casket - $(RUNENV) $(RUNCMD) ./tcbmgr put casket one first - $(RUNENV) $(RUNCMD) ./tcbmgr put casket two second - $(RUNENV) $(RUNCMD) ./tcbmgr put -dk casket three third - $(RUNENV) $(RUNCMD) ./tcbmgr put -dc casket three third - $(RUNENV) $(RUNCMD) ./tcbmgr put -dc casket three third - $(RUNENV) $(RUNCMD) ./tcbmgr put -dd casket three third - $(RUNENV) $(RUNCMD) ./tcbmgr put -dd casket three third - $(RUNENV) $(RUNCMD) ./tcbmgr put casket four fourth - $(RUNENV) $(RUNCMD) ./tcbmgr put -dk casket five fifth - $(RUNENV) $(RUNCMD) ./tcbmgr out casket one - $(RUNENV) $(RUNCMD) ./tcbmgr out casket two - $(RUNENV) $(RUNCMD) ./tcbmgr get casket three > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr get casket four > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr get casket five > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr list -j three -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr optimize casket - $(RUNENV) $(RUNCMD) ./tcbmgr put -dc casket three third - $(RUNENV) $(RUNCMD) ./tcbmgr get casket three > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr get casket four > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr get casket five > check.out - $(RUNENV) $(RUNCMD) ./tcbmgr list -pv casket > check.out - $(RUNENV) $(RUNCMD) ./tcatest write 'casket.tch#mode=wct#bnum=5000' 50000 - $(RUNENV) $(RUNCMD) ./tcatest read 'casket.tch#mode=r' - $(RUNENV) $(RUNCMD) ./tcatest remove 'casket.tch#mode=w' - $(RUNENV) $(RUNCMD) ./tcatest misc 'casket.tch#mode=wct#bnum=500#opts=ld' 5000 - $(RUNENV) $(RUNCMD) ./tcatest wicked 'casket.tch#mode=wct' 5000 - $(RUNENV) $(RUNCMD) ./tcatest write 'casket.tcb#mode=wct#lmemb=5#nmemb=5' 50000 - $(RUNENV) $(RUNCMD) ./tcatest read 'casket.tcb#mode=r' - $(RUNENV) $(RUNCMD) ./tcatest remove 'casket.tcb#mode=w' - $(RUNENV) $(RUNCMD) ./tcatest misc 'casket.tcb#mode=wct#lmemb=5#nmemb=5#opts=ld' 5000 - $(RUNENV) $(RUNCMD) ./tcatest wicked 'casket.tcb#mode=wct' 5000 - $(RUNENV) $(RUNCMD) ./tcatest write '*#bnum=5000#cap=100' 50000 - $(RUNENV) $(RUNCMD) ./tcatest misc '*' 5000 - $(RUNENV) $(RUNCMD) ./tcatest wicked '*' 5000 - $(RUNENV) $(RUNCMD) ./tcamgr create 'casket.tch#mode=wct#bnum=3' - $(RUNENV) $(RUNCMD) ./tcamgr inform 'casket.tch' - $(RUNENV) $(RUNCMD) ./tcamgr put casket.tch one first - $(RUNENV) $(RUNCMD) ./tcamgr put casket.tch two second - $(RUNENV) $(RUNCMD) ./tcamgr put -dk casket.tch three third - $(RUNENV) $(RUNCMD) ./tcamgr put -dc casket.tch three third - $(RUNENV) $(RUNCMD) ./tcamgr put -dc casket.tch three third - $(RUNENV) $(RUNCMD) ./tcamgr put -dc casket.tch three third - $(RUNENV) $(RUNCMD) ./tcamgr put casket.tch four fourth - $(RUNENV) $(RUNCMD) ./tcamgr put -dk casket.tch five fifth - $(RUNENV) $(RUNCMD) ./tcamgr out casket.tch one - $(RUNENV) $(RUNCMD) ./tcamgr out casket.tch two - $(RUNENV) $(RUNCMD) ./tcamgr get casket.tch three > check.out - $(RUNENV) $(RUNCMD) ./tcamgr get casket.tch four > check.out - $(RUNENV) $(RUNCMD) ./tcamgr get casket.tch five > check.out - $(RUNENV) $(RUNCMD) ./tcamgr list -pv -fm f casket.tch > check.out - $(RUNENV) $(RUNCMD) ./tcamgr put -dc casket.tch three third - $(RUNENV) $(RUNCMD) ./tcamgr get casket.tch three > check.out - $(RUNENV) $(RUNCMD) ./tcamgr get casket.tch four > check.out - $(RUNENV) $(RUNCMD) ./tcamgr get casket.tch five > check.out - $(RUNENV) $(RUNCMD) ./tcamgr list -pv casket.tch > check.out - rm -rf casket* - @printf '\n' - @printf '#================================================================\n' - @printf '# Checking completed.\n' - @printf '#================================================================\n' - - -check-valgrind : - make RUNCMD="valgrind --tool=memcheck --log-fd=1" check | tee leak.log - grep ERROR leak.log - grep 'at exit' leak.log - - -check-large : - rm -rf casket* - $(RUNENV) $(RUNCMD) ./tchmttest typical casket 3 1000000 5000000 13 8 - $(RUNENV) $(RUNCMD) ./tchmttest typical -nc casket 3 1000000 5000000 13 8 - $(RUNENV) $(RUNCMD) ./tcbmttest typical casket 3 500000 8 8 500000 16 8 - $(RUNENV) $(RUNCMD) ./tcbmttest typical -nc casket 3 500000 8 8 500000 16 8 - rm -rf casket* - - -check-thread : - rm -rf casket* - $(RUNENV) $(RUNCMD) ./tcumttest typical 5 500000 500000 - $(RUNENV) $(RUNCMD) ./tcumttest typical -nc -rr 1000 5 500000 500000 - $(RUNENV) $(RUNCMD) ./tchmttest typical casket 5 500000 500000 - $(RUNENV) $(RUNCMD) ./tchmttest typical -rc 500000 -nc -rr 1000 casket 5 500000 500000 - $(RUNENV) $(RUNCMD) ./tcbmttest typical casket 5 100000 5 5 - $(RUNENV) $(RUNCMD) ./tcbmttest typical -nc -rr 1000 casket 5 100000 5 5 - rm -rf casket* - - -check-forever : - while true ; \ - do \ - make check || break ; \ - make check || break ; \ - make check || break ; \ - make check || break ; \ - make check || break ; \ - make check-thread || break ; \ - done - - -dicthdb : - rm -f casket - sed -e 's/.*$$/&\t&/' /usr/share/dict/words | \ - ./tchmgr importtsv -sc casket - - -dictbdb : - rm -f casket - sed -e 's/.*$$/&\t&/' /usr/share/dict/words | \ - ./tcbmgr importtsv -sc casket - - -.PHONY : all clean install check - - - -#================================================================ -# Building binaries -#================================================================ - - -libtokyocabinet.a : $(LIBOBJFILES) - $(AR) $(ARFLAGS) $@ $(LIBOBJFILES) - - -libtokyocabinet.so.$(LIBVER).$(LIBREV).0 : $(LIBOBJFILES) - $(CC) -shared -Wl,-soname,libtokyocabinet.so.$(LIBVER) -o $@ $(LIBOBJFILES) \ - $(LDFLAGS) $(LIBS) - - -libtokyocabinet.so.$(LIBVER) : libtokyocabinet.so.$(LIBVER).$(LIBREV).0 - ln -f -s libtokyocabinet.so.$(LIBVER).$(LIBREV).0 $@ - - -libtokyocabinet.so : libtokyocabinet.so.$(LIBVER).$(LIBREV).0 - ln -f -s libtokyocabinet.so.$(LIBVER).$(LIBREV).0 $@ - - -libtokyocabinet.$(LIBVER).$(LIBREV).0.dylib : $(LIBOBJFILES) - $(CC) -dynamiclib -o $@ \ - -install_name $(LIBDIR)/libtokyocabinet.$(LIBVER).dylib \ - -current_version $(LIBVER).$(LIBREV).0 -compatibility_version $(LIBVER) \ - $(LIBOBJFILES) $(LDFLAGS) $(LIBS) - - -libtokyocabinet.$(LIBVER).dylib : libtokyocabinet.$(LIBVER).$(LIBREV).0.dylib - ln -f -s libtokyocabinet.$(LIBVER).$(LIBREV).0.dylib $@ - - -libtokyocabinet.dylib : libtokyocabinet.$(LIBVER).$(LIBREV).0.dylib - ln -f -s libtokyocabinet.$(LIBVER).$(LIBREV).0.dylib $@ - - -tcutest : tcutest.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tcumttest : tcumttest.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tcucodec : tcucodec.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tchtest : tchtest.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tchmttest : tchmttest.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tchmgr : tchmgr.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tcbtest : tcbtest.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tcbmttest : tcbmttest.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tcbmgr : tcbmgr.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tcatest : tcatest.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -tcamgr : tcamgr.o $(LIBRARYFILES) - $(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -ltokyocabinet $(LIBS) - - -myconf.o : myconf.h - -tcutil.o : tcutil.h myconf.h - -tchdb.o : tchdb.h tcutil.h myconf.h - -tcbdb.o : tcbdb.h tchdb.h tcutil.h myconf.h - -tcutest.o tcucodec.o : tcutil.h myconf.h - -tchtest.o tchmttest.o tchmgr.o : tcutil.h tchdb.h myconf.h - -tcbtest.o tcbmttest.o tcbmgr.o : tcutil.h tchdb.h tcbdb.h myconf.h - -tcatest.o : tcutil.h tchdb.h tcbdb.h tcadb.h myconf.h - - - -# END OF FILE diff --git a/bacula/src/lib/tokyocabinet/README b/bacula/src/lib/tokyocabinet/README deleted file mode 100644 index ed9ad3238d..0000000000 --- a/bacula/src/lib/tokyocabinet/README +++ /dev/null @@ -1,38 +0,0 @@ -================================================================ - Tokyo Cabinet: a modern implementation of DBM - Copyright (C) 2006-2008 Mikio Hirabayashi -================================================================ - - -Please read the following documents with a WWW browser. -How to install Tokyo Cabinet is explained in the specification. - - README - this file - COPYING - license - ChangeLog - history of enhancement - THANKS - list of contributors - doc/index.html - index of documents - - -Contents of the directory tree is below. - - ./ - sources of Tokyo Cabinet - ./doc/ - manuals and specifications - ./man/ - manuals for nroff - ./example/ - sample code of tutorial - ./lab/ - for test and experiment - ./bros/ - for comparison with other database managers - - -Tokyo Cabinet is released under the terms of the GNU Lesser General -Public License. See the file `COPYING' for details. - -Tokyo Cabinet was written by Mikio Hirabayashi. You can contact the -author by e-mail to `mikio@users.sourceforge.net'. - - -Thanks. - - - -== END OF FILE == diff --git a/bacula/src/lib/tokyocabinet/THANKS b/bacula/src/lib/tokyocabinet/THANKS deleted file mode 100644 index 1a80e0b871..0000000000 --- a/bacula/src/lib/tokyocabinet/THANKS +++ /dev/null @@ -1,12 +0,0 @@ -================================================================ - Thanks to all of the following for their valuable suggestions - or contributions. -================================================================ - - -mixi Inc. and and its developers - - allowing me to develop and publish Tokyo Cabinet as business work - - - -== END OF FILE == diff --git a/bacula/src/lib/tokyocabinet/TODO b/bacula/src/lib/tokyocabinet/TODO deleted file mode 100644 index 1dc71db64c..0000000000 --- a/bacula/src/lib/tokyocabinet/TODO +++ /dev/null @@ -1,4 +0,0 @@ - -tcmdbfwmkeysを貝偏 - -adbも実装 \ No newline at end of file diff --git a/bacula/src/lib/tokyocabinet/compat.c b/bacula/src/lib/tokyocabinet/compat.c deleted file mode 100644 index 0c6bec0e6a..0000000000 --- a/bacula/src/lib/tokyocabinet/compat.c +++ /dev/null @@ -1,248 +0,0 @@ -/************************************************************************************************* - * The compat WIN32 API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - -#ifdef HAVE_WIN32 - -#include "tcutil.h" -#include "myconf.h" -#include -#include - -int msync(void *start, size_t length, int flags) -{ - return 0; -} -int fsync(int fd) -{ - return 0; -} - -/* - * Keep track of HANDLE for CreateView - */ - -struct mmap_priv -{ - HANDLE h; - HANDLE mv; -}; - -static TCLIST *mmap_list=NULL; - -static void mmap_register(HANDLE h, HANDLE mv) -{ - struct mmap_priv *priv; -/* - if (!tcglobalmutexlock()) { - return; - } -*/ - if (!mmap_list) { - mmap_list = tclistnew(); - } - - priv = tcmalloc(sizeof(struct mmap_priv)); - priv->h = h; - priv->mv = mv; - tclistpush(mmap_list, priv, sizeof(priv)); -/* - tcglobalmutexunlock(); -*/ -} - -static HANDLE mmap_unregister(HANDLE mv) -{ - HANDLE h=NULL; - struct mmap_priv *priv; - int i, max, size; - int nok=1; -/* - if (!tcglobalmutexlock()) { - return NULL; - } -*/ - max = tclistnum(mmap_list); - for(i=0; nok && imv == mv)) { - tclistremove(mmap_list, i, &size); - h = priv->h; - tcfree(mmap_list); - nok=0; - } - } -/* - tcglobalmutexunlock(); -*/ - return h; -} - - -/* - * Emulation of mmap and unmmap for tokyo dbm - */ -void *mmap(void *start, size_t length, int prot, int flags, - int fd, off_t offset) -{ - DWORD fm_access = 0; - DWORD mv_access = 0; - HANDLE h; - HANDLE mv; - - if (length == 0) { - return MAP_FAILED; - } - if (!fd) { - return MAP_FAILED; - } - - if (flags & PROT_WRITE) { - fm_access |= PAGE_READWRITE; - } else if (flags & PROT_READ) { - fm_access |= PAGE_READONLY; - } - - if (flags & PROT_READ) { - mv_access |= FILE_MAP_READ; - } - if (flags & PROT_WRITE) { - mv_access |= FILE_MAP_WRITE; - } - - h = CreateFileMapping((HANDLE)_get_osfhandle (fd), - NULL /* security */, - fm_access, - 0 /* MaximumSizeHigh */, - 0 /* MaximumSizeLow */, - NULL /* name of the file mapping object */); - - if (!h || h == INVALID_HANDLE_VALUE) { - return MAP_FAILED; - } - - mv = MapViewOfFile(h, mv_access, - 0 /* offset hi */, - 0 /* offset lo */, - length); - if (!mv || mv == INVALID_HANDLE_VALUE) { - CloseHandle(h); - return MAP_FAILED; - } - - mmap_register(h, mv); - return (void *) mv; -} - -int munmap(void *start, size_t length) -{ - HANDLE h; - if (!start) { - return -1; - } - h = mmap_unregister(start); - UnmapViewOfFile(start); - CloseHandle(h); - return 0; -} - -int regcomp(regex_t *preg, const char *regex, int cflags) -{ - return 0; -} - -int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) -{ - return 0; -} - -size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) -{ - *errbuf = 0; - return 0; -} -/* -int gettimeofday(struct timeval *tv, struct timezone *tz) -{ - return -1; -} -*/ -void regfree(regex_t *preg) -{ -} - -int glob(const char *pattern, int flags, - int (*errfunc) (const char *epath, int eerrno), - glob_t *pglob) -{ - return GLOB_NOMATCH; -} -void globfree(glob_t *pglob) -{ -} - -char *realpath(const char *path, char *resolved_path) -{ - strcpy(resolved_path, path); - return resolved_path; -} - -/* -int rand_r(unsigned int *seedp) -{ - *seedp = *seedp * 1103515245 + 12345; - return((unsigned)(*seedp/65536) % 32768); -} -*/ - -/* read from a file descriptor at a given offset */ -ssize_t pread(int fd, void *buf, size_t count, off_t offset) -{ - __int64 cur_pos; - ssize_t num_read; - - if ((cur_pos = _lseeki64(fd, 0, SEEK_CUR)) == (off_t)-1) - return -1; - - if (_lseeki64(fd, offset, SEEK_SET) == (off_t)-1) - return -1; - - num_read = read(fd, buf, count); - - if (_lseeki64(fd, cur_pos, SEEK_SET) == (off_t)-1) - return -1; - - return num_read; -} - -/* write to a file descriptor at a given offset */ -ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) -{ - __int64 cur_pos; - ssize_t num_write; - - if ((cur_pos = _lseeki64(fd, 0, SEEK_CUR)) == (off_t)-1) - return -1; - - if (_lseeki64(fd, offset, SEEK_SET) == (off_t)-1) - return -1; - - num_write = write(fd, buf, count); - - if (_lseeki64(fd, cur_pos, SEEK_SET) == (off_t)-1) - return -1; - - return num_write; -} - -#endif diff --git a/bacula/src/lib/tokyocabinet/compat.h b/bacula/src/lib/tokyocabinet/compat.h deleted file mode 100644 index 4ea0a3098d..0000000000 --- a/bacula/src/lib/tokyocabinet/compat.h +++ /dev/null @@ -1,89 +0,0 @@ -/************************************************************************************************* - * The win32 compat API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - -#ifndef COMPAT_H -#define COMPAT_H - -#ifdef HAVE_WIN32 -#include - -typedef int regoff_t; - -typedef struct { - regoff_t rm_so; - regoff_t rm_eo; -} regmatch_t; - -typedef struct { - -} regex_t; - -#define REG_EXTENDED 0 -#define REG_NOSUB 0 -#define REG_ICASE 0 -#define REG_NOTBOL 0 -int regcomp(regex_t *preg, const char *regex, int cflags); -int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags); -size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size); -void regfree(regex_t *preg); - - -/* mmap implementation for tokyodbm */ -#define PROT_WRITE 0x2 /* Page can be written. */ -#define PROT_READ 0x1 /* page can be read */ -#define MAP_SHARED 0x01 /* Share changes. */ -#define MAP_FAILED ((void *) -1) -#define MS_SYNC 0 - -void *mmap(void *start, size_t length, int prot, int flags, - int fd, off_t offset); -int munmap(void *start, size_t length); -int msync(void *start, size_t length, int flags); -int fsync(int fd); -ssize_t pread(int fd, void *buf, size_t count, off_t offset); -ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset); -int rand_r(int *seedp); - -/* -struct timezone { - int tz_minuteswest; - int tz_dsttime; -}; - -int gettimeofday(struct timeval *tv, struct timezone *tz); -*/ - -typedef struct { - size_t gl_pathc; /* Count of paths matched so far */ - char **gl_pathv; /* List of matched pathnames. */ - size_t gl_offs; /* Slots to reserve in ‘gl_pathv’. */ -} glob_t; - -int glob(const char *pattern, int flags, - int (*errfunc) (const char *epath, int eerrno), - glob_t *pglob); - -void globfree(glob_t *pglob); - -#define GLOB_ERR 0 -#define GLOB_NOSORT 0 -#define GLOB_NOMATCH 0 - -char *realpath(const char *path, char *resolved_path); - -#define lstat stat - -#endif /* HAVE_WIN32 */ -#endif /* !COMPAT_H */ diff --git a/bacula/src/lib/tokyocabinet/configure b/bacula/src/lib/tokyocabinet/configure deleted file mode 100755 index 269fee8b78..0000000000 --- a/bacula/src/lib/tokyocabinet/configure +++ /dev/null @@ -1,3868 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for tokyocabinet 1.2.5. -# -# Copyright (C) 2003 Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -exec 6>&1 - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_config_libobj_dir=. -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - -# Identity of this package. -PACKAGE_NAME='tokyocabinet' -PACKAGE_TARNAME='tokyocabinet' -PACKAGE_VERSION='1.2.5' -PACKAGE_STRING='tokyocabinet 1.2.5' -PACKAGE_BUGREPORT='' - -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT MYLIBVER MYLIBREV MYFORMATVER MYHEADERFILES MYLIBRARYFILES MYLIBOBJFILES MYCOMMANDFILES MYMAN1FILES MYMAN3FILES MYDOCUMENTFILES MYPCFILES MYCFLAGS MYCPPFLAGS MYLDFLAGS MYRUNPATH MYLDLIBPATHENV MYPOSTCMD LIBOBJS LTLIBOBJS' -ac_subst_files='' - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -ac_prev= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_option in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 - { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures tokyocabinet 1.2.5 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -_ACEOF - - cat <<_ACEOF -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] -_ACEOF - - cat <<\_ACEOF -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of tokyocabinet 1.2.5:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-debug build for debugging - --enable-devel build for development - --enable-profile build for profiling - --enable-off64 build with 64-bit file offset on 32-bit system - --enable-fastest build for fastest run - --enable-swab build for swapping byte-orders - --enable-uyield build for detecting race conditions - --disable-zlib build without ZLIB compression - --disable-pthread build without POSIX thread support - --disable-shared avoid to build shared libraries - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have - headers in a nonstandard directory - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -_ACEOF -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - ac_popdir=`pwd` - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir - done -fi - -test -n "$ac_init_help" && exit 0 -if $ac_init_version; then - cat <<\_ACEOF -tokyocabinet configure 1.2.5 -generated by GNU Autoconf 2.59 - -Copyright (C) 2003 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit 0 -fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by tokyocabinet $as_me 1.2.5, which was -generated by GNU Autoconf 2.59. Invocation command line was - - $ $0 $@ - -_ACEOF -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_sep= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; - 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " - ;; - esac - done -done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -{ - (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) - sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; - *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} - echo - - cat <<\_ASBOX -## ----------------- ## -## Output variables. ## -## ----------------- ## -_ASBOX - echo - for ac_var in $ac_subst_vars - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - - if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## -_ASBOX - echo - for ac_var in $ac_subst_files - do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" - done | sort - echo - fi - - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - sed "/^$/d" confdefs.h | sort - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status - ' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Package information -MYLIBVER=3 -MYLIBREV=6 -MYFORMATVER="1.0" - -# Targets -MYHEADERFILES="tcutil.h tchdb.h tcbdb.h tcadb.h" -MYLIBRARYFILES="libtokyocabinet.a" -MYLIBOBJFILES="tcutil.o tchdb.o tcbdb.o tcadb.o myconf.o" -MYCOMMANDFILES="tcutest tcumttest tcucodec tchtest tchmttest tchmgr" -MYCOMMANDFILES="$MYCOMMANDFILES tcbtest tcbmttest tcbmgr tcatest tcamgr" -MYMAN1FILES="tcutest.1 tcumttest.1 tcucodec.1 tchtest.1 tchmttest.1 tchmgr.1" -MYMAN1FILES="$MYMAN1FILES tcbtest.1 tcbmttest.1 tcbmgr.1 tcatest.1 tcamgr.1" -MYMAN3FILES="tokyocabinet.3 tcutil.3 tcxstr.3 tclist.3 tcmap.3 tcmdb.3 tcmpool.3" -MYMAN3FILES="$MYMAN3FILES tchdb.3 tcbdb.3 tcadb.3" -MYDOCUMENTFILES="COPYING ChangeLog THANKS doc" -MYPCFILES="tokyocabinet.pc" - -# Building flags -MYCFLAGS="-std=c99 -Wall -fPIC -fsigned-char -O2" -MYCPPFLAGS="-I. -I\$(INCLUDEDIR) -L$HOME/include -L/usr/local/include -DNDEBUG -D_GNU_SOURCE=1" -MYLDFLAGS="-L. -L\$(LIBDIR) -L$HOME/lib -L/usr/local/lib" -MYRUNPATH="\$(LIBDIR)" -MYLDLIBPATHENV="LD_LIBRARY_PATH" -MYPOSTCMD="true" - -# Building paths -pathtmp="$PATH" -PATH="$HOME/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" -PATH="$PATH:/usr/ccs/bin:/usr/ucb:/usr/xpg4/bin:/usr/xpg6/bin:$pathtmp" -LIBRARY_PATH="$HOME/lib:/usr/local/lib:$LIBRARY_PATH" -LD_LIBRARY_PATH="$HOME/lib:/usr/local/lib:$LD_LIBRARY_PATH" -CPATH="$HOME/include:/usr/local/include:$CPATH" -PKG_CONFIG_PATH="$HOME/lib/pkgconfig:/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" -export PATH LIBRARY_PATH LD_LIBRARY_PATH CPATH PKG_CONFIG_PATH - - - -#================================================================ -# Options -#================================================================ - - -# Internal variables -enables="" - -# Debug mode -# Check whether --enable-debug or --disable-debug was given. -if test "${enable_debug+set}" = set; then - enableval="$enable_debug" - -fi; -if test "$enable_debug" = "yes" -then - MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g" - MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG" - MYLDFLAGS="$MYLDFLAGS -static" - enables="$enables (debug)" -fi - -# Developping mode -# Check whether --enable-devel or --disable-devel was given. -if test "${enable_devel+set}" = set; then - enableval="$enable_devel" - -fi; -if test "$enable_devel" = "yes" -then - MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -O2 -pipe" - MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG" - enables="$enables (devel)" -fi - -# Profiling mode -# Check whether --enable-profile or --disable-profile was given. -if test "${enable_profile+set}" = set; then - enableval="$enable_profile" - -fi; -if test "$enable_profile" = "yes" -then - MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -pg -O2 -pipe" - enables="$enables (profile)" -fi - -# 64-bit offset mode -# Check whether --enable-off64 or --disable-off64 was given. -if test "${enable_off64+set}" = set; then - enableval="$enable_off64" - -fi; -if test "$enable_off64" = "yes" -then - MYCPPFLAGS="$MYCPPFLAGS -D_FILE_OFFSET_BITS=64" - enables="$enables (off64)" -fi - -# Fastest mode -# Check whether --enable-fastest or --disable-fastest was given. -if test "${enable_fastest+set}" = set; then - enableval="$enable_fastest" - -fi; -if test "$enable_fastest" = "yes" -then - MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -O3" - MYCFLAGS="$MYCFLAGS -fomit-frame-pointer -fforce-addr -minline-all-stringops" - MYCPPFLAGS="$MYCPPFLAGS -D_MYFASTEST" - enables="$enables (fastest)" -fi - -# Swapping byte-orders mode -# Check whether --enable-swab or --disable-swab was given. -if test "${enable_swab+set}" = set; then - enableval="$enable_swab" - -fi; -if test "$enable_swab" = "yes" -then - MYCPPFLAGS="$MYCPPFLAGS -D_MYSWAB" - enables="$enables (swab)" -fi - -# Micro yield mode -# Check whether --enable-uyield or --disable-uyield was given. -if test "${enable_uyield+set}" = set; then - enableval="$enable_uyield" - -fi; -if test "$enable_uyield" = "yes" -then - MYCPPFLAGS="$MYCPPFLAGS -D_MYMICROYIELD" - enables="$enables (uyield)" -fi - -# Disable ZLIB compression -# Check whether --enable-zlib or --disable-zlib was given. -if test "${enable_zlib+set}" = set; then - enableval="$enable_zlib" - -fi; -if test "$enable_zlib" = "no" -then - MYCPPFLAGS="$MYCPPFLAGS -D_MYNOZLIB" - enables="$enables (no-zlib)" -fi - -# Disable POSIX thread -# Check whether --enable-pthread or --disable-pthread was given. -if test "${enable_pthread+set}" = set; then - enableval="$enable_pthread" - -fi; -if test "$enable_pthread" = "no" -then - MYCPPFLAGS="$MYCPPFLAGS -D_MYNOPTHREAD" - enables="$enables (no-pthread)" -fi - -# Disable shared object -# Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - -fi; -if test "$enable_shared" = "no" -then - enables="$enables (no-shared)" -fi - -# Messages -printf '#================================================================\n' -printf '# Configuring Tokyo Cabinet version %s%s.\n' "$PACKAGE_VERSION" "$enables" -printf '#================================================================\n' - - - -#================================================================ -# Checking Commands and Libraries -#================================================================ - -# C compiler -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CC" && break -done - - CC=$ac_ct_CC -fi - -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -# b.out is created by i960 compilers. -for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; - conftest.$ac_ext ) - # This is the source file. - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext - break;; - * ) - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -rm -f a.out a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_prog_cc_g=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_prog_cc_stdc=no -ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std1 is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std1. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext -done -rm -f conftest.$ac_ext conftest.$ac_objext -CC=$ac_save_CC - -fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; - *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; -esac - -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Byte order - -echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 -echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 -if test "${ac_cv_c_bigendian+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # See if sys/param.h defines the BYTE_ORDER macro. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include - -int -main () -{ -#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN - bogus endian macros -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - # It does; now see whether it defined to BIG_ENDIAN or not. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include - -int -main () -{ -#if BYTE_ORDER != BIG_ENDIAN - not big endian -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_bigendian=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_c_bigendian=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -# It does not; compile a test program. -if test "$cross_compiling" = yes; then - # try to guess the endianness by grepping values into an object file - ac_cv_c_bigendian=unknown - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; -short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; -void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } -short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; -short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; -void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } -int -main () -{ - _ascii (); _ebcdic (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then - ac_cv_c_bigendian=yes -fi -if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi -fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -int -main () -{ - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long l; - char c[sizeof (long)]; - } u; - u.l = 1; - exit (u.c[sizeof (long) - 1] == 1); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_bigendian=no -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_c_bigendian=yes -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 -echo "${ECHO_T}$ac_cv_c_bigendian" >&6 -case $ac_cv_c_bigendian in - yes) - MYCPPFLAGS="$MYCPPFLAGS -D_MYBIGEND" ;; - no) - ;; - *) - { { echo "$as_me:$LINENO: error: unknown endianness -presetting ac_cv_c_bigendian=no (or yes) will help" >&5 -echo "$as_me: error: unknown endianness -presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} - { (exit 1); exit 1; }; } ;; -esac - - -# Underlying libraries - -echo "$as_me:$LINENO: checking for main in -lc" >&5 -echo $ECHO_N "checking for main in -lc... $ECHO_C" >&6 -if test "${ac_cv_lib_c_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lc $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_c_main=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_c_main=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_c_main" >&5 -echo "${ECHO_T}$ac_cv_lib_c_main" >&6 -if test $ac_cv_lib_c_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBC 1 -_ACEOF - - LIBS="-lc $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lm" >&5 -echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6 -if test "${ac_cv_lib_m_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_m_main=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_m_main=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5 -echo "${ECHO_T}$ac_cv_lib_m_main" >&6 -if test $ac_cv_lib_m_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBM 1 -_ACEOF - - LIBS="-lm $LIBS" - -fi - -if test "$enable_pthread" != "no" -then - -echo "$as_me:$LINENO: checking for main in -lpthread" >&5 -echo $ECHO_N "checking for main in -lpthread... $ECHO_C" >&6 -if test "${ac_cv_lib_pthread_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_pthread_main=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_pthread_main=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_main" >&5 -echo "${ECHO_T}$ac_cv_lib_pthread_main" >&6 -if test $ac_cv_lib_pthread_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPTHREAD 1 -_ACEOF - - LIBS="-lpthread $LIBS" - -fi - -fi -if test "$enable_zlib" != "no" -then - -echo "$as_me:$LINENO: checking for main in -lz" >&5 -echo $ECHO_N "checking for main in -lz... $ECHO_C" >&6 -if test "${ac_cv_lib_z_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_z_main=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_z_main=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_z_main" >&5 -echo "${ECHO_T}$ac_cv_lib_z_main" >&6 -if test $ac_cv_lib_z_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBZ 1 -_ACEOF - - LIBS="-lz $LIBS" - -fi - -fi - -# Shared libraries -if test "$enable_shared" != "no" && test "$enable_profile" != "yes" -then - if uname | grep Darwin >/dev/null - then - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.$MYLIBVER.$MYLIBREV.0.dylib" - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.$MYLIBVER.dylib" - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.dylib" - MYLDLIBPATHENV="DYLD_LIBRARY_PATH" - else - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.so.$MYLIBVER.$MYLIBREV.0" - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.so.$MYLIBVER" - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.so" - fi -fi - - - -#================================================================ -# Generic Settings -#================================================================ - -# Export variables - - - - - - - - - - - - - - - - - - -# Targets - ac_config_files="$ac_config_files Makefile tokyocabinet.pc" -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -{ - (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} | - sed ' - t clear - : clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g -t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g -t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed - - -ac_libobjs= -ac_ltlibobjs= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` - # 2. Add them. - ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi -DUALCASE=1; export DUALCASE # for MKS sh - -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - - -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var - fi -done - -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - - -# Name of the executable. -as_me=`$as_basename "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -if mkdir -p . 2>/dev/null; then - as_mkdir_p=: -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - -exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by tokyocabinet $as_me 1.2.5, which was -generated by GNU Autoconf 2.59. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 -_ACEOF - -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi - -cat >>$CONFIG_STATUS <<\_ACEOF - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Report bugs to ." -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -tokyocabinet config.status 1.2.5 -configured by $0, generated by GNU Autoconf 2.59, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" - -Copyright (C) 2003 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - ac_shift=: - ;; - -*) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; - esac - - case $ac_option in - # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" - ac_need_defaults=false;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF -if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion -fi - -_ACEOF - - - - - -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_config_target in $ac_config_targets -do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "tokyocabinet.pc" ) CONFIG_FILES="$CONFIG_FILES tokyocabinet.pc" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } -} - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - -# -# CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@MYLIBVER@,$MYLIBVER,;t t -s,@MYLIBREV@,$MYLIBREV,;t t -s,@MYFORMATVER@,$MYFORMATVER,;t t -s,@MYHEADERFILES@,$MYHEADERFILES,;t t -s,@MYLIBRARYFILES@,$MYLIBRARYFILES,;t t -s,@MYLIBOBJFILES@,$MYLIBOBJFILES,;t t -s,@MYCOMMANDFILES@,$MYCOMMANDFILES,;t t -s,@MYMAN1FILES@,$MYMAN1FILES,;t t -s,@MYMAN3FILES@,$MYMAN3FILES,;t t -s,@MYDOCUMENTFILES@,$MYDOCUMENTFILES,;t t -s,@MYPCFILES@,$MYPCFILES,;t t -s,@MYCFLAGS@,$MYCFLAGS,;t t -s,@MYCPPFLAGS@,$MYCPPFLAGS,;t t -s,@MYLDFLAGS@,$MYLDFLAGS,;t t -s,@MYRUNPATH@,$MYRUNPATH,;t t -s,@MYLDLIBPATHENV@,$MYLDLIBPATHENV,;t t -s,@MYPOSTCMD@,$MYPOSTCMD,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@LTLIBOBJS@,$LTLIBOBJS,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - - -# Messages -printf '#================================================================\n' -printf '# Ready to make.\n' -printf '#================================================================\n' - - - -# END OF FILE diff --git a/bacula/src/lib/tokyocabinet/configure.in b/bacula/src/lib/tokyocabinet/configure.in deleted file mode 100644 index c84d1acbd1..0000000000 --- a/bacula/src/lib/tokyocabinet/configure.in +++ /dev/null @@ -1,232 +0,0 @@ -# Source of configuration for Tokyo Cabinet - - - -#================================================================ -# Generic Settings -#================================================================ - -# Package name -AC_INIT(tokyocabinet, 1.2.5) - -# Package information -MYLIBVER=3 -MYLIBREV=6 -MYFORMATVER="1.0" - -# Targets -MYHEADERFILES="tcutil.h tchdb.h tcbdb.h tcadb.h" -MYLIBRARYFILES="libtokyocabinet.a" -MYLIBOBJFILES="tcutil.o tchdb.o tcbdb.o tcadb.o myconf.o" -MYCOMMANDFILES="tcutest tcumttest tcucodec tchtest tchmttest tchmgr" -MYCOMMANDFILES="$MYCOMMANDFILES tcbtest tcbmttest tcbmgr tcatest tcamgr" -MYMAN1FILES="tcutest.1 tcumttest.1 tcucodec.1 tchtest.1 tchmttest.1 tchmgr.1" -MYMAN1FILES="$MYMAN1FILES tcbtest.1 tcbmttest.1 tcbmgr.1 tcatest.1 tcamgr.1" -MYMAN3FILES="tokyocabinet.3 tcutil.3 tcxstr.3 tclist.3 tcmap.3 tcmdb.3 tcmpool.3" -MYMAN3FILES="$MYMAN3FILES tchdb.3 tcbdb.3 tcadb.3" -MYDOCUMENTFILES="COPYING ChangeLog THANKS doc" -MYPCFILES="tokyocabinet.pc" - -# Building flags -MYCFLAGS="-std=c99 -Wall -fPIC -fsigned-char -O2" -MYCPPFLAGS="-I. -I\$(INCLUDEDIR) -L$HOME/include -L/usr/local/include -DNDEBUG -D_GNU_SOURCE=1" -MYLDFLAGS="-L. -L\$(LIBDIR) -L$HOME/lib -L/usr/local/lib" -MYRUNPATH="\$(LIBDIR)" -MYLDLIBPATHENV="LD_LIBRARY_PATH" -MYPOSTCMD="true" - -# Building paths -pathtmp="$PATH" -PATH="$HOME/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" -PATH="$PATH:/usr/ccs/bin:/usr/ucb:/usr/xpg4/bin:/usr/xpg6/bin:$pathtmp" -LIBRARY_PATH="$HOME/lib:/usr/local/lib:$LIBRARY_PATH" -LD_LIBRARY_PATH="$HOME/lib:/usr/local/lib:$LD_LIBRARY_PATH" -CPATH="$HOME/include:/usr/local/include:$CPATH" -PKG_CONFIG_PATH="$HOME/lib/pkgconfig:/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH" -export PATH LIBRARY_PATH LD_LIBRARY_PATH CPATH PKG_CONFIG_PATH - - - -#================================================================ -# Options -#================================================================ - - -# Internal variables -enables="" - -# Debug mode -AC_ARG_ENABLE(debug, - AC_HELP_STRING([--enable-debug], [build for debugging])) -if test "$enable_debug" = "yes" -then - MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g" - MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG" - MYLDFLAGS="$MYLDFLAGS -static" - enables="$enables (debug)" -fi - -# Developping mode -AC_ARG_ENABLE(devel, - AC_HELP_STRING([--enable-devel], [build for development])) -if test "$enable_devel" = "yes" -then - MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -O2 -pipe" - MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG" - enables="$enables (devel)" -fi - -# Profiling mode -AC_ARG_ENABLE(profile, - AC_HELP_STRING([--enable-profile], [build for profiling])) -if test "$enable_profile" = "yes" -then - MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -pg -O2 -pipe" - enables="$enables (profile)" -fi - -# 64-bit offset mode -AC_ARG_ENABLE(off64, - AC_HELP_STRING([--enable-off64], [build with 64-bit file offset on 32-bit system])) -if test "$enable_off64" = "yes" -then - MYCPPFLAGS="$MYCPPFLAGS -D_FILE_OFFSET_BITS=64" - enables="$enables (off64)" -fi - -# Fastest mode -AC_ARG_ENABLE(fastest, - AC_HELP_STRING([--enable-fastest], [build for fastest run])) -if test "$enable_fastest" = "yes" -then - MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -O3" - MYCFLAGS="$MYCFLAGS -fomit-frame-pointer -fforce-addr -minline-all-stringops" - MYCPPFLAGS="$MYCPPFLAGS -D_MYFASTEST" - enables="$enables (fastest)" -fi - -# Swapping byte-orders mode -AC_ARG_ENABLE(swab, - AC_HELP_STRING([--enable-swab], [build for swapping byte-orders])) -if test "$enable_swab" = "yes" -then - MYCPPFLAGS="$MYCPPFLAGS -D_MYSWAB" - enables="$enables (swab)" -fi - -# Micro yield mode -AC_ARG_ENABLE(uyield, - AC_HELP_STRING([--enable-uyield], [build for detecting race conditions])) -if test "$enable_uyield" = "yes" -then - MYCPPFLAGS="$MYCPPFLAGS -D_MYMICROYIELD" - enables="$enables (uyield)" -fi - -# Disable ZLIB compression -AC_ARG_ENABLE(zlib, - AC_HELP_STRING([--disable-zlib], [build without ZLIB compression])) -if test "$enable_zlib" = "no" -then - MYCPPFLAGS="$MYCPPFLAGS -D_MYNOZLIB" - enables="$enables (no-zlib)" -fi - -# Disable POSIX thread -AC_ARG_ENABLE(pthread, - AC_HELP_STRING([--disable-pthread], [build without POSIX thread support])) -if test "$enable_pthread" = "no" -then - MYCPPFLAGS="$MYCPPFLAGS -D_MYNOPTHREAD" - enables="$enables (no-pthread)" -fi - -# Disable shared object -AC_ARG_ENABLE(shared, - AC_HELP_STRING([--disable-shared], [avoid to build shared libraries])) -if test "$enable_shared" = "no" -then - enables="$enables (no-shared)" -fi - -# Messages -printf '#================================================================\n' -printf '# Configuring Tokyo Cabinet version %s%s.\n' "$PACKAGE_VERSION" "$enables" -printf '#================================================================\n' - - - -#================================================================ -# Checking Commands and Libraries -#================================================================ - -# C compiler -AC_PROG_CC - -# Byte order -AC_C_BIGENDIAN(MYCPPFLAGS="$MYCPPFLAGS -D_MYBIGEND") - -# Underlying libraries -AC_CHECK_LIB(c, main) -AC_CHECK_LIB(m, main) -if test "$enable_pthread" != "no" -then -AC_CHECK_LIB(pthread, main) -fi -if test "$enable_zlib" != "no" -then - AC_CHECK_LIB(z, main) -fi - -# Shared libraries -if test "$enable_shared" != "no" && test "$enable_profile" != "yes" -then - if uname | grep Darwin >/dev/null - then - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.$MYLIBVER.$MYLIBREV.0.dylib" - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.$MYLIBVER.dylib" - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.dylib" - MYLDLIBPATHENV="DYLD_LIBRARY_PATH" - else - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.so.$MYLIBVER.$MYLIBREV.0" - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.so.$MYLIBVER" - MYLIBRARYFILES="$MYLIBRARYFILES libtokyocabinet.so" - fi -fi - - - -#================================================================ -# Generic Settings -#================================================================ - -# Export variables -AC_SUBST(MYLIBVER) -AC_SUBST(MYLIBREV) -AC_SUBST(MYFORMATVER) -AC_SUBST(MYHEADERFILES) -AC_SUBST(MYLIBRARYFILES) -AC_SUBST(MYLIBOBJFILES) -AC_SUBST(MYCOMMANDFILES) -AC_SUBST(MYMAN1FILES) -AC_SUBST(MYMAN3FILES) -AC_SUBST(MYDOCUMENTFILES) -AC_SUBST(MYPCFILES) -AC_SUBST(MYCFLAGS) -AC_SUBST(MYCPPFLAGS) -AC_SUBST(MYLDFLAGS) -AC_SUBST(MYRUNPATH) -AC_SUBST(MYLDLIBPATHENV) -AC_SUBST(MYPOSTCMD) - -# Targets -AC_OUTPUT(Makefile tokyocabinet.pc) - -# Messages -printf '#================================================================\n' -printf '# Ready to make.\n' -printf '#================================================================\n' - - - -# END OF FILE diff --git a/bacula/src/lib/tokyocabinet/myconf.c b/bacula/src/lib/tokyocabinet/myconf.c deleted file mode 100644 index afcc086e9e..0000000000 --- a/bacula/src/lib/tokyocabinet/myconf.c +++ /dev/null @@ -1,225 +0,0 @@ -/************************************************************************************************* - * System-dependent configurations of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include "myconf.h" - - - -/************************************************************************************************* - * common settings - *************************************************************************************************/ - - -int _tc_dummyfunc(void){ - return 0; -} - - -int _tc_dummyfuncv(int a, ...){ - return 0; -} - - - -/************************************************************************************************* - * for ZLIB - *************************************************************************************************/ - - -#if TCUSEZLIB - - -#include - -#define ZLIBBUFSIZ 8192 - - -static char *_tc_deflate_impl(const char *ptr, int size, int *sp, int mode); -static char *_tc_inflate_impl(const char *ptr, int size, int *sp, int mode); -static unsigned int _tc_getcrc_impl(const char *ptr, int size); - - -char *(*_tc_deflate)(const char *, int, int *, int) = _tc_deflate_impl; -char *(*_tc_inflate)(const char *, int, int *, int) = _tc_inflate_impl; -unsigned int (*_tc_getcrc)(const char *, int) = _tc_getcrc_impl; - - -static char *_tc_deflate_impl(const char *ptr, int size, int *sp, int mode){ - assert(ptr && size >= 0 && sp); - z_stream zs; - char *buf, *swap; - unsigned char obuf[ZLIBBUFSIZ]; - int rv, asiz, bsiz, osiz; - zs.zalloc = Z_NULL; - zs.zfree = Z_NULL; - zs.opaque = Z_NULL; - switch(mode){ - case _TCZMRAW: - if(deflateInit2(&zs, 5, Z_DEFLATED, -15, 7, Z_DEFAULT_STRATEGY) != Z_OK) - return NULL; - break; - case _TCZMGZIP: - if(deflateInit2(&zs, 6, Z_DEFLATED, 15 + 16, 9, Z_DEFAULT_STRATEGY) != Z_OK) - return NULL; - break; - default: - if(deflateInit2(&zs, 6, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY) != Z_OK) - return NULL; - break; - } - asiz = size + 16; - if(asiz < ZLIBBUFSIZ) asiz = ZLIBBUFSIZ; - if(!(buf = malloc(asiz))){ - deflateEnd(&zs); - return NULL; - } - bsiz = 0; - zs.next_in = (unsigned char *)ptr; - zs.avail_in = size; - zs.next_out = obuf; - zs.avail_out = ZLIBBUFSIZ; - while((rv = deflate(&zs, Z_FINISH)) == Z_OK){ - osiz = ZLIBBUFSIZ - zs.avail_out; - if(bsiz + osiz > asiz){ - asiz = asiz * 2 + osiz; - if(!(swap = realloc(buf, asiz))){ - free(buf); - deflateEnd(&zs); - return NULL; - } - buf = swap; - } - memcpy(buf + bsiz, obuf, osiz); - bsiz += osiz; - zs.next_out = obuf; - zs.avail_out = ZLIBBUFSIZ; - } - if(rv != Z_STREAM_END){ - free(buf); - deflateEnd(&zs); - return NULL; - } - osiz = ZLIBBUFSIZ - zs.avail_out; - if(bsiz + osiz + 1 > asiz){ - asiz = asiz * 2 + osiz; - if(!(swap = realloc(buf, asiz))){ - free(buf); - deflateEnd(&zs); - return NULL; - } - buf = swap; - } - memcpy(buf + bsiz, obuf, osiz); - bsiz += osiz; - buf[bsiz] = '\0'; - if(mode == _TCZMRAW) bsiz++; - *sp = bsiz; - deflateEnd(&zs); - return buf; -} - - -static char *_tc_inflate_impl(const char *ptr, int size, int *sp, int mode){ - assert(ptr && size >= 0 && sp); - z_stream zs; - char *buf, *swap; - unsigned char obuf[ZLIBBUFSIZ]; - int rv, asiz, bsiz, osiz; - zs.zalloc = Z_NULL; - zs.zfree = Z_NULL; - zs.opaque = Z_NULL; - switch(mode){ - case _TCZMRAW: - if(inflateInit2(&zs, -15) != Z_OK) return NULL; - break; - case _TCZMGZIP: - if(inflateInit2(&zs, 15 + 16) != Z_OK) return NULL; - break; - default: - if(inflateInit2(&zs, 15) != Z_OK) return NULL; - break; - } - asiz = size * 2 + 16; - if(asiz < ZLIBBUFSIZ) asiz = ZLIBBUFSIZ; - if(!(buf = malloc(asiz))){ - inflateEnd(&zs); - return NULL; - } - bsiz = 0; - zs.next_in = (unsigned char *)ptr; - zs.avail_in = size; - zs.next_out = obuf; - zs.avail_out = ZLIBBUFSIZ; - while((rv = inflate(&zs, Z_NO_FLUSH)) == Z_OK){ - osiz = ZLIBBUFSIZ - zs.avail_out; - if(bsiz + osiz >= asiz){ - asiz = asiz * 2 + osiz; - if(!(swap = realloc(buf, asiz))){ - free(buf); - inflateEnd(&zs); - return NULL; - } - buf = swap; - } - memcpy(buf + bsiz, obuf, osiz); - bsiz += osiz; - zs.next_out = obuf; - zs.avail_out = ZLIBBUFSIZ; - } - if(rv != Z_STREAM_END){ - free(buf); - inflateEnd(&zs); - return NULL; - } - osiz = ZLIBBUFSIZ - zs.avail_out; - if(bsiz + osiz >= asiz){ - asiz = asiz * 2 + osiz; - if(!(swap = realloc(buf, asiz))){ - free(buf); - inflateEnd(&zs); - return NULL; - } - buf = swap; - } - memcpy(buf + bsiz, obuf, osiz); - bsiz += osiz; - buf[bsiz] = '\0'; - *sp = bsiz; - inflateEnd(&zs); - return buf; -} - - -static unsigned int _tc_getcrc_impl(const char *ptr, int size){ - assert(ptr && size >= 0); - int crc = crc32(0, Z_NULL, 0); - return crc32(crc, (unsigned char *)ptr, size); -} - - -#else - - -char *(*_tc_deflate)(const char *, int, int *, int) = NULL; -char *(*_tc_inflate)(const char *, int, int *, int) = NULL; -unsigned int (*_tc_getcrc)(const char *, int) = NULL; - - -#endif - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/myconf.h b/bacula/src/lib/tokyocabinet/myconf.h deleted file mode 100644 index 3e44152873..0000000000 --- a/bacula/src/lib/tokyocabinet/myconf.h +++ /dev/null @@ -1,438 +0,0 @@ -/************************************************************************************************* - * System-dependent configurations of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#ifndef _MYCONF_H // duplication check -#define _MYCONF_H - - - -/************************************************************************************************* - * system discrimination - *************************************************************************************************/ - - -#if defined(__linux__) - -#define _SYS_LINUX_ -#define ESTSYSNAME "Linux" - -#elif defined(__FreeBSD__) - -#define _SYS_FREEBSD_ -#define ESTSYSNAME "FreeBSD" - -#elif defined(__NetBSD__) - -#define _SYS_NETBSD_ -#define ESTSYSNAME "NetBSD" - -#elif defined(__OpenBSD__) - -#define _SYS_OPENBSD_ -#define ESTSYSNAME "OpenBSD" - -#elif defined(__sun__) - -#define _SYS_SUNOS_ -#define ESTSYSNAME "SunOS" - -#elif defined(__hpux) - -#define _SYS_HPUX_ -#define ESTSYSNAME "HP-UX" - -#elif defined(__osf) - -#define _SYS_TRU64_ -#define ESTSYSNAME "Tru64" - -#elif defined(_AIX) - -#define _SYS_AIX_ -#define ESTSYSNAME "AIX" - -#elif defined(__APPLE__) && defined(__MACH__) - -#define _SYS_MACOSX_ -#define ESTSYSNAME "Mac OS X" - -#elif defined(_MSC_VER) - -#define _SYS_MSVC_ -#define ESTSYSNAME "Windows (VC++)" - -#elif defined(_WIN32) - -#define _SYS_MINGW_ -#define ESTSYSNAME "Windows (MinGW)" - -#elif defined(__CYGWIN__) - -#define _SYS_CYGWIN_ -#define ESTSYSNAME "Windows (Cygwin)" - -#else - -#define _SYS_GENERIC_ -#define ESTSYSNAME "Generic" - -#endif - - - -/************************************************************************************************* - * common settings - *************************************************************************************************/ - - -#if defined(NDEBUG) -#define TCDODEBUG(TC_expr) \ - do { \ - } while(false) -#else -#define TCDODEBUG(TC_expr) \ - do { \ - TC_expr; \ - } while(false) -#endif - -#define TCSWAB16(TC_num) \ - ( \ - ((TC_num & 0x00ffU) << 8) | \ - ((TC_num & 0xff00U) >> 8) \ - ) - -#define TCSWAB32(TC_num) \ - ( \ - ((TC_num & 0x000000ffUL) << 24) | \ - ((TC_num & 0x0000ff00UL) << 8) | \ - ((TC_num & 0x00ff0000UL) >> 8) | \ - ((TC_num & 0xff000000UL) >> 24) \ - ) - -#define TCSWAB64(TC_num) \ - ( \ - ((TC_num & 0x00000000000000ffULL) << 56) | \ - ((TC_num & 0x000000000000ff00ULL) << 40) | \ - ((TC_num & 0x0000000000ff0000ULL) << 24) | \ - ((TC_num & 0x00000000ff000000ULL) << 8) | \ - ((TC_num & 0x000000ff00000000ULL) >> 8) | \ - ((TC_num & 0x0000ff0000000000ULL) >> 24) | \ - ((TC_num & 0x00ff000000000000ULL) >> 40) | \ - ((TC_num & 0xff00000000000000ULL) >> 56) \ - ) - -#if defined(_MYBIGEND) || defined(_MYSWAB) -#define TCBIGEND 1 -#define TCHTOIS(TC_num) TCSWAB16(TC_num) -#define TCHTOIL(TC_num) TCSWAB32(TC_num) -#define TCHTOILL(TC_num) TCSWAB64(TC_num) -#define TCITOHS(TC_num) TCSWAB16(TC_num) -#define TCITOHL(TC_num) TCSWAB32(TC_num) -#define TCITOHLL(TC_num) TCSWAB64(TC_num) -#else -#define TCBIGEND 0 -#define TCHTOIS(TC_num) (TC_num) -#define TCHTOIL(TC_num) (TC_num) -#define TCHTOILL(TC_num) (TC_num) -#define TCITOHS(TC_num) (TC_num) -#define TCITOHL(TC_num) (TC_num) -#define TCITOHLL(TC_num) (TC_num) -#endif - -#if defined(_MYNOZLIB) -#define TCUSEZLIB 0 -#else -#define TCUSEZLIB 1 -#endif - -#if defined(_MYNOPTHREAD) -#define TCUSEPTHREAD 0 -#else -#define TCUSEPTHREAD 1 -#endif - -#if defined(_MYMICROYIELD) -#define TCMICROYIELD 1 -#else -#define TCMICROYIELD 0 -#endif - -#define sizeof(a) ((int)sizeof(a)) - -int _tc_dummyfunc(void); -int _tc_dummyfuncv(int a, ...); - - - -/************************************************************************************************* - * general headers - *************************************************************************************************/ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if TCUSEPTHREAD -#include -#endif - - - -/************************************************************************************************* - * notation of filesystems - *************************************************************************************************/ - - -#define MYPATHCHR '/' -#define MYPATHSTR "/" -#define MYEXTCHR '.' -#define MYEXTSTR "." -#define MYCDIRSTR "." -#define MYPDIRSTR ".." - - - -/************************************************************************************************* - * for ZLIB - *************************************************************************************************/ - - -enum { - _TCZMZLIB, - _TCZMRAW, - _TCZMGZIP -}; - - -extern char *(*_tc_deflate)(const char *, int, int *, int); - -extern char *(*_tc_inflate)(const char *, int, int *, int); - -extern unsigned int (*_tc_getcrc)(const char *, int); - - - -/************************************************************************************************* - * for POSIX thread disability - *************************************************************************************************/ - - -#if ! TCUSEPTHREAD - -#define pthread_once_t int -#undef PTHREAD_ONCE_INIT -#define PTHREAD_ONCE_INIT 0 -#define pthread_once(TC_a, TC_b) _tc_dummyfuncv((int)(TC_a), (TC_b)) - -#define pthread_mutexattr_t int -#undef PTHREAD_MUTEX_RECURSIVE -#define PTHREAD_MUTEX_RECURSIVE 0 -#define pthread_mutexattr_init(TC_a) _tc_dummyfuncv((int)(TC_a)) -#define pthread_mutexattr_destroy(TC_a) _tc_dummyfuncv((int)(TC_a)) -#define pthread_mutexattr_settype(TC_a, TC_b) _tc_dummyfuncv((int)(TC_a), (TC_b)) - -#define pthread_mutex_t int -#undef PTHREAD_MUTEX_INITIALIZER -#define PTHREAD_MUTEX_INITIALIZER 0 -#define pthread_mutex_init(TC_a, TC_b) _tc_dummyfuncv((int)(TC_a), (TC_b)) -#define pthread_mutex_destroy(TC_a) _tc_dummyfuncv((int)(TC_a)) -#define pthread_mutex_lock(TC_a) _tc_dummyfuncv((int)(TC_a)) -#define pthread_mutex_unlock(TC_a) _tc_dummyfuncv((int)(TC_a)) - -#define pthread_rwlock_t int -#undef PTHREAD_RWLOCK_INITIALIZER -#define PTHREAD_RWLOCK_INITIALIZER 0 -#define pthread_rwlock_init(TC_a, TC_b) _tc_dummyfuncv((int)(TC_a), (TC_b)) -#define pthread_rwlock_destroy(TC_a) _tc_dummyfuncv((int)(TC_a)) -#define pthread_rwlock_rdlock(TC_a) _tc_dummyfuncv((int)(TC_a)) -#define pthread_rwlock_wrlock(TC_a) _tc_dummyfuncv((int)(TC_a)) -#define pthread_rwlock_unlock(TC_a) _tc_dummyfuncv((int)(TC_a)) - -#define pthread_key_create(TC_a, TC_b) _tc_dummyfuncv((int)(TC_a), (TC_b)) -#define pthread_key_delete(TC_a) _tc_dummyfuncv((int)(TC_a)) -#define pthread_setspecific(TC_a, TC_b) _tc_dummyfuncv((int)(TC_a)) -#define pthread_getspecific(TC_a) _tc_dummyfuncv((int)(TC_a)) - -#define pthread_create(TC_th, TC_attr, TC_func, TC_arg) \ - (*(TC_th) = 0, (TC_func)(TC_arg), 0) -#define pthread_join(TC_th, TC_rv) \ - (*(TC_rv) = NULL, 0) -#define pthread_detach(TC_th) 0 - -#endif - -#if TCUSEPTHREAD && TCMICROYIELD -#define TCTESTYIELD() \ - do { \ - static uint32_t cnt = 0; \ - if(((++cnt) & (0x20 - 1)) == 0){ \ - pthread_yield(); \ - if(cnt > 0x1000) cnt = (uint32_t)time(NULL) % 0x1000; \ - } \ - } while(false) -#undef assert -#define assert(TC_expr) \ - do { \ - if(!(TC_expr)){ \ - fprintf(stderr, "assertion failed: %s\n", #TC_expr); \ - abort(); \ - } \ - TCTESTYIELD(); \ - } while(false) -#else -#define TCTESTYIELD() \ - do { \ - } while(false); -#endif - - - -/************************************************************************************************* - * utilities for implementation - *************************************************************************************************/ - - -#define TCNUMBUFSIZ 32 // size of a buffer for a number - -/* set a buffer for a variable length number */ -#define TCSETVNUMBUF(TC_len, TC_buf, TC_num) \ - do { \ - int _TC_num = (TC_num); \ - if(_TC_num == 0){ \ - ((signed char *)(TC_buf))[0] = 0; \ - (TC_len) = 1; \ - } else { \ - (TC_len) = 0; \ - while(_TC_num > 0){ \ - int _TC_rem = _TC_num & 0x7f; \ - _TC_num >>= 7; \ - if(_TC_num > 0){ \ - ((signed char *)(TC_buf))[(TC_len)] = -_TC_rem - 1; \ - } else { \ - ((signed char *)(TC_buf))[(TC_len)] = _TC_rem; \ - } \ - (TC_len)++; \ - } \ - } \ - } while(false) - -/* set a buffer for a variable length number of 64-bit */ -#define TCSETVNUMBUF64(TC_len, TC_buf, TC_num) \ - do { \ - long long int _TC_num = (TC_num); \ - if(_TC_num == 0){ \ - ((signed char *)(TC_buf))[0] = 0; \ - (TC_len) = 1; \ - } else { \ - (TC_len) = 0; \ - while(_TC_num > 0){ \ - int _TC_rem = _TC_num & 0x7f; \ - _TC_num >>= 7; \ - if(_TC_num > 0){ \ - ((signed char *)(TC_buf))[(TC_len)] = -_TC_rem - 1; \ - } else { \ - ((signed char *)(TC_buf))[(TC_len)] = _TC_rem; \ - } \ - (TC_len)++; \ - } \ - } \ - } while(false) - -/* read a variable length buffer */ -#define TCREADVNUMBUF(TC_buf, TC_num, TC_step) \ - do { \ - TC_num = 0; \ - int _TC_base = 1; \ - int _TC_i = 0; \ - while(true){ \ - if(((signed char *)(TC_buf))[_TC_i] >= 0){ \ - TC_num += ((signed char *)(TC_buf))[_TC_i] * _TC_base; \ - break; \ - } \ - TC_num += _TC_base * (((signed char *)(TC_buf))[_TC_i] + 1) * -1; \ - _TC_base <<= 7; \ - _TC_i++; \ - } \ - (TC_step) = _TC_i + 1; \ - } while(false) - -/* read a variable length buffer */ -#define TCREADVNUMBUF64(TC_buf, TC_num, TC_step) \ - do { \ - TC_num = 0; \ - long long int _TC_base = 1; \ - int _TC_i = 0; \ - while(true){ \ - if(((signed char *)(TC_buf))[_TC_i] >= 0){ \ - TC_num += ((signed char *)(TC_buf))[_TC_i] * _TC_base; \ - break; \ - } \ - TC_num += _TC_base * (((signed char *)(TC_buf))[_TC_i] + 1) * -1; \ - _TC_base <<= 7; \ - _TC_i++; \ - } \ - (TC_step) = _TC_i + 1; \ - } while(false) - -/* Compare keys of two records by lexical order. */ -#define TCCMPLEXICAL(TC_rv, TC_aptr, TC_asiz, TC_bptr, TC_bsiz) \ - do { \ - (TC_rv) = 0; \ - int _TC_min = (TC_asiz) < (TC_bsiz) ? (TC_asiz) : (TC_bsiz); \ - for(int _TC_i = 0; _TC_i < _TC_min; _TC_i++){ \ - if(((unsigned char *)(TC_aptr))[_TC_i] != ((unsigned char *)(TC_bptr))[_TC_i]){ \ - (TC_rv) = ((unsigned char *)(TC_aptr))[_TC_i] - ((unsigned char *)(TC_bptr))[_TC_i]; \ - break; \ - } \ - } \ - if((TC_rv) == 0) (TC_rv) = (TC_asiz) - (TC_bsiz); \ - } while(false) - - - -#endif // duplication check - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcadb.c b/bacula/src/lib/tokyocabinet/tcadb.c deleted file mode 100644 index 73b952ebea..0000000000 --- a/bacula/src/lib/tokyocabinet/tcadb.c +++ /dev/null @@ -1,523 +0,0 @@ -/************************************************************************************************* - * The abstract database API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include "tcutil.h" -#include "tchdb.h" -#include "tcbdb.h" -#include "tcadb.h" -#include "myconf.h" - - - -/************************************************************************************************* - * API - *************************************************************************************************/ - - -/* Create an abstract database object. */ -TCADB *tcadbnew(void){ - TCADB *adb; - TCMALLOC(adb, sizeof(*adb)); - adb->name = NULL; - adb->mdb = NULL; - adb->hdb = NULL; - adb->bdb = NULL; - adb->capnum = -1; - adb->capsiz = -1; - adb->capcnt = 0; - adb->cur = NULL; - return adb; -} - - -/* Delete an abstract database object. */ -void tcadbdel(TCADB *adb){ - assert(adb); - if(adb->name) tcadbclose(adb); - free(adb); -} - - -/* Open an abstract database. */ -bool tcadbopen(TCADB *adb, const char *name){ - assert(adb && name); - TCLIST *elems = tcstrsplit(name, "#"); - char *path = tclistshift2(elems); - if(!path){ - tclistdel(elems); - return false; - } - int64_t bnum = -1; - int64_t capnum = -1; - int64_t capsiz = -1; - bool owmode = true; - bool ocmode = true; - bool otmode = false; - bool onlmode = false; - bool onbmode = false; - int8_t apow = -1; - int8_t fpow = -1; - bool tlmode = false; - bool tdmode = false; - int32_t rcnum = -1; - int32_t lmemb = -1; - int32_t nmemb = -1; - int32_t lcnum = -1; - int32_t ncnum = -1; - int ln = TCLISTNUM(elems); - for(int i = 0; i < ln; i++){ - const char *elem = TCLISTVALPTR(elems, i); - char *pv = strchr(elem, '='); - if(!pv) continue; - *(pv++) = '\0'; - if(!tcstricmp(elem, "bnum")){ - bnum = strtoll(pv, NULL, 10); - } else if(!tcstricmp(elem, "capnum")){ - capnum = strtoll(pv, NULL, 10); - } else if(!tcstricmp(elem, "capsiz")){ - capsiz = strtoll(pv, NULL, 10); - } else if(!tcstricmp(elem, "mode")){ - owmode = strchr(pv, 'w') || strchr(pv, 'W'); - ocmode = strchr(pv, 'c') || strchr(pv, 'C'); - otmode = strchr(pv, 't') || strchr(pv, 'T'); - onlmode = strchr(pv, 'e') || strchr(pv, 'E'); - onbmode = strchr(pv, 'f') || strchr(pv, 'F'); - } else if(!tcstricmp(elem, "apow")){ - apow = strtol(pv, NULL, 10); - } else if(!tcstricmp(elem, "fpow")){ - fpow = strtol(pv, NULL, 10); - } else if(!tcstricmp(elem, "opts")){ - if(strchr(pv, 'l') || strchr(pv, 'L')) tlmode = true; - if(strchr(pv, 'd') || strchr(pv, 'D')) tdmode = true; - } else if(!tcstricmp(elem, "rcnum")){ - rcnum = strtol(pv, NULL, 10); - } else if(!tcstricmp(elem, "lmemb")){ - lmemb = strtol(pv, NULL, 10); - } else if(!tcstricmp(elem, "nmemb")){ - nmemb = strtol(pv, NULL, 10); - } else if(!tcstricmp(elem, "lcnum")){ - lcnum = strtol(pv, NULL, 10); - } else if(!tcstricmp(elem, "ncnum")){ - ncnum = strtol(pv, NULL, 10); - } - } - tclistdel(elems); - if(!tcstricmp(path, "*")){ - adb->mdb = bnum > 0 ? tcmdbnew2(bnum) : tcmdbnew(); - adb->capnum = capnum; - adb->capsiz = capsiz; - adb->capcnt = 0; - } else if(tcstribwm(path, ".tch")){ - TCHDB *hdb = tchdbnew(); - tchdbsetmutex(hdb); - int opts = 0; - if(tlmode) opts |= HDBTLARGE; - if(tdmode) opts |= HDBTDEFLATE; - tchdbtune(hdb, bnum, apow, fpow, opts); - tchdbsetcache(hdb, rcnum); - int omode = owmode ? HDBOWRITER : HDBOREADER; - if(ocmode) omode |= HDBOCREAT; - if(otmode) omode |= HDBOTRUNC; - if(onlmode) omode |= HDBONOLCK; - if(onbmode) omode |= HDBOLCKNB; - if(!tchdbopen(hdb, path, omode)){ - tchdbdel(hdb); - free(path); - return false; - } - adb->hdb = hdb; - } else if(tcstribwm(path, ".tcb")){ - TCBDB *bdb = tcbdbnew(); - tcbdbsetmutex(bdb); - int opts = 0; - if(tlmode) opts |= BDBTLARGE; - if(tdmode) opts |= BDBTDEFLATE; - tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts); - tcbdbsetcache(bdb, lcnum, ncnum); - if(capnum > 0) tcbdbsetcapnum(bdb, capnum); - int omode = owmode ? BDBOWRITER : BDBOREADER; - if(ocmode) omode |= BDBOCREAT; - if(otmode) omode |= BDBOTRUNC; - if(onlmode) omode |= BDBONOLCK; - if(onbmode) omode |= BDBOLCKNB; - if(!tcbdbopen(bdb, path, omode)){ - tcbdbdel(bdb); - free(path); - return false; - } - adb->bdb = bdb; - adb->cur = tcbdbcurnew(bdb); - } else { - free(path); - return false; - } - free(path); - adb->name = tcstrdup(name); - return true; -} - - -/* Close an abstract database object. */ -bool tcadbclose(TCADB *adb){ - assert(adb); - int err = false; - if(!adb->name) return false; - if(adb->mdb){ - tcmdbdel(adb->mdb); - adb->mdb = NULL; - } else if(adb->hdb){ - if(!tchdbclose(adb->hdb)) err = true; - tchdbdel(adb->hdb); - adb->hdb = NULL; - } else if(adb->bdb){ - tcbdbcurdel(adb->cur); - if(!tcbdbclose(adb->bdb)) err = true; - tcbdbdel(adb->bdb); - adb->bdb = NULL; - } - free(adb->name); - adb->name = NULL; - return !err; -} - - -/* Store a record into an abstract database object. */ -bool tcadbput(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(adb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - bool err = false; - if(adb->mdb){ - tcmdbput(adb->mdb, kbuf, ksiz, vbuf, vsiz); - if(adb->capnum > 0 || adb->capsiz > 0){ - adb->capcnt++; - if((adb->capcnt & 0xff) == 0){ - if(adb->capnum > 0 && tcmdbrnum(adb->mdb) > adb->capnum) tcmdbcutfront(adb->mdb, 0x100); - if(adb->capsiz > 0 && tcmdbmsiz(adb->mdb) > adb->capsiz) tcmdbcutfront(adb->mdb, 0x200); - } - } - } else if(adb->hdb){ - if(!tchdbput(adb->hdb, kbuf, ksiz, vbuf, vsiz)) err = true; - } else if(adb->bdb){ - if(!tcbdbput(adb->bdb, kbuf, ksiz, vbuf, vsiz)) err = true; - } else { - err = true; - } - return !err; -} - - -/* Store a string record into an abstract object. */ -bool tcadbput2(TCADB *adb, const char *kstr, const char *vstr){ - assert(adb && kstr && vstr); - return tcadbput(adb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Store a new record into an abstract database object. */ -bool tcadbputkeep(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(adb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - bool err = false; - if(adb->mdb){ - if(tcmdbputkeep(adb->mdb, kbuf, ksiz, vbuf, vsiz)){ - if(adb->capnum > 0 || adb->capsiz > 0){ - adb->capcnt++; - if((adb->capcnt & 0xff) == 0){ - if(adb->capnum > 0 && tcmdbrnum(adb->mdb) > adb->capnum) tcmdbcutfront(adb->mdb, 0x100); - if(adb->capsiz > 0 && tcmdbmsiz(adb->mdb) > adb->capsiz) tcmdbcutfront(adb->mdb, 0x200); - } - } - } else { - err = true; - } - } else if(adb->hdb){ - if(!tchdbputkeep(adb->hdb, kbuf, ksiz, vbuf, vsiz)) err = true; - } else if(adb->bdb){ - if(!tcbdbputkeep(adb->bdb, kbuf, ksiz, vbuf, vsiz)) err = true; - } else { - err = true; - } - return !err; -} - - -/* Store a new string record into an abstract database object. */ -bool tcadbputkeep2(TCADB *adb, const char *kstr, const char *vstr){ - assert(adb && kstr && vstr); - return tcadbputkeep(adb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Concatenate a value at the end of the existing record in an abstract database object. */ -bool tcadbputcat(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(adb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - bool err = false; - if(adb->mdb){ - tcmdbputcat(adb->mdb, kbuf, ksiz, vbuf, vsiz); - if(adb->capnum > 0 || adb->capsiz > 0){ - adb->capcnt++; - if((adb->capcnt & 0xff) == 0){ - if(adb->capnum > 0 && tcmdbrnum(adb->mdb) > adb->capnum) tcmdbcutfront(adb->mdb, 0x100); - if(adb->capsiz > 0 && tcmdbmsiz(adb->mdb) > adb->capsiz) tcmdbcutfront(adb->mdb, 0x200); - } - } - } else if(adb->hdb){ - if(!tchdbputcat(adb->hdb, kbuf, ksiz, vbuf, vsiz)) err = true; - } else if(adb->bdb){ - if(!tcbdbputcat(adb->bdb, kbuf, ksiz, vbuf, vsiz)) err = true; - } else { - err = true; - } - return !err; -} - - -/* Concatenate a string value at the end of the existing record in an abstract database object. */ -bool tcadbputcat2(TCADB *adb, const char *kstr, const char *vstr){ - assert(adb && kstr && vstr); - return tcadbputcat(adb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Remove a record of an abstract database object. */ -bool tcadbout(TCADB *adb, const void *kbuf, int ksiz){ - assert(adb && kbuf && ksiz >= 0); - bool err = false; - if(adb->mdb){ - if(!tcmdbout(adb->mdb, kbuf, ksiz)) err = true; - } else if(adb->hdb){ - if(!tchdbout(adb->hdb, kbuf, ksiz)) err = true; - } else if(adb->bdb){ - if(!tcbdbout(adb->bdb, kbuf, ksiz)) err = true; - } else { - err = true; - } - return !err; -} - - -/* Remove a string record of an abstract database object. */ -bool tcadbout2(TCADB *adb, const char *kstr){ - assert(adb && kstr); - return tcadbout(adb, kstr, strlen(kstr)); -} - - -/* Retrieve a record in an abstract database object. */ -void *tcadbget(TCADB *adb, const void *kbuf, int ksiz, int *sp){ - assert(adb && kbuf && ksiz >= 0 && sp); - char *rv; - if(adb->mdb){ - rv = tcmdbget(adb->mdb, kbuf, ksiz, sp); - } else if(adb->hdb){ - rv = tchdbget(adb->hdb, kbuf, ksiz, sp); - } else if(adb->bdb){ - rv = tcbdbget(adb->bdb, kbuf, ksiz, sp); - } else { - rv = NULL; - } - return rv; -} - - -/* Retrieve a string record in an abstract database object. */ -char *tcadbget2(TCADB *adb, const char *kstr){ - assert(adb && kstr); - int vsiz; - return tcadbget(adb, kstr, strlen(kstr), &vsiz); -} - - -/* Get the size of the value of a record in an abstract database object. */ -int tcadbvsiz(TCADB *adb, const void *kbuf, int ksiz){ - assert(adb && kbuf && ksiz >= 0); - int rv; - if(adb->mdb){ - rv = tcmdbvsiz(adb->mdb, kbuf, ksiz); - } else if(adb->hdb){ - rv = tchdbvsiz(adb->hdb, kbuf, ksiz); - } else if(adb->bdb){ - rv = tcbdbvsiz(adb->bdb, kbuf, ksiz); - } else { - rv = -1; - } - return rv; -} - - -/* Get the size of the value of a string record in an abstract database object. */ -int tcadbvsiz2(TCADB *adb, const char *kstr){ - assert(adb && kstr); - return tcadbvsiz(adb, kstr, strlen(kstr)); -} - - -/* Initialize the iterator of an abstract database object. */ -bool tcadbiterinit(TCADB *adb){ - assert(adb); - bool err = false; - if(adb->mdb){ - tcmdbiterinit(adb->mdb); - } else if(adb->hdb){ - if(!tchdbiterinit(adb->hdb)) err = true; - } else if(adb->bdb){ - if(!tcbdbcurfirst(adb->cur)){ - int ecode = tcbdbecode(adb->bdb); - if(ecode != TCESUCCESS && ecode != TCEINVALID && ecode != TCEKEEP && ecode != TCENOREC) - err = true; - } - } else { - err = true; - } - return !err; -} - - -/* Get the next key of the iterator of an abstract database object. */ -void *tcadbiternext(TCADB *adb, int *sp){ - assert(adb && sp); - char *rv; - if(adb->mdb){ - rv = tcmdbiternext(adb->mdb, sp); - } else if(adb->hdb){ - rv = tchdbiternext(adb->hdb, sp); - } else if(adb->bdb){ - rv = tcbdbcurkey(adb->cur, sp); - tcbdbcurnext(adb->cur); - } else { - rv = NULL; - } - return rv; -} - - -/* Get the next key string of the iterator of an abstract database object. */ -char *tcadbiternext2(TCADB *adb){ - assert(adb); - int vsiz; - return tcadbiternext(adb, &vsiz); -} - - -/* Get forward matching keys in an abstract database object. */ -TCLIST *tcadbfwmkeys(TCADB *adb, const void *pbuf, int psiz, int max){ - assert(adb && pbuf && psiz >= 0); - TCLIST *rv; - if(adb->mdb){ - rv = tcmdbfwmkeys(adb->mdb, pbuf, psiz, max); - } else if(adb->hdb){ - rv = tchdbfwmkeys(adb->hdb, pbuf, psiz, max); - } else if(adb->bdb){ - rv = tcbdbfwmkeys(adb->bdb, pbuf, psiz, max); - } else { - rv = tclistnew(); - } - return rv; -} - - -/* Get forward matching string keys in an abstract database object. */ -TCLIST *tcadbfwmkeys2(TCADB *adb, const char *pstr, int max){ - assert(adb && pstr); - return tcadbfwmkeys(adb, pstr, strlen(pstr), max); -} - - -/* Synchronize updated contents of an abstract database object with the file and the device. */ -bool tcadbsync(TCADB *adb){ - assert(adb); - bool err = false; - if(adb->mdb){ - err = true; - } else if(adb->hdb){ - if(!tchdbsync(adb->hdb)) err = true; - } else if(adb->bdb){ - if(!tcbdbsync(adb->bdb)) err = true; - } else { - err = true; - } - return !err; -} - - -/* Remove all records of an abstract database object. */ -bool tcadbvanish(TCADB *adb){ - assert(adb); - bool err = false; - if(adb->mdb){ - tcmdbvanish(adb->mdb); - } else if(adb->hdb){ - if(!tchdbvanish(adb->hdb)) err = true; - } else if(adb->bdb){ - if(!tcbdbvanish(adb->bdb)) err = true; - } else { - err = true; - } - return !err; -} - - -/* Copy the database file of an abstract database object. */ -bool tcadbcopy(TCADB *adb, const char *path){ - assert(adb && path); - bool err = false; - if(adb->mdb){ - err = true; - } else if(adb->hdb){ - if(!tchdbcopy(adb->hdb, path)) err = true; - } else if(adb->bdb){ - if(!tcbdbcopy(adb->bdb, path)) err = true; - } else { - err = true; - } - return !err; -} - - -/* Get the number of records of an abstract database object. */ -uint64_t tcadbrnum(TCADB *adb){ - assert(adb); - uint64_t rv; - if(adb->mdb){ - rv = tcmdbrnum(adb->mdb); - } else if(adb->hdb){ - rv = tchdbrnum(adb->hdb); - } else if(adb->bdb){ - rv = tcbdbrnum(adb->bdb); - } else { - rv = 0; - } - return rv; -} - - -/* Get the size of the database of an abstract database object. */ -uint64_t tcadbsize(TCADB *adb){ - assert(adb); - uint64_t rv; - if(adb->mdb){ - rv = tcmdbmsiz(adb->mdb); - } else if(adb->hdb){ - rv = tchdbfsiz(adb->hdb); - } else if(adb->bdb){ - rv = tcbdbfsiz(adb->bdb); - } else { - rv = 0; - } - return rv; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcadb.h b/bacula/src/lib/tokyocabinet/tcadb.h deleted file mode 100644 index b33773bf10..0000000000 --- a/bacula/src/lib/tokyocabinet/tcadb.h +++ /dev/null @@ -1,320 +0,0 @@ -/************************************************************************************************* - * The abstract database API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#ifndef _TCADB_H /* duplication check */ -#define _TCADB_H - -#if defined(__cplusplus) -#define __TCADB_CLINKAGEBEGIN extern "C" { -#define __TCADB_CLINKAGEEND } -#else -#define __TCADB_CLINKAGEBEGIN -#define __TCADB_CLINKAGEEND -#endif -__TCADB_CLINKAGEBEGIN - - -#include -#include -#include -#include -#include -#include -#include - - - -/************************************************************************************************* - * API - *************************************************************************************************/ - - -typedef struct { /* type of structure for an abstract database */ - char *name; /* name of the database */ - TCMDB *mdb; /* on-memory database object */ - TCHDB *hdb; /* hash database object */ - TCBDB *bdb; /* B+ tree database object */ - int64_t capnum; /* capacity number of records */ - int64_t capsiz; /* capacity size of using memory */ - uint32_t capcnt; /* count for capacity check */ - BDBCUR *cur; /* cursor of B+ tree */ -} TCADB; - - -/* Create an abstract database object. - The return value is the new abstract database object. */ -TCADB *tcadbnew(void); - - -/* Delete an abstract database object. - `adb' specifies the abstract database object. */ -void tcadbdel(TCADB *adb); - - -/* Open an abstract database. - `adb' specifies the abstract database object. - `name' specifies the name of the database. If it is "*", the database will be an on-memory - database. If its suffix is ".tch", the database will be a hash database. If its suffix is - ".tcb", the database will be a B+ tree database. Otherwise, this function fails. Tuning - parameters can trail the name, separated by "#". Each parameter is composed of the name and - the number, separated by "=". On-memory database supports "bnum", "capnum", and "capsiz". - Hash database supports "mode", "bnum", "apow", "fpow", "opts", and "rcnum". B+ tree database - supports "mode", "lmemb", "nmemb", "bnum", "apow", "fpow", "opts", "lcnum", and "ncnum". - "capnum" specifies the capacity number of records. "capsiz" specifies the capacity size of - using memory. Records spilled the capacity are removed by the storing order. "mode" can - contain "w" of writer, "r" of reader, "c" of creating, "t" of truncating, "e" of no locking, - and "f" of non-blocking lock. The default mode is relevant to "wc". "opts" can contains "l" - of large option, "d" of Deflate option, and "b" of TCBS option. For example, - "casket.tch#bnum=1000000#opts=ld" means that the name of the database file is "casket.tch", - and the bucket number is 1000000, and the options are large and Deflate. - If successful, the return value is true, else, it is false. */ -bool tcadbopen(TCADB *adb, const char *name); - - -/* Close an abstract database object. - `adb' specifies the abstract database object. - If successful, the return value is true, else, it is false. - Update of a database is assured to be written when the database is closed. If a writer opens - a database but does not close it appropriately, the database will be broken. */ -bool tcadbclose(TCADB *adb); - - -/* Store a record into an abstract database object. - `adb' specifies the abstract database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, it is overwritten. */ -bool tcadbput(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a string record into an abstract object. - `adb' specifies the abstract database object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, it is overwritten. */ -bool tcadbput2(TCADB *adb, const char *kstr, const char *vstr); - - -/* Store a new record into an abstract database object. - `adb' specifies the abstract database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tcadbputkeep(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a new string record into an abstract database object. - `adb' specifies the abstract database object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tcadbputkeep2(TCADB *adb, const char *kstr, const char *vstr); - - -/* Concatenate a value at the end of the existing record in an abstract database object. - `adb' specifies the abstract database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If there is no corresponding record, a new record is created. */ -bool tcadbputcat(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Concatenate a string value at the end of the existing record in an abstract database object. - `adb' specifies the abstract database object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If there is no corresponding record, a new record is created. */ -bool tcadbputcat2(TCADB *adb, const char *kstr, const char *vstr); - - -/* Remove a record of an abstract database object. - `adb' specifies the abstract database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. */ -bool tcadbout(TCADB *adb, const void *kbuf, int ksiz); - - -/* Remove a string record of an abstract database object. - `adb' specifies the abstract database object. - `kstr' specifies the string of the key. - If successful, the return value is true, else, it is false. */ -bool tcadbout2(TCADB *adb, const char *kstr); - - -/* Retrieve a record in an abstract database object. - `adb' specifies the abstract database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the corresponding - record. `NULL' is returned if no record corresponds. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -void *tcadbget(TCADB *adb, const void *kbuf, int ksiz, int *sp); - - -/* Retrieve a string record in an abstract database object. - `adb' specifies the abstract database object. - `kstr' specifies the string of the key. - If successful, the return value is the string of the value of the corresponding record. - `NULL' is returned if no record corresponds. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcadbget2(TCADB *adb, const char *kstr); - - -/* Get the size of the value of a record in an abstract database object. - `adb' specifies the abstract database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. */ -int tcadbvsiz(TCADB *adb, const void *kbuf, int ksiz); - - -/* Get the size of the value of a string record in an abstract database object. - `adb' specifies the abstract database object. - `kstr' specifies the string of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. */ -int tcadbvsiz2(TCADB *adb, const char *kstr); - - -/* Initialize the iterator of an abstract database object. - `adb' specifies the abstract database object. - If successful, the return value is true, else, it is false. - The iterator is used in order to access the key of every record stored in a database. */ -bool tcadbiterinit(TCADB *adb); - - -/* Get the next key of the iterator of an abstract database object. - `adb' specifies the abstract database object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the next key, else, it is - `NULL'. `NULL' is returned when no record is to be get out of the iterator. - Because an additional zero code is appended at the end of the region of the return value, the - return value can be treated as a character string. Because the region of the return value is - allocated with the `malloc' call, it should be released with the `free' call when it is no - longer in use. It is possible to access every record by iteration of calling this function. - It is allowed to update or remove records whose keys are fetched while the iteration. - However, it is not assured if updating the database is occurred while the iteration. Besides, - the order of this traversal access method is arbitrary, so it is not assured that the order of - storing matches the one of the traversal access. */ -void *tcadbiternext(TCADB *adb, int *sp); - - -/* Get the next key string of the iterator of an abstract database object. - `adb' specifies the abstract database object. - If successful, the return value is the string of the next key, else, it is `NULL'. `NULL' is - returned when no record is to be get out of the iterator. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. It is possible to access every - record by iteration of calling this function. However, it is not assured if updating the - database is occurred while the iteration. Besides, the order of this traversal access method - is arbitrary, so it is not assured that the order of storing matches the one of the traversal - access. */ -char *tcadbiternext2(TCADB *adb); - - -/* Get forward matching keys in an abstract database object. - `adb' specifies the abstract database object. - `pbuf' specifies the pointer to the region of the prefix. - `psiz' specifies the size of the region of the prefix. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the corresponding keys. This function does never fail - and return an empty list even if no key corresponds. - Because the object of the return value is created with the function `tclistnew', it should be - deleted with the function `tclistdel' when it is no longer in use. Note that this function - may be very slow because every key in the database is scanned. */ -TCLIST *tcadbfwmkeys(TCADB *adb, const void *pbuf, int psiz, int max); - - -/* Get forward matching string keys in an abstract database object. - `adb' specifies the abstract database object. - `pstr' specifies the string of the prefix. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the corresponding keys. This function does never fail - and return an empty list even if no key corresponds. - Because the object of the return value is created with the function `tclistnew', it should be - deleted with the function `tclistdel' when it is no longer in use. Note that this function - may be very slow because every key in the database is scanned. */ -TCLIST *tcadbfwmkeys2(TCADB *adb, const char *pstr, int max); - - -/* Synchronize updated contents of an abstract database object with the file and the device. - `adb' specifies the abstract database object. - If successful, the return value is true, else, it is false. - This function fails and has no effect for on-memory database. */ -bool tcadbsync(TCADB *adb); - - -/* Remove all records of an abstract database object. - `adb' specifies the abstract database object. - If successful, the return value is true, else, it is false. */ -bool tcadbvanish(TCADB *adb); - - -/* Copy the database file of an abstract database object. - `adb' specifies the abstract database object. - `path' specifies the path of the destination file. If it begins with `@', the trailing - substring is executed as a command line. - If successful, the return value is true, else, it is false. False is returned if the executed - command returns non-zero code. - The database file is assured to be kept synchronized and not modified while the copying or - executing operation is in progress. So, this function is useful to create a backup file of - the database file. This function fails and has no effect for on-memory database. */ -bool tcadbcopy(TCADB *adb, const char *path); - - -/* Get the number of records of an abstract database object. - `adb' specifies the abstract database object. - The return value is the number of records or 0 if the object does not connect to any database - instance. */ -uint64_t tcadbrnum(TCADB *adb); - - -/* Get the size of the database of an abstract database object. - `adb' specifies the abstract database object. - The return value is the size of the database or 0 if the object does not connect to any - database instance. */ -uint64_t tcadbsize(TCADB *adb); - - - -__TCADB_CLINKAGEEND -#endif /* duplication check */ - - -/* END OF FILE */ diff --git a/bacula/src/lib/tokyocabinet/tcamgr.c b/bacula/src/lib/tokyocabinet/tcamgr.c deleted file mode 100644 index 691099b6e0..0000000000 --- a/bacula/src/lib/tokyocabinet/tcamgr.c +++ /dev/null @@ -1,538 +0,0 @@ -/************************************************************************************************* - * The command line utility of the abstract database API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include -#include "myconf.h" - - -/* global variables */ -const char *g_progname; // program name - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void printerr(TCADB *adb); -static int printdata(const char *ptr, int size, bool px); -static char *hextoobj(const char *str, int *sp); -static int runcreate(int argc, char **argv); -static int runinform(int argc, char **argv); -static int runput(int argc, char **argv); -static int runout(int argc, char **argv); -static int runget(int argc, char **argv); -static int runlist(int argc, char **argv); -static int runversion(int argc, char **argv); -static int proccreate(const char *name); -static int procinform(const char *name); -static int procput(const char *name, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - int dmode); -static int procout(const char *name, const char *kbuf, int ksiz); -static int procget(const char *name, const char *kbuf, int ksiz, bool px, bool pz); -static int proclist(const char *name, int max, bool pv, bool px, const char *fmstr); -static int procversion(void); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "create")){ - rv = runcreate(argc, argv); - } else if(!strcmp(argv[1], "inform")){ - rv = runinform(argc, argv); - } else if(!strcmp(argv[1], "put")){ - rv = runput(argc, argv); - } else if(!strcmp(argv[1], "out")){ - rv = runout(argc, argv); - } else if(!strcmp(argv[1], "get")){ - rv = runget(argc, argv); - } else if(!strcmp(argv[1], "list")){ - rv = runlist(argc, argv); - } else if(!strcmp(argv[1], "version") || !strcmp(argv[1], "--version")){ - rv = runversion(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: the command line utility of the abstract database API\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s create name\n", g_progname); - fprintf(stderr, " %s inform name\n", g_progname); - fprintf(stderr, " %s put [-sx] [-dk|-dc] name key value\n", g_progname); - fprintf(stderr, " %s out [-sx] name key\n", g_progname); - fprintf(stderr, " %s get [-sx] [-px] [-pz] name key\n", g_progname); - fprintf(stderr, " %s list [-m num] [-pv] [-px] [-fm str] name\n", g_progname); - fprintf(stderr, " %s version\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print error information */ -static void printerr(TCADB *adb){ - fprintf(stderr, "%s: error\n", g_progname); -} - - -/* print record data */ -static int printdata(const char *ptr, int size, bool px){ - int len = 0; - while(size-- > 0){ - if(px){ - if(len > 0) putchar(' '); - len += printf("%02X", *(unsigned char *)ptr); - } else { - putchar(*ptr); - len++; - } - ptr++; - } - return len; -} - - -/* create a binary object from a hexadecimal string */ -static char *hextoobj(const char *str, int *sp){ - int len = strlen(str); - char *buf = tcmalloc(len + 1); - int j = 0; - for(int i = 0; i < len; i += 2){ - while(strchr(" \n\r\t\f\v", str[i])){ - i++; - } - char mbuf[3]; - if((mbuf[0] = str[i]) == '\0') break; - if((mbuf[1] = str[i+1]) == '\0') break; - mbuf[2] = '\0'; - buf[j++] = (char)strtol(mbuf, NULL, 16); - } - buf[j] = '\0'; - *sp = j; - return buf; -} - - -/* parse arguments of create command */ -static int runcreate(int argc, char **argv){ - char *name = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - usage(); - } else if(!name){ - name = argv[i]; - } else { - usage(); - } - } - if(!name) usage(); - int rv = proccreate(name); - return rv; -} - - -/* parse arguments of inform command */ -static int runinform(int argc, char **argv){ - char *name = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - usage(); - } else if(!name){ - name = argv[i]; - } else { - usage(); - } - } - if(!name) usage(); - name = tcsprintf("%s#mode=r", name); - int rv = procinform(name); - free(name); - return rv; -} - - -/* parse arguments of put command */ -static int runput(int argc, char **argv){ - char *name = NULL; - char *key = NULL; - char *value = NULL; - int dmode = 0; - bool sx = false; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-dk")){ - dmode = -1; - } else if(!strcmp(argv[i], "-dc")){ - dmode = 1; - } else if(!strcmp(argv[i], "-sx")){ - sx = true; - } else { - usage(); - } - } else if(!name){ - name = argv[i]; - } else if(!key){ - key = argv[i]; - } else if(!value){ - value = argv[i]; - } else { - usage(); - } - } - if(!name || !key || !value) usage(); - int ksiz, vsiz; - char *kbuf, *vbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - vbuf = hextoobj(value, &vsiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - vsiz = strlen(value); - vbuf = tcmemdup(value, vsiz); - } - int rv = procput(name, kbuf, ksiz, vbuf, vsiz, dmode); - free(vbuf); - free(kbuf); - return rv; -} - - -/* parse arguments of out command */ -static int runout(int argc, char **argv){ - char *name = NULL; - char *key = NULL; - bool sx = false; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-sx")){ - sx = true; - } else { - usage(); - } - } else if(!name){ - name = argv[i]; - } else if(!key){ - key = argv[i]; - } else { - usage(); - } - } - if(!name || !key) usage(); - int ksiz; - char *kbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - } - int rv = procout(name, kbuf, ksiz); - free(kbuf); - return rv; -} - - -/* parse arguments of get command */ -static int runget(int argc, char **argv){ - char *name = NULL; - char *key = NULL; - bool sx = false; - bool px = false; - bool pz = false; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-sx")){ - sx = true; - } else if(!strcmp(argv[i], "-px")){ - px = true; - } else if(!strcmp(argv[i], "-pz")){ - pz = true; - } else { - usage(); - } - } else if(!name){ - name = argv[i]; - } else if(!key){ - key = argv[i]; - } else { - usage(); - } - } - if(!name || !key) usage(); - int ksiz; - char *kbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - } - name = tcsprintf("%s#mode=r", name); - int rv = procget(name, kbuf, ksiz, px, pz); - free(name); - free(kbuf); - return rv; -} - - -/* parse arguments of list command */ -static int runlist(int argc, char **argv){ - char *name = NULL; - int max = -1; - bool pv = false; - bool px = false; - char *fmstr = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-m")){ - if(++i >= argc) usage(); - max = atoi(argv[i]); - } else if(!strcmp(argv[i], "-pv")){ - pv = true; - } else if(!strcmp(argv[i], "-px")){ - px = true; - } else if(!strcmp(argv[i], "-fm")){ - if(++i >= argc) usage(); - fmstr = argv[i]; - } else { - usage(); - } - } else if(!name){ - name = argv[i]; - } else { - usage(); - } - } - if(!name) usage(); - name = tcsprintf("%s#mode=r", name); - int rv = proclist(name, max, pv, px, fmstr); - free(name); - return rv; -} - - -/* parse arguments of version command */ -static int runversion(int argc, char **argv){ - int rv = procversion(); - return rv; -} - - -/* perform create command */ -static int proccreate(const char *name){ - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - printerr(adb); - tcadbdel(adb); - return 1; - } - bool err = false; - if(!tcadbclose(adb)){ - printerr(adb); - err = true; - } - tcadbdel(adb); - return err ? 1 : 0; -} - - -/* perform inform command */ -static int procinform(const char *name){ - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - printerr(adb); - tcadbdel(adb); - return 1; - } - bool err = false; - printf("record number: %llu\n", (unsigned long long)tcadbrnum(adb)); - printf("size: %llu\n", (unsigned long long)tcadbsize(adb)); - if(!tcadbclose(adb)){ - printerr(adb); - err = true; - } - tcadbdel(adb); - return err ? 1 : 0; -} - - -/* perform put command */ -static int procput(const char *name, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - int dmode){ - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - printerr(adb); - tcadbdel(adb); - return 1; - } - bool err = false; - switch(dmode){ - case -1: - if(!tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz)){ - printerr(adb); - err = true; - } - break; - case 1: - if(!tcadbputcat(adb, kbuf, ksiz, vbuf, vsiz)){ - printerr(adb); - err = true; - } - break; - default: - if(!tcadbput(adb, kbuf, ksiz, vbuf, vsiz)){ - printerr(adb); - err = true; - } - break; - } - if(!tcadbclose(adb)){ - if(!err) printerr(adb); - err = true; - } - tcadbdel(adb); - return err ? 1 : 0; -} - - -/* perform out command */ -static int procout(const char *name, const char *kbuf, int ksiz){ - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - printerr(adb); - tcadbdel(adb); - return 1; - } - bool err = false; - if(!tcadbout(adb, kbuf, ksiz)){ - printerr(adb); - err = true; - } - if(!tcadbclose(adb)){ - if(!err) printerr(adb); - err = true; - } - tcadbdel(adb); - return err ? 1 : 0; -} - - -/* perform get command */ -static int procget(const char *name, const char *kbuf, int ksiz, bool px, bool pz){ - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - printerr(adb); - tcadbdel(adb); - return 1; - } - bool err = false; - int vsiz; - char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz); - if(vbuf){ - printdata(vbuf, vsiz, px); - if(!pz) putchar('\n'); - free(vbuf); - } else { - printerr(adb); - err = true; - } - if(!tcadbclose(adb)){ - if(!err) printerr(adb); - err = true; - } - tcadbdel(adb); - return err ? 1 : 0; -} - - -/* perform list command */ -static int proclist(const char *name, int max, bool pv, bool px, const char *fmstr){ - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - printerr(adb); - tcadbdel(adb); - return 1; - } - bool err = false; - if(fmstr){ - TCLIST *keys = tcadbfwmkeys2(adb, fmstr, max); - for(int i = 0; i < tclistnum(keys); i++){ - int ksiz; - const char *kbuf = tclistval(keys, i, &ksiz); - printdata(kbuf, ksiz, px); - if(pv){ - int vsiz; - char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz); - if(vbuf){ - putchar('\t'); - printdata(vbuf, vsiz, px); - free(vbuf); - } - } - putchar('\n'); - } - tclistdel(keys); - } else { - if(!tcadbiterinit(adb)){ - printerr(adb); - err = true; - } - int ksiz; - char *kbuf; - int cnt = 0; - while((kbuf = tcadbiternext(adb, &ksiz)) != NULL){ - printdata(kbuf, ksiz, px); - if(pv){ - int vsiz; - char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz); - if(vbuf){ - putchar('\t'); - printdata(vbuf, vsiz, px); - free(vbuf); - } - } - putchar('\n'); - free(kbuf); - if(max >= 0 && ++cnt >= max) break; - } - } - if(!tcadbclose(adb)){ - if(!err) printerr(adb); - err = true; - } - tcadbdel(adb); - return err ? 1 : 0; -} - - -/* perform version command */ -static int procversion(void){ - printf("Tokyo Cabinet version %s (%d:%s)\n", tcversion, _TC_LIBVER, _TC_FORMATVER); - printf("Copyright (C) 2006-2008 Mikio Hirabayashi\n"); - return 0; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcatest.c b/bacula/src/lib/tokyocabinet/tcatest.c deleted file mode 100644 index 44a2567de0..0000000000 --- a/bacula/src/lib/tokyocabinet/tcatest.c +++ /dev/null @@ -1,797 +0,0 @@ -/************************************************************************************************* - * The test cases of the abstract database API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include -#include "myconf.h" - -#define RECBUFSIZ 32 // buffer for records - - -/* global variables */ -const char *g_progname; // program name - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void iprintf(const char *format, ...); -static void eprint(TCADB *adb, const char *func); -static int myrand(int range); -static int runwrite(int argc, char **argv); -static int runread(int argc, char **argv); -static int runremove(int argc, char **argv); -static int runrcat(int argc, char **argv); -static int runmisc(int argc, char **argv); -static int runwicked(int argc, char **argv); -static int procwrite(const char *name, int rnum); -static int procread(const char *name); -static int procremove(const char *name); -static int procrcat(const char *name, int rnum); -static int procmisc(const char *name, int rnum); -static int procwicked(const char *name, int rnum); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - srand((unsigned int)(tctime() * 1000) % UINT_MAX); - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "write")){ - rv = runwrite(argc, argv); - } else if(!strcmp(argv[1], "read")){ - rv = runread(argc, argv); - } else if(!strcmp(argv[1], "remove")){ - rv = runremove(argc, argv); - } else if(!strcmp(argv[1], "rcat")){ - rv = runrcat(argc, argv); - } else if(!strcmp(argv[1], "misc")){ - rv = runmisc(argc, argv); - } else if(!strcmp(argv[1], "wicked")){ - rv = runwicked(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: test cases of the abstract database API of Tokyo Cabinet\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s write name rnum\n", g_progname); - fprintf(stderr, " %s read name\n", g_progname); - fprintf(stderr, " %s remove name\n", g_progname); - fprintf(stderr, " %s rcat name rnum\n", g_progname); - fprintf(stderr, " %s misc name rnum\n", g_progname); - fprintf(stderr, " %s wicked name rnum\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print formatted information string and flush the buffer */ -static void iprintf(const char *format, ...){ - va_list ap; - va_start(ap, format); - vprintf(format, ap); - fflush(stdout); - va_end(ap); -} - - -/* print error message of abstract database */ -static void eprint(TCADB *adb, const char *func){ - fprintf(stderr, "%s: %s: error\n", g_progname, func); -} - - -/* get a random number */ -static int myrand(int range){ - return (int)((double)range * rand() / (RAND_MAX + 1.0)); -} - - -/* parse arguments of write command */ -static int runwrite(int argc, char **argv){ - char *name = NULL; - char *rstr = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - usage(); - } else if(!name){ - name = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!name || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int rv = procwrite(name, rnum); - return rv; -} - - -/* parse arguments of read command */ -static int runread(int argc, char **argv){ - char *name = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - usage(); - } else if(!name){ - name = argv[i]; - } else { - usage(); - } - } - if(!name) usage(); - int rv = procread(name); - return rv; -} - - -/* parse arguments of remove command */ -static int runremove(int argc, char **argv){ - char *name = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - usage(); - } else if(!name){ - name = argv[i]; - } else { - usage(); - } - } - if(!name) usage(); - int rv = procremove(name); - return rv; -} - - -/* parse arguments of rcat command */ -static int runrcat(int argc, char **argv){ - char *name = NULL; - char *rstr = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - usage(); - } else if(!name){ - name = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!name || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int rv = procrcat(name, rnum); - return rv; -} - - -/* parse arguments of misc command */ -static int runmisc(int argc, char **argv){ - char *name = NULL; - char *rstr = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - usage(); - } else if(!name){ - name = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!name || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int rv = procmisc(name, rnum); - return rv; -} - - -/* parse arguments of wicked command */ -static int runwicked(int argc, char **argv){ - char *name = NULL; - char *rstr = NULL; - for(int i = 2; i < argc; i++){ - if(!name && argv[i][0] == '-'){ - usage(); - } else if(!name){ - name = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!name || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int rv = procwicked(name, rnum); - return rv; -} - - -/* perform write command */ -static int procwrite(const char *name, int rnum){ - iprintf("\n name=%s rnum=%d\n\n", name, rnum); - bool err = false; - double stime = tctime(); - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - eprint(adb, "tcadbopen"); - err = true; - } - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", i); - if(!tcadbput(adb, buf, len, buf, len)){ - eprint(adb, "tcadbput"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb)); - iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb)); - if(!tcadbclose(adb)){ - eprint(adb, "tcadbclose"); - err = true; - } - tcadbdel(adb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform read command */ -static int procread(const char *name){ - iprintf("\n name=%s\n\n", name); - bool err = false; - double stime = tctime(); - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - eprint(adb, "tcadbopen"); - err = true; - } - int rnum = tcadbrnum(adb); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - int vsiz; - char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(adb, "tcadbget"); - err = true; - break; - } - free(vbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb)); - iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb)); - if(!tcadbclose(adb)){ - eprint(adb, "tcadbclose"); - err = true; - } - tcadbdel(adb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform remove command */ -static int procremove(const char *name){ - iprintf("\n name=%s\n\n", name); - bool err = false; - double stime = tctime(); - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - eprint(adb, "tcadbopen"); - err = true; - } - int rnum = tcadbrnum(adb); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - if(!tcadbout(adb, kbuf, ksiz)){ - eprint(adb, "tcadbout"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb)); - iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb)); - if(!tcadbclose(adb)){ - eprint(adb, "tcadbclose"); - err = true; - } - tcadbdel(adb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform rcat command */ -static int procrcat(const char *name, int rnum){ - iprintf("\n name=%s rnum=%d\n\n", name, rnum); - int pnum = rnum / 5 + 1; - bool err = false; - double stime = tctime(); - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - eprint(adb, "tcadbopen"); - err = true; - } - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(pnum)); - if(!tcadbputcat(adb, kbuf, ksiz, kbuf, ksiz)){ - eprint(adb, "tcadbputcat"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb)); - iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb)); - if(!tcadbclose(adb)){ - eprint(adb, "tcadbclose"); - err = true; - } - tcadbdel(adb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform misc command */ -static int procmisc(const char *name, int rnum){ - iprintf("\n name=%s rnum=%d\n\n", name, rnum); - bool err = false; - double stime = tctime(); - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - eprint(adb, "tcadbopen"); - err = true; - } - iprintf("writing:\n"); - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", i); - if(!tcadbputkeep(adb, buf, len, buf, len)){ - eprint(adb, "tcadbputkeep"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("reading:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - int vsiz; - char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(adb, "tcadbget"); - err = true; - break; - } else if(vsiz != ksiz || memcmp(vbuf, kbuf, vsiz)){ - eprint(adb, "(validation)"); - err = true; - free(vbuf); - break; - } - free(vbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(tcadbrnum(adb) != rnum){ - eprint(adb, "(validation)"); - err = true; - } - iprintf("random writing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '*', vsiz); - if(!tcadbput(adb, kbuf, ksiz, vbuf, vsiz)){ - eprint(adb, "tcadbput"); - err = true; - break; - } - int rsiz; - char *rbuf = tcadbget(adb, kbuf, ksiz, &rsiz); - if(!rbuf){ - eprint(adb, "tcadbget"); - err = true; - break; - } - if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(adb, "(validation)"); - err = true; - free(rbuf); - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - free(rbuf); - } - iprintf("word writing:\n"); - const char *words[] = { - "a", "A", "bb", "BB", "ccc", "CCC", "dddd", "DDDD", "eeeee", "EEEEEE", - "mikio", "hirabayashi", "tokyo", "cabinet", "hyper", "estraier", "19780211", "birth day", - "one", "first", "two", "second", "three", "third", "four", "fourth", "five", "fifth", - "_[1]_", "uno", "_[2]_", "dos", "_[3]_", "tres", "_[4]_", "cuatro", "_[5]_", "cinco", - "[\xe5\xb9\xb3\xe6\x9e\x97\xe5\xb9\xb9\xe9\x9b\x84]", "[\xe9\xa6\xac\xe9\xb9\xbf]", NULL - }; - for(int i = 0; words[i] != NULL; i += 2){ - const char *kbuf = words[i]; - int ksiz = strlen(kbuf); - const char *vbuf = words[i+1]; - int vsiz = strlen(vbuf); - if(!tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz)){ - eprint(adb, "tcadbputkeep"); - err = true; - break; - } - if(rnum > 250) putchar('.'); - } - if(rnum > 250) iprintf(" (%08d)\n", sizeof(words) / sizeof(*words)); - iprintf("random erasing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - tcadbout(adb, kbuf, ksiz); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("writing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "[%d]", i); - char vbuf[RECBUFSIZ]; - int vsiz = i % RECBUFSIZ; - memset(vbuf, '*', vsiz); - if(!tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz)){ - eprint(adb, "tcadbputkeep"); - err = true; - break; - } - if(vsiz < 1){ - char tbuf[PATH_MAX]; - for(int j = 0; j < PATH_MAX; j++){ - tbuf[j] = myrand(0x100); - } - if(!tcadbput(adb, kbuf, ksiz, tbuf, PATH_MAX)){ - eprint(adb, "tcadbput"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("erasing:\n"); - for(int i = 1; i <= rnum; i++){ - if(i % 2 == 1){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "[%d]", i); - if(!tcadbout(adb, kbuf, ksiz)){ - eprint(adb, "tcadbout"); - err = true; - break; - } - tcadbout(adb, kbuf, ksiz); - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("iterator checking:\n"); - if(!tcadbiterinit(adb)){ - eprint(adb, "tcadbiterinit"); - err = true; - } - char *kbuf; - int ksiz; - int inum = 0; - for(int i = 1; (kbuf = tcadbiternext(adb, &ksiz)) != NULL; i++, inum++){ - int vsiz; - char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(adb, "tcadbget"); - err = true; - free(kbuf); - break; - } - free(vbuf); - free(kbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(rnum > 250) iprintf(" (%08d)\n", inum); - if(inum != tcadbrnum(adb)){ - eprint(adb, "(validation)"); - err = true; - } - if(*name != '*' && !tcadbsync(adb)){ - eprint(adb, "tcadbsync"); - err = true; - } - if(!tcadbvanish(adb)){ - eprint(adb, "tcadbsync"); - err = true; - } - iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb)); - iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb)); - if(!tcadbclose(adb)){ - eprint(adb, "tcadbclose"); - err = true; - } - tcadbdel(adb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform wicked command */ -static int procwicked(const char *name, int rnum){ - iprintf("\n name=%s rnum=%d\n\n", name, rnum); - bool err = false; - double stime = tctime(); - TCADB *adb = tcadbnew(); - if(!tcadbopen(adb, name)){ - eprint(adb, "tcadbopen"); - err = true; - } - TCMAP *map = tcmapnew2(rnum / 5); - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '*', vsiz); - vbuf[vsiz] = '\0'; - char *rbuf; - switch(myrand(16)){ - case 0: - putchar('0'); - if(!tcadbput(adb, kbuf, ksiz, vbuf, vsiz)){ - eprint(adb, "tcadbput"); - err = true; - } - tcmapput(map, kbuf, ksiz, vbuf, vsiz); - break; - case 1: - putchar('1'); - if(!tcadbput2(adb, kbuf, vbuf)){ - eprint(adb, "tcadbput2"); - err = true; - } - tcmapput2(map, kbuf, vbuf); - break; - case 2: - putchar('2'); - tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz); - tcmapputkeep(map, kbuf, ksiz, vbuf, vsiz); - break; - case 3: - putchar('3'); - tcadbputkeep2(adb, kbuf, vbuf); - tcmapputkeep2(map, kbuf, vbuf); - break; - case 4: - putchar('4'); - if(!tcadbputcat(adb, kbuf, ksiz, vbuf, vsiz)){ - eprint(adb, "tcadbputcat"); - err = true; - } - tcmapputcat(map, kbuf, ksiz, vbuf, vsiz); - break; - case 5: - putchar('5'); - if(!tcadbputcat2(adb, kbuf, vbuf)){ - eprint(adb, "tcadbputcat2"); - err = true; - } - tcmapputcat2(map, kbuf, vbuf); - break; - case 6: - putchar('6'); - if(myrand(10) == 0){ - tcadbout(adb, kbuf, ksiz); - tcmapout(map, kbuf, ksiz); - } - break; - case 7: - putchar('7'); - if(myrand(10) == 0){ - tcadbout2(adb, kbuf); - tcmapout2(map, kbuf); - } - break; - case 8: - putchar('8'); - if((rbuf = tcadbget(adb, kbuf, ksiz, &vsiz)) != NULL) free(rbuf); - break; - case 9: - putchar('9'); - if((rbuf = tcadbget2(adb, kbuf)) != NULL) free(rbuf); - break; - case 10: - putchar('A'); - tcadbvsiz(adb, kbuf, ksiz); - break; - case 11: - putchar('B'); - tcadbvsiz2(adb, kbuf); - break; - case 12: - putchar('E'); - if(myrand(rnum / 50) == 0){ - if(!tcadbiterinit(adb)){ - eprint(adb, "tcadbiterinit"); - err = true; - } - } - for(int j = myrand(rnum) / 1000 + 1; j >= 0; j--){ - int iksiz; - char *ikbuf = tcadbiternext(adb, &iksiz); - if(ikbuf) free(ikbuf); - } - break; - default: - putchar('@'); - if(myrand(10000) == 0) srand((unsigned int)(tctime() * 1000) % UINT_MAX); - break; - } - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - tcadbsync(adb); - if(tcadbrnum(adb) != tcmaprnum(map)){ - eprint(adb, "(validation)"); - err = true; - } - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", i - 1); - int vsiz; - const char *vbuf = tcmapget(map, kbuf, ksiz, &vsiz); - int rsiz; - char *rbuf = tcadbget(adb, kbuf, ksiz, &rsiz); - if(vbuf){ - putchar('.'); - if(!rbuf){ - eprint(adb, "tcadbget"); - err = true; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(adb, "(validation)"); - err = true; - } - } else { - putchar('*'); - if(rbuf){ - eprint(adb, "(validation)"); - err = true; - } - } - free(rbuf); - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - tcmapiterinit(map); - int ksiz; - const char *kbuf; - for(int i = 1; (kbuf = tcmapiternext(map, &ksiz)) != NULL; i++){ - putchar('+'); - int vsiz; - const char *vbuf = tcmapiterval(kbuf, &vsiz); - int rsiz; - char *rbuf = tcadbget(adb, kbuf, ksiz, &rsiz); - if(!rbuf){ - eprint(adb, "tcadbget"); - err = true; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(adb, "(validation)"); - err = true; - } - free(rbuf); - if(!tcadbout(adb, kbuf, ksiz)){ - eprint(adb, "tcadbout"); - err = true; - } - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - int mrnum = tcmaprnum(map); - if(mrnum % 50 > 0) iprintf(" (%08d)\n", mrnum); - if(tcadbrnum(adb) != 0){ - eprint(adb, "(validation)"); - err = true; - } - iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb)); - iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb)); - tcmapdel(map); - if(!tcadbclose(adb)){ - eprint(adb, "tcadbclose"); - err = true; - } - tcadbdel(adb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcbdb.c b/bacula/src/lib/tokyocabinet/tcbdb.c deleted file mode 100644 index c97f837fd7..0000000000 --- a/bacula/src/lib/tokyocabinet/tcbdb.c +++ /dev/null @@ -1,3690 +0,0 @@ -/************************************************************************************************* - * The B+ tree database API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include "tcutil.h" -#include "tchdb.h" -#include "tcbdb.h" -#include "myconf.h" - -#define BDBFILEMODE 00644 // permission of created files -#define BDBOPAQUESIZ 64 // size of using opaque field -#define BDBPAGEBUFSIZ 32768 // size of a buffer to read each page -#define BDBNODEIDBASE ((1LL<<48)+1) // base number of node ID -#define BDBLEVELMAX 64 // max level of B+ tree -#define BDBCACHEOUT 8 // number of pages in a process of cacheout - -#define BDBDEFLMEMB 128 // default number of members in each leaf -#define BDBMINLMEMB 4 // minimum number of members in each leaf -#define BDBDEFNMEMB 256 // default number of members in each node -#define BDBMINNMEMB 4 // minimum number of members in each node -#define BDBDEFBNUM 16381 // default bucket number -#define BDBDEFAPOW 8 // default alignment power -#define BDBDEFFPOW 10 // default free block pool power -#define BDBDEFLCNUM 1024 // default number of leaf cache -#define BDBDEFNCNUM 512 // default number of node cache - -typedef struct { // type of structure for a record - char *kbuf; // pointer to the key region - int ksiz; // size of the key region - char *vbuf; // pointer to the value region - int vsiz; // size of the value region - TCLIST *rest; // list of value objects -} BDBREC; - -typedef struct { // type of structure for a leaf page - uint64_t id; // ID number of the leaf - TCLIST *recs; // list of records - uint64_t prev; // ID number of the previous leaf - uint64_t next; // ID number of the next leaf - bool dirty; // whether to be written back - bool dead; // whether to be removed -} BDBLEAF; - -typedef struct { // type of structure for a page index - uint64_t pid; // ID number of the referring page - char *kbuf; // pointer to the key region - int ksiz; // size of the key region -} BDBIDX; - -typedef struct { // type of structure for a node page - uint64_t id; // ID number of the node - uint64_t heir; // ID of the child before the first index - TCLIST *idxs; // list of indexes - bool dirty; // whether to be written back -} BDBNODE; - -enum { // enumeration for duplication behavior - BDBPDOVER, // overwrite an existing value - BDBPDKEEP, // keep the existing value - BDBPDCAT, // concatenate values - BDBPDDUP, // allow duplication of keys - BDBPDDUPB, // allow backward duplication -}; - - -/* private macros */ -#define BDBLOCKMETHOD(TC_bdb, TC_wr) \ - ((TC_bdb)->mmtx ? tcbdblockmethod((TC_bdb), (TC_wr)) : true) -#define BDBUNLOCKMETHOD(TC_bdb) \ - ((TC_bdb)->mmtx ? tcbdbunlockmethod(TC_bdb) : true) -#define BDBLOCKCACHE(TC_bdb) \ - ((TC_bdb)->mmtx ? tcbdblockcache(TC_bdb) : true) -#define BDBUNLOCKCACHE(TC_bdb) \ - ((TC_bdb)->mmtx ? tcbdbunlockcache(TC_bdb) : true) -#define BDBLOCKTRAN(TC_bdb) \ - ((TC_bdb)->mmtx ? tcbdblocktran(TC_bdb) : true) -#define BDBUNLOCKTRAN(TC_bdb) \ - ((TC_bdb)->mmtx ? tcbdbunlocktran(TC_bdb) : true) - - -/* private function prototypes */ -static void tcbdbclear(TCBDB *bdb); -static void tcdumpmeta(TCBDB *bdb); -static void tcloadmeta(TCBDB *bdb); -static BDBLEAF *tcbdbleafnew(TCBDB *bdb, uint64_t prev, uint64_t next); -static bool tcbdbleafcacheout(TCBDB *bdb, BDBLEAF *leaf); -static bool tcbdbleafsave(TCBDB *bdb, BDBLEAF *leaf); -static BDBLEAF *tcbdbleafload(TCBDB *bdb, uint64_t id); -static BDBLEAF *tcbdbgethistleaf(TCBDB *bdb, const char *kbuf, int ksiz); -static bool tcbdbleafaddrec(TCBDB *bdb, BDBLEAF *leaf, int dmode, - const char *kbuf, int ksiz, const char *vbuf, int vsiz); -static int tcbdbleafdatasize(BDBLEAF *leaf); -static BDBLEAF *tcbdbleafdivide(TCBDB *bdb, BDBLEAF *leaf); -static bool tcbdbleafkill(TCBDB *bdb, BDBLEAF *leaf); -static BDBNODE *tcbdbnodenew(TCBDB *bdb, uint64_t heir); -static bool tcbdbnodecacheout(TCBDB *bdb, BDBNODE *node); -static bool tcbdbnodesave(TCBDB *bdb, BDBNODE *node); -static BDBNODE *tcbdbnodeload(TCBDB *bdb, uint64_t id); -static void tcbdbnodeaddidx(TCBDB *bdb, BDBNODE *node, bool order, uint64_t pid, - const char *kbuf, int ksiz); -static bool tcbdbnodesubidx(TCBDB *bdb, BDBNODE *node, uint64_t pid); -static uint64_t tcbdbsearchleaf(TCBDB *bdb, const char *kbuf, int ksiz); -static BDBREC *tcbdbsearchrec(TCBDB *bdb, BDBLEAF *leaf, const char *kbuf, int ksiz, int *ip); -static bool tcbdbcacheadjust(TCBDB *bdb); -static void tcbdbcachepurge(TCBDB *bdb); -static bool tcbdbopenimpl(TCBDB *bdb, const char *path, int omode); -static bool tcbdbcloseimpl(TCBDB *bdb); -static bool tcbdbputimpl(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz, - int dmode); -static bool tcbdboutimpl(TCBDB *bdb, const char *kbuf, int ksiz); -static bool tcbdboutlist(TCBDB *bdb, const char *kbuf, int ksiz); -static const char *tcbdbgetimpl(TCBDB *bdb, const char *kbuf, int ksiz, int *sp); -static int tcbdbgetnum(TCBDB *bdb, const char *kbuf, int ksiz); -static TCLIST *tcbdbgetlist(TCBDB *bdb, const char *kbuf, int ksiz); -static bool tcbdbrangeimpl(TCBDB *bdb, const char *bkbuf, int bksiz, bool binc, - const char *ekbuf, int eksiz, bool einc, int max, TCLIST *keys); -static bool tcbdbrangefwm(TCBDB *bdb, const char *pbuf, int psiz, int max, TCLIST *keys); -static bool tcbdboptimizeimpl(TCBDB *bdb, int32_t lmemb, int32_t nmemb, - int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts); -static bool tcbdbvanishimpl(TCBDB *bdb); -static bool tcbdblockmethod(TCBDB *bdb, bool wr); -static bool tcbdbunlockmethod(TCBDB *bdb); -static bool tcbdblockcache(TCBDB *bdb); -static bool tcbdbunlockcache(TCBDB *bdb); -static bool tcbdblocktran(TCBDB *bdb); -static bool tcbdbunlocktran(TCBDB *bdb); -static bool tcbdbcurfirstimpl(BDBCUR *cur); -static bool tcbdbcurlastimpl(BDBCUR *cur); -static bool tcbdbcurjumpimpl(BDBCUR *cur, const char *kbuf, int ksiz, bool forward); -static bool tcbdbcuradjust(BDBCUR *cur, bool forward); -static bool tcbdbcurprevimpl(BDBCUR *cur); -static bool tcbdbcurnextimpl(BDBCUR *cur); -static bool tcbdbcurputimpl(BDBCUR *cur, const char *vbuf, int vsiz, int mode); -static bool tcbdbcuroutimpl(BDBCUR *cur); -static bool tcbdbcurrecimpl(BDBCUR *cur, const char **kbp, int *ksp, const char **vbp, int *vsp); - - -/* debugging function prototypes */ -void tcbdbprintmeta(TCBDB *bdb); -void tcbdbprintleaf(TCBDB *bdb, BDBLEAF *leaf); -void tcbdbprintnode(TCBDB *bdb, BDBNODE *node); - - - -/************************************************************************************************* - * API - *************************************************************************************************/ - - -/* Get the message string corresponding to an error code. */ -const char *tcbdberrmsg(int ecode){ - return tchdberrmsg(ecode); -} - - -/* Create a B+ tree database object. */ -TCBDB *tcbdbnew(void){ - TCBDB *bdb; - TCMALLOC(bdb, sizeof(*bdb)); - tcbdbclear(bdb); - bdb->hdb = tchdbnew(); - TCMALLOC(bdb->hist, sizeof(*bdb->hist) * BDBLEVELMAX); - return bdb; -} - - -/* Delete a B+ tree database object. */ -void tcbdbdel(TCBDB *bdb){ - assert(bdb); - if(bdb->open) tcbdbclose(bdb); - free(bdb->hist); - tchdbdel(bdb->hdb); - if(bdb->mmtx){ - pthread_mutex_destroy(bdb->tmtx); - pthread_mutex_destroy(bdb->cmtx); - pthread_rwlock_destroy(bdb->mmtx); - free(bdb->tmtx); - free(bdb->cmtx); - free(bdb->mmtx); - } - free(bdb); -} - - -/* Get the last happened error code of a B+ tree database object. */ -int tcbdbecode(TCBDB *bdb){ - assert(bdb); - return tchdbecode(bdb->hdb); -} - - -/* Set mutual exclusion control of a B+ tree database object for threading. */ -bool tcbdbsetmutex(TCBDB *bdb){ - assert(bdb); - if(!TCUSEPTHREAD) return true; - if(!tcglobalmutexlock()) return false; - if(bdb->mmtx || bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - tcglobalmutexunlock(); - return false; - } - TCMALLOC(bdb->mmtx, sizeof(pthread_rwlock_t)); - TCMALLOC(bdb->cmtx, sizeof(pthread_mutex_t)); - TCMALLOC(bdb->tmtx, sizeof(pthread_mutex_t)); - if(pthread_rwlock_init(bdb->mmtx, NULL) != 0 || pthread_mutex_init(bdb->cmtx, NULL) != 0 || - pthread_mutex_init(bdb->tmtx, NULL) != 0){ - free(bdb->tmtx); - free(bdb->cmtx); - free(bdb->mmtx); - bdb->tmtx = NULL; - bdb->cmtx = NULL; - bdb->mmtx = NULL; - tcglobalmutexunlock(); - return false; - } - tcglobalmutexunlock(); - return tchdbsetmutex(bdb->hdb); -} - - -/* Set the custom comparison function of a B+ tree database object. */ -bool tcbdbsetcmpfunc(TCBDB *bdb, BDBCMP cmp, void *cmpop){ - assert(bdb && cmp); - if(bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - bdb->cmp = cmp; - bdb->cmpop = cmpop; - return true; -} - - -/* Set the tuning parameters of a B+ tree database object. */ -bool tcbdbtune(TCBDB *bdb, int32_t lmemb, int32_t nmemb, - int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){ - assert(bdb); - if(bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - bdb->lmemb = (lmemb > 0) ? tclmax(lmemb, BDBMINLMEMB) : BDBDEFLMEMB; - bdb->nmemb = (nmemb > 0) ? tclmax(nmemb, BDBMINNMEMB) : BDBDEFNMEMB; - bdb->opts = opts; - uint8_t hopts = 0; - if(opts & BDBTLARGE) hopts |= HDBTLARGE; - if(opts & BDBTDEFLATE) hopts |= HDBTDEFLATE; - if(opts & BDBTTCBS) hopts |= HDBTTCBS; - bnum = (bnum > 0) ? bnum : BDBDEFBNUM; - apow = (apow >= 0) ? apow : BDBDEFAPOW; - fpow = (fpow >= 0) ? fpow : BDBDEFFPOW; - return tchdbtune(bdb->hdb, bnum, apow, fpow, hopts); -} - - -/* Set the caching parameters of a B+ tree database object. */ -bool tcbdbsetcache(TCBDB *bdb, int32_t lcnum, int32_t ncnum){ - assert(bdb); - if(bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - if(lcnum > 0) bdb->lcnum = tclmax(lcnum, BDBLEVELMAX); - if(ncnum > 0) bdb->ncnum = tclmax(ncnum, BDBLEVELMAX); - return true; -} - - -/* Open a database file and connect a B+ tree database object. */ -bool tcbdbopen(TCBDB *bdb, const char *path, int omode){ - assert(bdb && path); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbopenimpl(bdb, path, omode); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Close a B+ tree database object. */ -bool tcbdbclose(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcloseimpl(bdb); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Store a record into a B+ tree database object. */ -bool tcbdbput(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(bdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbputimpl(bdb, kbuf, ksiz, vbuf, vsiz, BDBPDOVER); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Store a string record into a B+ tree database object. */ -bool tcbdbput2(TCBDB *bdb, const char *kstr, const char *vstr){ - assert(bdb && kstr && vstr); - return tcbdbput(bdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Store a new record into a B+ tree database object. */ -bool tcbdbputkeep(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(bdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbputimpl(bdb, kbuf, ksiz, vbuf, vsiz, BDBPDKEEP); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Store a new string record into a B+ tree database object. */ -bool tcbdbputkeep2(TCBDB *bdb, const char *kstr, const char *vstr){ - assert(bdb && kstr && vstr); - return tcbdbputkeep(bdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Concatenate a value at the end of the existing record in a B+ tree database object. */ -bool tcbdbputcat(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(bdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbputimpl(bdb, kbuf, ksiz, vbuf, vsiz, BDBPDCAT); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Concatenate a string value at the end of the existing record in a B+ tree database object. */ -bool tcbdbputcat2(TCBDB *bdb, const char *kstr, const char *vstr){ - assert(bdb && kstr && vstr); - return tcbdbputcat(bdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Store a record into a B+ tree database object with allowing duplication of keys. */ -bool tcbdbputdup(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(bdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbputimpl(bdb, kbuf, ksiz, vbuf, vsiz, BDBPDDUP); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Store a string record into a B+ tree database object with allowing duplication of keys. */ -bool tcbdbputdup2(TCBDB *bdb, const char *kstr, const char *vstr){ - assert(bdb && kstr && vstr); - return tcbdbputdup(bdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Store records into a B+ tree database object with allowing duplication of keys. */ -bool tcbdbputdup3(TCBDB *bdb, const void *kbuf, int ksiz, const TCLIST *vals){ - assert(bdb && kbuf && ksiz >= 0 && vals); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool err = false; - int ln = TCLISTNUM(vals); - for(int i = 0; i < ln; i++){ - int vsiz; - const char *vbuf = tclistval(vals, i, &vsiz); - if(!tcbdbputimpl(bdb, kbuf, ksiz, vbuf, vsiz, BDBPDDUP)) err = true; - } - BDBUNLOCKMETHOD(bdb); - return !err; -} - - -/* Remove a record of a B+ tree database object. */ -bool tcbdbout(TCBDB *bdb, const void *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdboutimpl(bdb, kbuf, ksiz); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Remove a string record of a B+ tree database object. */ -bool tcbdbout2(TCBDB *bdb, const char *kstr){ - assert(bdb && kstr); - return tcbdbout(bdb, kstr, strlen(kstr)); -} - - -/* Remove records of a B+ tree database object. */ -bool tcbdbout3(TCBDB *bdb, const void *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdboutlist(bdb, kbuf, ksiz); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Retrieve a record in a B+ tree database object. */ -void *tcbdbget(TCBDB *bdb, const void *kbuf, int ksiz, int *sp){ - assert(bdb && kbuf && ksiz >= 0 && sp); - if(!BDBLOCKMETHOD(bdb, false)) return NULL; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return NULL; - } - const char *vbuf = tcbdbgetimpl(bdb, kbuf, ksiz, sp); - char *rv; - if(vbuf){ - TCMEMDUP(rv, vbuf, *sp); - } else { - rv = NULL; - } - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)){ - free(rv); - rv = NULL; - } - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Retrieve a string record in a B+ tree database object. */ -char *tcbdbget2(TCBDB *bdb, const char *kstr){ - assert(bdb && kstr); - int vsiz; - return tcbdbget(bdb, kstr, strlen(kstr), &vsiz); -} - - -/* Retrieve a record in a B+ tree database object and write the value into a buffer. */ -const void *tcbdbget3(TCBDB *bdb, const void *kbuf, int ksiz, int *sp){ - assert(bdb && kbuf && ksiz >= 0 && sp); - if(!BDBLOCKMETHOD(bdb, false)) return NULL; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return NULL; - } - const char *rv = tcbdbgetimpl(bdb, kbuf, ksiz, sp); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = NULL; - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Retrieve records in a B+ tree database object. */ -TCLIST *tcbdbget4(TCBDB *bdb, const void *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - if(!BDBLOCKMETHOD(bdb, false)) return NULL; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return NULL; - } - TCLIST *rv = tcbdbgetlist(bdb, kbuf, ksiz); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)){ - if(rv) tclistdel(rv); - rv = NULL; - } - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Get the number of records corresponding a key in a B+ tree database object. */ -int tcbdbvnum(TCBDB *bdb, const void *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - if(!BDBLOCKMETHOD(bdb, false)) return 0; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return 0; - } - int rv = tcbdbgetnum(bdb, kbuf, ksiz); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = 0; - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Get the number of records corresponding a string key in a B+ tree database object. */ -int tcbdbvnum2(TCBDB *bdb, const char *kstr){ - assert(bdb && kstr); - return tcbdbvnum(bdb, kstr, strlen(kstr)); -} - - -/* Get the size of the value of a record in a B+ tree database object. */ -int tcbdbvsiz(TCBDB *bdb, const void *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - int vsiz; - if(!tcbdbget3(bdb, kbuf, ksiz, &vsiz)) return -1; - return vsiz; -} - - -/* Get the size of the value of a string record in a B+ tree database object. */ -int tcbdbvsiz2(TCBDB *bdb, const char *kstr){ - assert(bdb && kstr); - return tcbdbvsiz(bdb, kstr, strlen(kstr)); -} - - -/* Get keys of ranged records in a B+ tree database object. */ -TCLIST *tcbdbrange(TCBDB *bdb, const void *bkbuf, int bksiz, bool binc, - const void *ekbuf, int eksiz, bool einc, int max){ - assert(bdb); - TCLIST *keys = tclistnew(); - if(!BDBLOCKMETHOD(bdb, false)) return keys; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return keys; - } - tcbdbrangeimpl(bdb, bkbuf, bksiz, binc, ekbuf, eksiz, einc, max, keys); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - tcbdbcacheadjust(bdb); - BDBUNLOCKMETHOD(bdb); - } - return keys; -} - - -/* Get string keys of ranged records in a B+ tree database object. */ -TCLIST *tcbdbrange2(TCBDB *bdb, const char *bkstr, bool binc, - const char *ekstr, bool einc, int max){ - return tcbdbrange(bdb, bkstr, bkstr ? strlen(bkstr) : 0, binc, - ekstr, ekstr ? strlen(ekstr) : 0, einc, max); -} - - -/* Get forward matching keys in a B+ tree database object. */ -TCLIST *tcbdbfwmkeys(TCBDB *bdb, const void *pbuf, int psiz, int max){ - assert(bdb && pbuf && psiz >= 0); - TCLIST *keys = tclistnew(); - if(!BDBLOCKMETHOD(bdb, false)) return keys; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return keys; - } - tcbdbrangefwm(bdb, pbuf, psiz, max, keys); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - tcbdbcacheadjust(bdb); - BDBUNLOCKMETHOD(bdb); - } - return keys; -} - - -/* Get forward matching string keys in a B+ tree database object. */ -TCLIST *tcbdbfwmkeys2(TCBDB *bdb, const char *pstr, int max){ - assert(bdb && pstr); - return tcbdbfwmkeys(bdb, pstr, strlen(pstr), max); -} - - - -/* Synchronize updated contents of a B+ tree database object with the file and the device. */ -bool tcbdbsync(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode || bdb->tran){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbmemsync(bdb, true); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Optimize the file of a B+ tree database object. */ -bool tcbdboptimize(TCBDB *bdb, int32_t lmemb, int32_t nmemb, - int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode || bdb->tran){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdboptimizeimpl(bdb, lmemb, nmemb, bnum, apow, fpow, opts); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Remove all records of a B+ tree database object. */ -bool tcbdbvanish(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode || bdb->tran){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbvanishimpl(bdb); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Copy the database file of a B+ tree database object. */ -bool tcbdbcopy(TCBDB *bdb, const char *path){ - assert(bdb && path); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - TCLIST *lids = tclistnew(); - TCLIST *nids = tclistnew(); - const char *vbuf; - int vsiz; - TCMAP *leafc = bdb->leafc; - tcmapiterinit(leafc); - while((vbuf = tcmapiternext(leafc, &vsiz)) != NULL){ - tclistpush(lids, vbuf, vsiz); - } - TCMAP *nodec = bdb->nodec; - tcmapiterinit(nodec); - while((vbuf = tcmapiternext(nodec, &vsiz)) != NULL){ - tclistpush(nids, vbuf, vsiz); - } - BDBUNLOCKMETHOD(bdb); - bool err = false; - int ln = TCLISTNUM(lids); - for(int i = 0; i < ln; i++){ - vbuf = TCLISTVALPTR(lids, i); - if(BDBLOCKMETHOD(bdb, true)){ - if(bdb->open){ - int rsiz; - BDBLEAF *leaf = (BDBLEAF *)tcmapget(bdb->leafc, vbuf, sizeof(leaf->id), &rsiz); - if(leaf && leaf->dirty && !tcbdbleafsave(bdb, leaf)) err = true; - } else { - err = true; - } - BDBUNLOCKMETHOD(bdb); - } else { - err = true; - } - } - ln = TCLISTNUM(nids); - for(int i = 0; i < ln; i++){ - vbuf = TCLISTVALPTR(nids, i); - if(BDBLOCKMETHOD(bdb, true)){ - if(bdb->open){ - int rsiz; - BDBNODE *node = (BDBNODE *)tcmapget(bdb->nodec, vbuf, sizeof(node->id), &rsiz); - if(node && node->dirty && !tcbdbnodesave(bdb, node)) err = true; - } else { - err = true; - } - BDBUNLOCKMETHOD(bdb); - } else { - err = true; - } - } - tclistdel(nids); - tclistdel(lids); - if(!tcbdbtranbegin(bdb)) err = true; - if(BDBLOCKMETHOD(bdb, false)){ - if(!tchdbcopy(bdb->hdb, path)) err = true; - BDBUNLOCKMETHOD(bdb); - } else { - err = true; - } - if(!tcbdbtrancommit(bdb)) err = true; - return !err; -} - - -/* Begin the transaction of a B+ tree database object. */ -bool tcbdbtranbegin(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode || bdb->tran){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(!tcbdbmemsync(bdb, false)){ - BDBUNLOCKMETHOD(bdb); - return false; - } - if(!BDBLOCKTRAN(bdb)){ - BDBUNLOCKMETHOD(bdb); - return false; - } - bdb->tran = true; - TCMEMDUP(bdb->rbopaque, bdb->opaque, BDBOPAQUESIZ); - BDBUNLOCKMETHOD(bdb); - return true; -} - - -/* Commit the transaction of a B+ tree database object. */ -bool tcbdbtrancommit(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode || !bdb->tran){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - free(bdb->rbopaque); - bdb->tran = false; - bdb->rbopaque = NULL; - bool err = false; - if(!tcbdbmemsync(bdb, false)) err = true; - BDBUNLOCKTRAN(bdb); - BDBUNLOCKMETHOD(bdb); - return !err; -} - - -/* Abort the transaction of a B+ tree database object. */ -bool tcbdbtranabort(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode || !bdb->tran){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - tcbdbcachepurge(bdb); - memcpy(bdb->opaque, bdb->rbopaque, BDBOPAQUESIZ); - tcloadmeta(bdb); - free(bdb->rbopaque); - bdb->tran = false; - bdb->rbopaque = NULL; - BDBUNLOCKTRAN(bdb); - BDBUNLOCKMETHOD(bdb); - return true; -} - - -/* Get the file path of a B+ tree database object. */ -const char *tcbdbpath(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, false)) return NULL; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return NULL; - } - const char *rv = tchdbpath(bdb->hdb); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Get the number of records of a B+ tree database object. */ -uint64_t tcbdbrnum(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, false)) return 0; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return 0; - } - uint64_t rv = bdb->rnum; - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Get the size of the database file of a B+ tree database object. */ -uint64_t tcbdbfsiz(TCBDB *bdb){ - assert(bdb); - if(!BDBLOCKMETHOD(bdb, false)) return 0; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return 0; - } - uint64_t rv = tchdbfsiz(bdb->hdb); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Create a cursor object. */ -BDBCUR *tcbdbcurnew(TCBDB *bdb){ - assert(bdb); - BDBCUR *cur; - TCMALLOC(cur, sizeof(*cur)); - cur->bdb = bdb; - cur->id = 0; - cur->kidx = 0; - cur->vidx = 0; - return cur; -} - - -/* Delete a cursor object. */ -void tcbdbcurdel(BDBCUR *cur){ - assert(cur); - free(cur); -} - - -/* Move a cursor object to the first record. */ -bool tcbdbcurfirst(BDBCUR *cur){ - assert(cur); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcurfirstimpl(cur); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = false; - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Move a cursor object to the last record. */ -bool tcbdbcurlast(BDBCUR *cur){ - assert(cur); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcurlastimpl(cur); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = false; - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Move a cursor object to the front of records corresponding a key. */ -bool tcbdbcurjump(BDBCUR *cur, const void *kbuf, int ksiz){ - assert(cur && kbuf && ksiz >= 0); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcurjumpimpl(cur, kbuf, ksiz, true); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = false; - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Move a cursor object to the front of records corresponding a key string. */ -bool tcbdbcurjump2(BDBCUR *cur, const char *kstr){ - assert(cur && kstr); - return tcbdbcurjump(cur, kstr, strlen(kstr)); -} - - -/* Move a cursor object to the previous record. */ -bool tcbdbcurprev(BDBCUR *cur){ - assert(cur); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcurprevimpl(cur); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = false; - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Move a cursor object to the next record. */ -bool tcbdbcurnext(BDBCUR *cur){ - assert(cur); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcurnextimpl(cur); - bool adj = TCMAPRNUM(bdb->leafc) > bdb->lcnum || TCMAPRNUM(bdb->nodec) > bdb->ncnum; - BDBUNLOCKMETHOD(bdb); - if(adj && BDBLOCKMETHOD(bdb, true)){ - if(!bdb->tran && !tcbdbcacheadjust(bdb)) rv = false; - BDBUNLOCKMETHOD(bdb); - } - return rv; -} - - -/* Insert a record around a cursor object. */ -bool tcbdbcurput(BDBCUR *cur, const void *vbuf, int vsiz, int cpmode){ - assert(cur && vbuf && vsiz >= 0); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcurputimpl(cur, vbuf, vsiz, cpmode); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Insert a string record around a cursor object. */ -bool tcbdbcurput2(BDBCUR *cur, const char *vstr, int cpmode){ - assert(cur && vstr); - return tcbdbcurput(cur, vstr, strlen(vstr), cpmode); -} - - -/* Delete the record where a cursor object is. */ -bool tcbdbcurout(BDBCUR *cur){ - assert(cur); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcuroutimpl(cur); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Get the key of the record where the cursor object is. */ -char *tcbdbcurkey(BDBCUR *cur, int *sp){ - assert(cur && sp); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - const char *kbuf, *vbuf; - int ksiz, vsiz; - char *rv; - if(tcbdbcurrecimpl(cur, &kbuf, &ksiz, &vbuf, &vsiz)){ - TCMEMDUP(rv, kbuf, ksiz); - *sp = ksiz; - } else { - rv = NULL; - } - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Get the key string of the record where the cursor object is. */ -char *tcbdbcurkey2(BDBCUR *cur){ - assert(cur); - int ksiz; - return tcbdbcurkey(cur, &ksiz); -} - - -/* Get the key of the record where the cursor object is, as a volatile buffer. */ -const char *tcbdbcurkey3(BDBCUR *cur, int *sp){ - assert(cur && sp); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - const char *kbuf, *vbuf; - int ksiz, vsiz; - const char *rv; - if(tcbdbcurrecimpl(cur, &kbuf, &ksiz, &vbuf, &vsiz)){ - rv = kbuf; - *sp = ksiz; - } else { - rv = NULL; - } - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Get the value of the record where the cursor object is. */ -char *tcbdbcurval(BDBCUR *cur, int *sp){ - assert(cur && sp); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - const char *kbuf, *vbuf; - int ksiz, vsiz; - char *rv; - if(tcbdbcurrecimpl(cur, &kbuf, &ksiz, &vbuf, &vsiz)){ - TCMEMDUP(rv, vbuf, vsiz); - *sp = vsiz; - } else { - rv = NULL; - } - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Get the value string of the record where the cursor object is. */ -char *tcbdbcurval2(BDBCUR *cur){ - assert(cur); - int vsiz; - return tcbdbcurval(cur, &vsiz); -} - - -/* Get the value of the record where the cursor object is, as a volatile buffer. */ -const char *tcbdbcurval3(BDBCUR *cur, int *sp){ - assert(cur && sp); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - const char *kbuf, *vbuf; - int ksiz, vsiz; - const char *rv; - if(tcbdbcurrecimpl(cur, &kbuf, &ksiz, &vbuf, &vsiz)){ - rv = vbuf; - *sp = vsiz; - } else { - rv = NULL; - } - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Get the key and the value of the record where the cursor object is. */ -bool tcbdbcurrec(BDBCUR *cur, TCXSTR *kxstr, TCXSTR *vxstr){ - assert(cur && kxstr && vxstr); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - const char *kbuf, *vbuf; - int ksiz, vsiz; - bool rv; - if(tcbdbcurrecimpl(cur, &kbuf, &ksiz, &vbuf, &vsiz)){ - tcxstrclear(kxstr); - TCXSTRCAT(kxstr, kbuf, ksiz); - tcxstrclear(vxstr); - TCXSTRCAT(vxstr, vbuf, vsiz); - rv = true; - } else { - rv = false; - } - BDBUNLOCKMETHOD(bdb); - return rv; -} - - - -/************************************************************************************************* - * features for experts - *************************************************************************************************/ - - -/* Set the error code of a B+ tree database object. */ -void tcbdbsetecode(TCBDB *bdb, int ecode, const char *filename, int line, const char *func){ - assert(bdb && filename && line >= 1 && func); - tchdbsetecode(bdb->hdb, ecode, filename, line, func); -} - - -/* Set the file descriptor for debugging output. */ -void tcbdbsetdbgfd(TCBDB *bdb, int fd){ - assert(bdb && fd >= 0); - tchdbsetdbgfd(bdb->hdb, fd); -} - - -/* Get the file descriptor for debugging output. */ -int tcbdbdbgfd(TCBDB *bdb){ - assert(bdb); - return tchdbdbgfd(bdb->hdb); -} - - -/* Synchronize updating contents on memory. */ -bool tcbdbmemsync(TCBDB *bdb, bool phys){ - assert(bdb); - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - bool err = false; - bool clk = BDBLOCKCACHE(bdb); - const char *vbuf; - int vsiz; - TCMAP *leafc = bdb->leafc; - tcmapiterinit(leafc); - while((vbuf = tcmapiternext(leafc, &vsiz)) != NULL){ - int rsiz; - BDBLEAF *leaf = (BDBLEAF *)tcmapiterval(vbuf, &rsiz); - if(leaf->dirty && !tcbdbleafsave(bdb, leaf)) err = true; - } - TCMAP *nodec = bdb->nodec; - tcmapiterinit(nodec); - while((vbuf = tcmapiternext(nodec, &vsiz)) != NULL){ - int rsiz; - BDBNODE *node = (BDBNODE *)tcmapiterval(vbuf, &rsiz); - if(node->dirty && !tcbdbnodesave(bdb, node)) err = true; - } - if(clk) BDBUNLOCKCACHE(bdb); - tcdumpmeta(bdb); - if(!tchdbmemsync(bdb->hdb, phys)) err = true; - return !err; -} - - -/* Get the comparison function of a B+ tree database object. */ -BDBCMP tcbdbcmpfunc(TCBDB *bdb){ - assert(bdb); - return bdb->cmp; -} - - -/* Get the opaque object for the comparison function of a B+ tree database object. */ -void *tcbdbcmpop(TCBDB *bdb){ - assert(bdb); - return bdb->cmpop; -} - - -/* Get the maximum number of cached leaf nodes of a B+ tree database object. */ -uint32_t tcbdblmemb(TCBDB *bdb){ - assert(bdb); - return bdb->lmemb; -} - - -/* Get the maximum number of cached non-leaf nodes of a B+ tree database object. */ -uint32_t tcbdbnmemb(TCBDB *bdb){ - assert(bdb); - return bdb->nmemb; -} - - -/* Get the number of the leaf nodes of B+ tree database object. */ -uint64_t tcbdblnum(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return bdb->lnum; -} - - -/* Get the number of the non-leaf nodes of B+ tree database object. */ -uint64_t tcbdbnnum(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return bdb->nnum; -} - - -/* Get the number of elements of the bucket array of a B+ tree database object. */ -uint64_t tcbdbbnum(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return tchdbbnum(bdb->hdb); -} - - -/* Get the record alignment of a B+ tree database object. */ -uint32_t tcbdbalign(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return tchdbalign(bdb->hdb); -} - - -/* Get the maximum number of the free block pool of a B+ tree database object. */ -uint32_t tcbdbfbpmax(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return tchdbfbpmax(bdb->hdb); -} - - -/* Get the inode number of the database file of a B+ tree database object. */ -uint64_t tcbdbinode(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return tchdbinode(bdb->hdb); -} - - -/* Get the modification time of the database file of a B+ tree database object. */ -time_t tcbdbmtime(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return tchdbmtime(bdb->hdb); -} - - -/* Get the additional flags of a B+ tree database object. */ -uint8_t tcbdbflags(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return tchdbflags(bdb->hdb); -} - - -/* Get the options of a B+ tree database object. */ -uint8_t tcbdbopts(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return bdb->opts; -} - - -/* Get the pointer to the opaque field of a B+ tree database object. */ -char *tcbdbopaque(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return tchdbopaque(bdb->hdb) + BDBOPAQUESIZ; -} - - -/* Get the number of used elements of the bucket array of a B+ tree database object. */ -uint64_t tcbdbbnumused(TCBDB *bdb){ - assert(bdb); - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return tchdbbnumused(bdb->hdb); -} - - -/* Set the maximum size of each leaf node. */ -bool tcbdbsetlsmax(TCBDB *bdb, uint32_t lsmax){ - assert(bdb); - if(bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - bdb->lsmax = lsmax; - return true; -} - - -/* Set the capacity number of records. */ -bool tcbdbsetcapnum(TCBDB *bdb, uint64_t capnum){ - assert(bdb); - if(bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - bdb->capnum = capnum; - return true; -} - - -/* Store a new record into a B+ tree database object with backward duplication. */ -bool tcbdbputdupback(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(bdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!BDBLOCKMETHOD(bdb, true)) return false; - if(!bdb->open || !bdb->wmode){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbputimpl(bdb, kbuf, ksiz, vbuf, vsiz, BDBPDDUPB); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Store a new string record into a B+ tree database object with backward duplication. */ -bool tcbdbputdupback2(TCBDB *bdb, const char *kstr, const char *vstr){ - assert(bdb && kstr && vstr); - return tcbdbputdupback(bdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Move a cursor object to the rear of records corresponding a key. */ -bool tcbdbcurjumpback(BDBCUR *cur, const void *kbuf, int ksiz){ - assert(cur && kbuf && ksiz >= 0); - TCBDB *bdb = cur->bdb; - if(!BDBLOCKMETHOD(bdb, false)) return false; - if(!bdb->open){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - BDBUNLOCKMETHOD(bdb); - return false; - } - bool rv = tcbdbcurjumpimpl(cur, kbuf, ksiz, false); - BDBUNLOCKMETHOD(bdb); - return rv; -} - - -/* Move a cursor object to the rear of records corresponding a key string. */ -bool tcbdbcurjumpback2(BDBCUR *cur, const char *kstr){ - assert(cur && kstr); - return tcbdbcurjumpback(cur, kstr, strlen(kstr)); -} - - -/* Compare keys of two records by lexical order. */ -int tcbdbcmplexical(const char *aptr, int asiz, const char *bptr, int bsiz, void *op){ - assert(aptr && asiz >= 0 && bptr && bsiz >= 0); - int rv; - TCCMPLEXICAL(rv, aptr, asiz, bptr, bsiz); - return rv; -} - - -/* Compare two keys as decimal strings of real numbers. */ -int tcbdbcmpdecimal(const char *aptr, int asiz, const char *bptr, int bsiz, void *op){ - assert(aptr && asiz >= 0 && bptr && bsiz >= 0); - int sign; - int64_t anum = 0; - sign = 1; - if(asiz > 0 && *aptr == '-'){ - aptr++; - asiz--; - sign = -1; - } - for(int i = 0; i < asiz; i++){ - int c = aptr[i]; - if(c < '0' || c > '9') continue; - anum = anum * 10 + c - '0'; - } - anum *= sign; - int64_t bnum = 0; - sign = 1; - if(bsiz > 0 && *bptr == '-'){ - bptr++; - bsiz--; - sign = -1; - } - for(int i = 0; i < bsiz; i++){ - int c = bptr[i]; - if(c < '0' || c > '9') continue; - bnum = bnum * 10 + c - '0'; - } - bnum *= sign; - return (anum < bnum) ? -1 : anum > bnum; -} - - -/* Compare two keys as 32-bit integers in the native byte order. */ -int tcbdbcmpint32(const char *aptr, int asiz, const char *bptr, int bsiz, void *op){ - assert(aptr && bptr); - int32_t anum, bnum; - if(asiz == sizeof(int32_t)){ - memcpy(&anum, aptr, sizeof(int32_t)); - } else if(asiz < sizeof(int32_t)){ - memset(&anum, 0, sizeof(int32_t)); - memcpy(&anum, aptr, asiz); - } else { - memcpy(&anum, aptr, sizeof(int32_t)); - } - if(bsiz == sizeof(int32_t)){ - memcpy(&bnum, bptr, sizeof(int32_t)); - } else if(bsiz < sizeof(int32_t)){ - memset(&bnum, 0, sizeof(int32_t)); - memcpy(&bnum, bptr, bsiz); - } else { - memcpy(&bnum, bptr, sizeof(int32_t)); - } - return (anum < bnum) ? -1 : anum > bnum; -} - - -/* Compare two keys as 64-bit integers in the native byte order. */ -int tcbdbcmpint64(const char *aptr, int asiz, const char *bptr, int bsiz, void *op){ - assert(aptr && bptr); - int64_t anum, bnum; - if(asiz == sizeof(int64_t)){ - memcpy(&anum, aptr, sizeof(int64_t)); - } else if(asiz < sizeof(int64_t)){ - memset(&anum, 0, sizeof(int64_t)); - memcpy(&anum, aptr, asiz); - } else { - memcpy(&anum, aptr, sizeof(int64_t)); - } - if(bsiz == sizeof(int64_t)){ - memcpy(&bnum, bptr, sizeof(int64_t)); - } else if(bsiz < sizeof(int64_t)){ - memset(&bnum, 0, sizeof(int64_t)); - memcpy(&bnum, bptr, bsiz); - } else { - memcpy(&bnum, bptr, sizeof(int64_t)); - } - return (anum < bnum) ? -1 : anum > bnum; -} - - - -/************************************************************************************************* - * private features - *************************************************************************************************/ - - -/* Clear all members. - `bdb' specifies the B+ tree database object. */ -static void tcbdbclear(TCBDB *bdb){ - assert(bdb); - bdb->mmtx = NULL; - bdb->cmtx = NULL; - bdb->tmtx = NULL; - bdb->hdb = NULL; - bdb->opaque = NULL; - bdb->open = false; - bdb->wmode = false; - bdb->lmemb = BDBDEFLMEMB; - bdb->nmemb = BDBDEFNMEMB; - bdb->opts = 0; - bdb->root = 0; - bdb->first = 0; - bdb->last = 0; - bdb->lnum = 0; - bdb->nnum = 0; - bdb->rnum = 0; - bdb->leafc = NULL; - bdb->nodec = NULL; - bdb->cmp = NULL; - bdb->cmpop = NULL; - bdb->lcnum = BDBDEFLCNUM; - bdb->ncnum = BDBDEFNCNUM; - bdb->lsmax = 0; - bdb->lschk = 0; - bdb->capnum = 0; - bdb->hist = NULL; - bdb->hnum = 0; - bdb->hleaf = 0; - bdb->lleaf = 0; - bdb->tran = false; - bdb->rbopaque = NULL; - bdb->cnt_saveleaf = -1; - bdb->cnt_loadleaf = -1; - bdb->cnt_killleaf = -1; - bdb->cnt_adjleafc = -1; - bdb->cnt_savenode = -1; - bdb->cnt_loadnode = -1; - bdb->cnt_adjnodec = -1; - TCDODEBUG(bdb->cnt_saveleaf = 0); - TCDODEBUG(bdb->cnt_loadleaf = 0); - TCDODEBUG(bdb->cnt_killleaf = 0); - TCDODEBUG(bdb->cnt_adjleafc = 0); - TCDODEBUG(bdb->cnt_savenode = 0); - TCDODEBUG(bdb->cnt_loadnode = 0); - TCDODEBUG(bdb->cnt_adjnodec = 0); -} - - -/* Serialize meta data into the opaque field. - `bdb' specifies the B+ tree database object. */ -static void tcdumpmeta(TCBDB *bdb){ - assert(bdb); - memset(bdb->opaque, 0, 64); - char *wp = bdb->opaque; - if(bdb->cmp == tcbdbcmplexical){ - *(uint8_t *)(wp++) = 0x0; - } else if(bdb->cmp == tcbdbcmpdecimal){ - *(uint8_t *)(wp++) = 0x1; - } else if(bdb->cmp == tcbdbcmpint32){ - *(uint8_t *)(wp++) = 0x2; - } else if(bdb->cmp == tcbdbcmpint64){ - *(uint8_t *)(wp++) = 0x3; - } else { - *(uint8_t *)(wp++) = 0xff; - } - wp += 7; - uint32_t lnum; - lnum = bdb->lmemb; - lnum = TCHTOIL(lnum); - memcpy(wp, &lnum, sizeof(lnum)); - wp += sizeof(lnum); - lnum = bdb->nmemb; - lnum = TCHTOIL(lnum); - memcpy(wp, &lnum, sizeof(lnum)); - wp += sizeof(lnum); - uint64_t llnum; - llnum = bdb->root; - llnum = TCHTOILL(llnum); - memcpy(wp, &llnum, sizeof(llnum)); - wp += sizeof(llnum); - llnum = bdb->first; - llnum = TCHTOILL(llnum); - memcpy(wp, &llnum, sizeof(llnum)); - wp += sizeof(llnum); - llnum = bdb->last; - llnum = TCHTOILL(llnum); - memcpy(wp, &llnum, sizeof(llnum)); - wp += sizeof(llnum); - llnum = bdb->lnum; - llnum = TCHTOILL(llnum); - memcpy(wp, &llnum, sizeof(llnum)); - wp += sizeof(llnum); - llnum = bdb->nnum; - llnum = TCHTOILL(llnum); - memcpy(wp, &llnum, sizeof(llnum)); - wp += sizeof(llnum); - llnum = bdb->rnum; - llnum = TCHTOILL(llnum); - memcpy(wp, &llnum, sizeof(llnum)); - wp += sizeof(llnum); -} - - -/* Deserialize meta data from the opaque field. - `bdb' specifies the B+ tree database object. */ -static void tcloadmeta(TCBDB *bdb){ - const char *rp = bdb->opaque; - uint8_t cnum = *(uint8_t *)(rp++); - if(cnum == 0x0){ - bdb->cmp = tcbdbcmplexical; - } else if(cnum == 0x1){ - bdb->cmp = tcbdbcmpdecimal; - } else if(cnum == 0x2){ - bdb->cmp = tcbdbcmpint32; - } else if(cnum == 0x3){ - bdb->cmp = tcbdbcmpint64; - } - rp += 7; - uint32_t lnum; - memcpy(&lnum, rp, sizeof(lnum)); - rp += sizeof(lnum); - bdb->lmemb = TCITOHL(lnum); - memcpy(&lnum, rp, sizeof(lnum)); - rp += sizeof(lnum); - bdb->nmemb = TCITOHL(lnum); - uint64_t llnum; - memcpy(&llnum, rp, sizeof(llnum)); - bdb->root = TCITOHLL(llnum); - rp += sizeof(llnum); - memcpy(&llnum, rp, sizeof(llnum)); - bdb->first = TCITOHLL(llnum); - rp += sizeof(llnum); - memcpy(&llnum, rp, sizeof(llnum)); - bdb->last = TCITOHLL(llnum); - rp += sizeof(llnum); - memcpy(&llnum, rp, sizeof(llnum)); - bdb->lnum = TCITOHLL(llnum); - rp += sizeof(llnum); - memcpy(&llnum, rp, sizeof(llnum)); - bdb->nnum = TCITOHLL(llnum); - rp += sizeof(llnum); - memcpy(&llnum, rp, sizeof(llnum)); - bdb->rnum = TCITOHLL(llnum); - rp += sizeof(llnum); -} - - -/* Create a new leaf. - `bdb' specifies the B+ tree database object. - `prev' specifies the ID number of the previous leaf. - `next' specifies the ID number of the next leaf. - The return value is the new leaf object. */ -static BDBLEAF *tcbdbleafnew(TCBDB *bdb, uint64_t prev, uint64_t next){ - assert(bdb); - BDBLEAF lent; - lent.id = ++bdb->lnum; - lent.recs = tclistnew2(bdb->lmemb + 1); - lent.prev = prev; - lent.next = next; - lent.dirty = true; - lent.dead = false; - tcmapputkeep(bdb->leafc, &(lent.id), sizeof(lent.id), &lent, sizeof(lent)); - int rsiz; - return (BDBLEAF *)tcmapget(bdb->leafc, &(lent.id), sizeof(lent.id), &rsiz); -} - - -/* Remove a leaf from the cache. - `bdb' specifies the B+ tree database object. - `leaf' specifies the leaf object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbleafcacheout(TCBDB *bdb, BDBLEAF *leaf){ - assert(bdb && leaf); - bool err = false; - if(leaf->dirty && !tcbdbleafsave(bdb, leaf)) err = true; - TCLIST *recs = leaf->recs; - int ln = TCLISTNUM(recs); - for(int i = 0; i < ln; i++){ - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, i); - free(recp->kbuf); - free(recp->vbuf); - if(recp->rest) tclistdel(recp->rest); - } - tclistdel(recs); - tcmapout(bdb->leafc, &(leaf->id), sizeof(leaf->id)); - return !err; -} - - -/* Save a leaf into the internal database. - `bdb' specifies the B+ tree database object. - `leaf' specifies the leaf object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbleafsave(TCBDB *bdb, BDBLEAF *leaf){ - assert(bdb && leaf); - TCDODEBUG(bdb->cnt_saveleaf++); - TCXSTR *rbuf = tcxstrnew3(BDBPAGEBUFSIZ); - char hbuf[(sizeof(uint64_t)+1)*3]; - char *wp = hbuf; - uint64_t llnum; - int step; - llnum = leaf->prev; - TCSETVNUMBUF64(step, wp, llnum); - wp += step; - llnum = leaf->next; - TCSETVNUMBUF64(step, wp, llnum); - wp += step; - TCXSTRCAT(rbuf, hbuf, wp - hbuf); - TCLIST *recs = leaf->recs; - int ln = TCLISTNUM(recs); - for(int i = 0; i < ln; i++){ - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, i); - int lnum; - wp = hbuf; - lnum = recp->ksiz; - TCSETVNUMBUF(step, wp, lnum); - wp += step; - lnum = recp->vsiz; - TCSETVNUMBUF(step, wp, lnum); - wp += step; - TCLIST *rest = recp->rest; - int rnum = rest ? TCLISTNUM(rest) : 0; - TCSETVNUMBUF(step, wp, rnum); - wp += step; - TCXSTRCAT(rbuf, hbuf, wp - hbuf); - TCXSTRCAT(rbuf, recp->kbuf, recp->ksiz); - TCXSTRCAT(rbuf, recp->vbuf, recp->vsiz); - for(int j = 0; j < rnum; j++){ - int vsiz; - const char *vbuf = tclistval(rest, j, &vsiz); - TCSETVNUMBUF(step, hbuf, vsiz); - TCXSTRCAT(rbuf, hbuf, step); - TCXSTRCAT(rbuf, vbuf, vsiz); - } - } - bool err = false; - step = sprintf(hbuf, "%llx", (unsigned long long)leaf->id); - if(ln < 1 && !tchdbout(bdb->hdb, hbuf, step) && tchdbecode(bdb->hdb) != TCENOREC) - err = true; - if(!leaf->dead && !tchdbput(bdb->hdb, hbuf, step, TCXSTRPTR(rbuf), TCXSTRSIZE(rbuf))) - err = true; - tcxstrdel(rbuf); - leaf->dirty = false; - return !err; -} - - -/* Load a leaf from the internal database. - `bdb' specifies the B+ tree database object. - `id' specifies the ID number of the leaf. - The return value is the leaf object or `NULL' on failure. */ -static BDBLEAF *tcbdbleafload(TCBDB *bdb, uint64_t id){ - assert(bdb && id > 0); - bool clk = BDBLOCKCACHE(bdb); - int rsiz; - BDBLEAF *leaf = (BDBLEAF *)tcmapget3(bdb->leafc, &id, sizeof(id), &rsiz); - if(leaf){ - if(clk) BDBUNLOCKCACHE(bdb); - return leaf; - } - if(clk) BDBUNLOCKCACHE(bdb); - TCDODEBUG(bdb->cnt_loadleaf++); - char hbuf[(sizeof(uint64_t)+1)*3]; - int step; - step = sprintf(hbuf, "%llx", (unsigned long long)id); - char *rbuf = NULL; - char wbuf[BDBPAGEBUFSIZ]; - const char *rp = NULL; - rsiz = tchdbget3(bdb->hdb, hbuf, step, wbuf, BDBPAGEBUFSIZ); - if(rsiz < 1){ - tcbdbsetecode(bdb, TCEMISC, __FILE__, __LINE__, __func__); - return false; - } else if(rsiz < BDBPAGEBUFSIZ){ - rp = wbuf; - } else { - if(!(rbuf = tchdbget(bdb->hdb, hbuf, step, &rsiz))){ - tcbdbsetecode(bdb, TCEMISC, __FILE__, __LINE__, __func__); - return false; - } - rp = rbuf; - } - BDBLEAF lent; - lent.id = id; - uint64_t llnum; - TCREADVNUMBUF64(rp, llnum, step); - lent.prev = llnum; - rp += step; - rsiz -= step; - TCREADVNUMBUF64(rp, llnum, step); - lent.next = llnum; - rp += step; - rsiz -= step; - lent.dirty = false; - lent.dead = false; - lent.recs = tclistnew2(bdb->lmemb + 1); - bool err = false; - while(rsiz >= 3){ - BDBREC rec; - TCREADVNUMBUF(rp, rec.ksiz, step); - rp += step; - rsiz -= step; - TCREADVNUMBUF(rp, rec.vsiz, step); - rp += step; - rsiz -= step; - int rnum; - TCREADVNUMBUF(rp, rnum, step); - rp += step; - rsiz -= step; - if(rsiz < rec.ksiz + rec.vsiz + rnum){ - err = true; - break; - } - TCMEMDUP(rec.kbuf, rp, rec.ksiz); - rp += rec.ksiz; - rsiz -= rec.ksiz; - TCMEMDUP(rec.vbuf, rp, rec.vsiz); - rp += rec.vsiz; - rsiz -= rec.vsiz; - if(rnum > 0){ - rec.rest = tclistnew2(rnum); - while(rnum-- > 0 && rsiz > 0){ - int vsiz; - TCREADVNUMBUF(rp, vsiz, step); - rp += step; - rsiz -= step; - if(rsiz < vsiz){ - err = true; - break; - } - TCLISTPUSH(rec.rest, rp, vsiz); - rp += vsiz; - rsiz -= vsiz; - } - } else { - rec.rest = NULL; - } - TCLISTPUSH(lent.recs, &rec, sizeof(rec)); - } - free(rbuf); - if(err || rsiz != 0){ - tcbdbsetecode(bdb, TCEMISC, __FILE__, __LINE__, __func__); - return NULL; - } - clk = BDBLOCKCACHE(bdb); - tcmapputkeep(bdb->leafc, &(lent.id), sizeof(lent.id), &lent, sizeof(lent)); - leaf = (BDBLEAF *)tcmapget(bdb->leafc, &(lent.id), sizeof(lent.id), &rsiz); - if(clk) BDBUNLOCKCACHE(bdb); - return leaf; -} - - -/* Load the historical leaf from the internal database. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is the pointer to the leaf, else, it is `NULL'. */ -static BDBLEAF *tcbdbgethistleaf(TCBDB *bdb, const char *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - BDBLEAF *leaf = tcbdbleafload(bdb, bdb->hleaf); - if(!leaf) return NULL; - int ln = TCLISTNUM(leaf->recs); - if(ln < 2) return NULL; - BDBREC *recp = (BDBREC *)TCLISTVALPTR(leaf->recs, 0); - int rv; - if(bdb->cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, recp->kbuf, recp->ksiz); - } else { - rv = bdb->cmp(kbuf, ksiz, recp->kbuf, recp->ksiz, bdb->cmpop); - } - if(rv == 0) return leaf; - if(rv < 0) return NULL; - recp = (BDBREC *)TCLISTVALPTR(leaf->recs, ln - 1); - if(bdb->cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, recp->kbuf, recp->ksiz); - } else { - rv = bdb->cmp(kbuf, ksiz, recp->kbuf, recp->ksiz, bdb->cmpop); - } - if(rv <= 0 || leaf->next < 1) return leaf; - return NULL; -} - - -/* Add a record to a leaf. - `bdb' specifies the B+ tree database object. - `leaf' specifies the leaf object. - `dmode' specifies behavior when the key overlaps. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. */ -static bool tcbdbleafaddrec(TCBDB *bdb, BDBLEAF *leaf, int dmode, - const char *kbuf, int ksiz, const char *vbuf, int vsiz){ - assert(bdb && leaf && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - BDBCMP cmp = bdb->cmp; - void *cmpop = bdb->cmpop; - TCLIST *recs = leaf->recs; - int ln = TCLISTNUM(recs); - int left = 0; - int right = ln; - int i = (left + right) / 2; - while(right >= left && i < ln){ - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, i); - int rv; - if(cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, recp->kbuf, recp->ksiz); - } else { - rv = cmp(kbuf, ksiz, recp->kbuf, recp->ksiz, cmpop); - } - if(rv == 0){ - break; - } else if(rv <= 0){ - right = i - 1; - } else { - left = i + 1; - } - i = (left + right) / 2; - } - while(i < ln){ - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, i); - int rv; - if(cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, recp->kbuf, recp->ksiz); - } else { - rv = cmp(kbuf, ksiz, recp->kbuf, recp->ksiz, cmpop); - } - if(rv == 0){ - switch(dmode){ - case BDBPDKEEP: - return false; - case BDBPDCAT: - TCREALLOC(recp->vbuf, recp->vbuf, recp->vsiz + vsiz + 1); - memcpy(recp->vbuf + recp->vsiz, vbuf, vsiz); - recp->vsiz += vsiz; - recp->vbuf[recp->vsiz] = '\0'; - break; - case BDBPDDUP: - if(!recp->rest) recp->rest = tclistnew(); - TCLISTPUSH(recp->rest, vbuf, vsiz); - bdb->rnum++; - break; - case BDBPDDUPB: - if(!recp->rest) recp->rest = tclistnew(); - tclistunshift(recp->rest, recp->vbuf, recp->vsiz); - if(vsiz > recp->vsiz) TCREALLOC(recp->vbuf, recp->vbuf, vsiz + 1); - memcpy(recp->vbuf, vbuf, vsiz); - recp->vbuf[vsiz] = '\0'; - recp->vsiz = vsiz; - bdb->rnum++; - break; - default: - if(vsiz > recp->vsiz) TCREALLOC(recp->vbuf, recp->vbuf, vsiz + 1); - memcpy(recp->vbuf, vbuf, vsiz); - recp->vbuf[vsiz] = '\0'; - recp->vsiz = vsiz; - break; - } - break; - } else if(rv < 0){ - BDBREC rec; - TCMEMDUP(rec.kbuf, kbuf, ksiz); - rec.ksiz = ksiz; - TCMEMDUP(rec.vbuf, vbuf, vsiz); - rec.vsiz = vsiz; - rec.rest = NULL; - tclistinsert(recs, i, &rec, sizeof(rec)); - bdb->rnum++; - break; - } - i++; - } - if(i >= ln){ - BDBREC rec; - TCMEMDUP(rec.kbuf, kbuf, ksiz); - rec.ksiz = ksiz; - TCMEMDUP(rec.vbuf, vbuf, vsiz); - rec.vsiz = vsiz; - rec.rest = NULL; - TCLISTPUSH(recs, &rec, sizeof(rec)); - bdb->rnum++; - } - leaf->dirty = true; - return true; -} - - -/* Calculate the size of data of a leaf object. - `bdb' specifies the B+ tree database object. - `leaf' specifies the leaf object. - The return value is size of data of the leaf. */ -static int tcbdbleafdatasize(BDBLEAF *leaf){ - assert(leaf); - int sum = 0; - TCLIST *recs = leaf->recs; - int ln = TCLISTNUM(recs); - for(int i = 0; i < ln; i++){ - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, i); - sum += recp->ksiz + recp->vsiz; - if(recp->rest){ - TCLIST *rest = recp->rest; - int rnum = TCLISTNUM(rest); - for(int j = 0; j < rnum; j++){ - int vsiz; - tclistval(rest, j, &vsiz); - sum += vsiz; - } - } - } - return sum; -} - - -/* Divide a leaf into two. - `bdb' specifies the B+ tree database object. - `leaf' specifies the leaf object. - The return value is the new leaf object or `NULL' on failure. */ -static BDBLEAF *tcbdbleafdivide(TCBDB *bdb, BDBLEAF *leaf){ - assert(bdb && leaf); - bdb->hleaf = 0; - TCLIST *recs = leaf->recs; - int mid = TCLISTNUM(recs) / 2; - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, mid); - BDBLEAF *newleaf = tcbdbleafnew(bdb, leaf->id, leaf->next); - if(newleaf->next > 0){ - BDBLEAF *nextleaf = tcbdbleafload(bdb, newleaf->next); - if(!nextleaf) return NULL; - nextleaf->prev = newleaf->id; - nextleaf->dirty = true; - } - leaf->next = newleaf->id; - leaf->dirty = true; - int ln = TCLISTNUM(recs); - TCLIST *newrecs = newleaf->recs; - for(int i = mid; i < ln; i++){ - recp = (BDBREC *)TCLISTVALPTR(recs, i); - TCLISTPUSH(newrecs, recp, sizeof(*recp)); - } - ln = TCLISTNUM(newrecs); - for(int i = 0; i < ln; i++){ - int rsiz; - free(tclistpop(recs, &rsiz)); - } - return newleaf; -} - - -/* Cut off the path to a leaf and mark it dead. - `bdb' specifies the B+ tree database object. - `leaf' specifies the leaf object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbleafkill(TCBDB *bdb, BDBLEAF *leaf){ - assert(bdb && leaf); - BDBNODE *node = tcbdbnodeload(bdb, bdb->hist[bdb->hnum-1]); - if(!node) return false; - if(tcbdbnodesubidx(bdb, node, leaf->id)){ - TCDODEBUG(bdb->cnt_killleaf++); - if(bdb->hleaf == leaf->id) bdb->hleaf = 0; - if(leaf->prev > 0){ - BDBLEAF *tleaf = tcbdbleafload(bdb, leaf->prev); - if(!tleaf) return false; - tleaf->next = leaf->next; - tleaf->dirty = true; - if(bdb->last == leaf->id) bdb->last = leaf->prev; - } - if(leaf->next > 0){ - BDBLEAF *tleaf = tcbdbleafload(bdb, leaf->next); - if(!tleaf) return false; - tleaf->prev = leaf->prev; - tleaf->dirty = true; - if(bdb->first == leaf->id) bdb->first = leaf->next; - } - leaf->dead = true; - } - return true; -} - - -/* Create a new node. - `bdb' specifies the B+ tree database object. - `heir' specifies the ID of the child before the first index. - The return value is the new node object. */ -static BDBNODE *tcbdbnodenew(TCBDB *bdb, uint64_t heir){ - assert(bdb && heir > 0); - BDBNODE nent; - nent.id = ++bdb->nnum + BDBNODEIDBASE; - nent.idxs = tclistnew2(bdb->nmemb + 1); - nent.heir = heir; - nent.dirty = true; - tcmapputkeep(bdb->nodec, &(nent.id), sizeof(nent.id), &nent, sizeof(nent)); - int rsiz; - return (BDBNODE *)tcmapget(bdb->nodec, &(nent.id), sizeof(nent.id), &rsiz); -} - - -/* Remove a node from the cache. - `bdb' specifies the B+ tree database object. - `node' specifies the node object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbnodecacheout(TCBDB *bdb, BDBNODE *node){ - assert(bdb && node); - bool err = false; - if(node->dirty && !tcbdbnodesave(bdb, node)) err = true; - TCLIST *idxs = node->idxs; - int ln = TCLISTNUM(idxs); - for(int i = 0; i < ln; i++){ - BDBIDX *idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - free(idxp->kbuf); - } - tclistdel(idxs); - tcmapout(bdb->nodec, &(node->id), sizeof(node->id)); - return !err; -} - - -/* Save a node into the internal database. - `bdb' specifies the B+ tree database object. - `node' specifies the node object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbnodesave(TCBDB *bdb, BDBNODE *node){ - assert(bdb && node); - TCDODEBUG(bdb->cnt_savenode++); - TCXSTR *rbuf = tcxstrnew3(BDBPAGEBUFSIZ); - char hbuf[(sizeof(uint64_t)+1)*2]; - uint64_t llnum; - int step; - llnum = node->heir; - TCSETVNUMBUF64(step, hbuf, llnum); - TCXSTRCAT(rbuf, hbuf, step); - TCLIST *idxs = node->idxs; - int ln = TCLISTNUM(idxs); - for(int i = 0; i < ln; i++){ - BDBIDX *idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - char *wp = hbuf; - llnum = idxp->pid; - TCSETVNUMBUF64(step, wp, llnum); - wp += step; - uint32_t lnum = idxp->ksiz; - TCSETVNUMBUF(step, wp, lnum); - wp += step; - TCXSTRCAT(rbuf, hbuf, wp - hbuf); - TCXSTRCAT(rbuf, idxp->kbuf, idxp->ksiz); - } - bool err = false; - step = sprintf(hbuf, "#%llx", (unsigned long long)(node->id - BDBNODEIDBASE)); - if(!tchdbput(bdb->hdb, hbuf, step, TCXSTRPTR(rbuf), TCXSTRSIZE(rbuf))) err = true; - tcxstrdel(rbuf); - node->dirty = false; - return !err; -} - - -/* Load a node from the internal database. - `bdb' specifies the B+ tree database object. - `id' specifies the ID number of the node. - The return value is the node object or `NULL' on failure. */ -static BDBNODE *tcbdbnodeload(TCBDB *bdb, uint64_t id){ - assert(bdb && id > BDBNODEIDBASE); - bool clk = BDBLOCKCACHE(bdb); - int rsiz; - BDBNODE *node = (BDBNODE *)tcmapget3(bdb->nodec, &id, sizeof(id), &rsiz); - if(node){ - if(clk) BDBUNLOCKCACHE(bdb); - return node; - } - if(clk) BDBUNLOCKCACHE(bdb); - TCDODEBUG(bdb->cnt_loadnode++); - char hbuf[(sizeof(uint64_t)+1)*2]; - int step; - step = sprintf(hbuf, "#%llx", (unsigned long long)(id - BDBNODEIDBASE)); - char *rbuf = NULL; - char wbuf[BDBPAGEBUFSIZ]; - const char *rp = NULL; - rsiz = tchdbget3(bdb->hdb, hbuf, step, wbuf, BDBPAGEBUFSIZ); - if(rsiz < 1){ - tcbdbsetecode(bdb, TCEMISC, __FILE__, __LINE__, __func__); - return false; - } else if(rsiz < BDBPAGEBUFSIZ){ - rp = wbuf; - } else { - if(!(rbuf = tchdbget(bdb->hdb, hbuf, step, &rsiz))){ - tcbdbsetecode(bdb, TCEMISC, __FILE__, __LINE__, __func__); - return false; - } - rp = rbuf; - } - BDBNODE nent; - nent.id = id; - uint64_t llnum; - TCREADVNUMBUF64(rp, llnum, step); - nent.heir = llnum; - rp += step; - rsiz -= step; - nent.dirty = false; - nent.idxs = tclistnew2(bdb->nmemb + 1); - bool err = false; - while(rsiz >= 2){ - BDBIDX idx; - TCREADVNUMBUF64(rp, idx.pid, step); - rp += step; - rsiz -= step; - TCREADVNUMBUF(rp, idx.ksiz, step); - rp += step; - rsiz -= step; - if(rsiz < idx.ksiz){ - err = true; - break; - } - TCMEMDUP(idx.kbuf, rp, idx.ksiz); - rp += idx.ksiz; - rsiz -= idx.ksiz; - TCLISTPUSH(nent.idxs, &idx, sizeof(idx)); - } - free(rbuf); - if(err || rsiz != 0){ - tcbdbsetecode(bdb, TCEMISC, __FILE__, __LINE__, __func__); - return NULL; - } - clk = BDBLOCKCACHE(bdb); - tcmapputkeep(bdb->nodec, &(nent.id), sizeof(nent.id), &nent, sizeof(nent)); - node = (BDBNODE *)tcmapget(bdb->nodec, &(nent.id), sizeof(nent.id), &rsiz); - if(clk) BDBUNLOCKCACHE(bdb); - return node; -} - - -/* Add an index to a node. - `bdb' specifies the B+ tree database object. - `node' specifies the node object. - `order' specifies whether the calling sequence is orderd or not. - `pid' specifies the ID number of referred page. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. */ -static void tcbdbnodeaddidx(TCBDB *bdb, BDBNODE *node, bool order, uint64_t pid, - const char *kbuf, int ksiz){ - assert(bdb && node && pid > 0 && kbuf && ksiz >= 0); - BDBIDX idx; - idx.pid = pid; - TCMEMDUP(idx.kbuf, kbuf, ksiz); - idx.ksiz = ksiz; - BDBCMP cmp = bdb->cmp; - void *cmpop = bdb->cmpop; - TCLIST *idxs = node->idxs; - if(order){ - TCLISTPUSH(idxs, &idx, sizeof(idx)); - } else { - int ln = TCLISTNUM(idxs); - int left = 0; - int right = ln; - int i = (left + right) / 2; - while(right >= left && i < ln){ - BDBIDX *idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - int rv; - if(cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, idxp->kbuf, idxp->ksiz); - } else { - rv = cmp(kbuf, ksiz, idxp->kbuf, idxp->ksiz, cmpop); - } - if(rv == 0){ - break; - } else if(rv <= 0){ - right = i - 1; - } else { - left = i + 1; - } - i = (left + right) / 2; - } - while(i < ln){ - BDBIDX *idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - int rv; - if(cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, idxp->kbuf, idxp->ksiz); - } else { - rv = cmp(kbuf, ksiz, idxp->kbuf, idxp->ksiz, cmpop); - } - if(rv < 0){ - tclistinsert(idxs, i, &idx, sizeof(idx)); - break; - } - i++; - } - if(i >= ln) TCLISTPUSH(idxs, &idx, sizeof(idx)); - } - node->dirty = true; -} - - -/* Subtract an index from a node. - `bdb' specifies the B+ tree database object. - `node' specifies the node object. - `pid' specifies the ID number of referred page. - The return value is whether the subtraction is completed. */ -static bool tcbdbnodesubidx(TCBDB *bdb, BDBNODE *node, uint64_t pid){ - assert(bdb && node && pid > 0); - TCLIST *idxs = node->idxs; - int ln = TCLISTNUM(idxs); - if(ln < 2) return false; - if(node->heir == pid){ - int rsiz; - BDBIDX *idxp = (BDBIDX *)tclistshift(idxs, &rsiz); - node->heir = idxp->pid; - free(idxp->kbuf); - free(idxp); - node->dirty = true; - return true; - } else { - int ln = TCLISTNUM(idxs); - for(int i = 0; i < ln; i++){ - BDBIDX *idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - if(idxp->pid == pid){ - int rsiz; - free(idxp->kbuf); - free(tclistremove(idxs, i, &rsiz)); - node->dirty = true; - return true; - } - } - } - return false; -} - - -/* Search the leaf object corresponding to a key. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - The return value is the ID number of the leaf object or 0 on failure. */ -static uint64_t tcbdbsearchleaf(TCBDB *bdb, const char *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - BDBCMP cmp = bdb->cmp; - void *cmpop = bdb->cmpop; - uint64_t *hist = bdb->hist; - uint64_t pid = bdb->root; - int hnum = 0; - bdb->hleaf = 0; - while(pid > BDBNODEIDBASE){ - BDBNODE *node = tcbdbnodeload(bdb, pid); - if(!node){ - tcbdbsetecode(bdb, TCEMISC, __FILE__, __LINE__, __func__); - return 0; - } - TCLIST *idxs = node->idxs; - int ln = TCLISTNUM(idxs); - if(ln < 1){ - tcbdbsetecode(bdb, TCEMISC, __FILE__, __LINE__, __func__); - return 0; - } - hist[hnum++] = node->id; - int left = 0; - int right = ln; - int i = (left + right) / 2; - BDBIDX *idxp = NULL; - while(right >= left && i < ln){ - idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - int rv; - if(cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, idxp->kbuf, idxp->ksiz); - } else { - rv = cmp(kbuf, ksiz, idxp->kbuf, idxp->ksiz, cmpop); - } - if(rv == 0){ - break; - } else if(rv <= 0){ - right = i - 1; - } else { - left = i + 1; - } - i = (left + right) / 2; - } - if(i > 0) i--; - while(i < ln){ - idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - int rv; - if(cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, idxp->kbuf, idxp->ksiz); - } else { - rv = cmp(kbuf, ksiz, idxp->kbuf, idxp->ksiz, cmpop); - } - if(rv < 0){ - if(i == 0){ - pid = node->heir; - break; - } - idxp = (BDBIDX *)TCLISTVALPTR(idxs, i - 1); - pid = idxp->pid; - break; - } - i++; - } - if(i >= ln) pid = idxp->pid; - } - if(!bdb->mmtx){ - if(bdb->lleaf == pid) bdb->hleaf = pid; - bdb->lleaf = pid; - } - bdb->hnum = hnum; - return pid; -} - - -/* Search a record of a leaf. - `bdb' specifies the B+ tree database object. - `leaf' specifies the leaf object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `ip' specifies the pointer to a variable to fetch the index of the correspnding record. - The return value is the pointer to a corresponding record or `NULL' on failure. */ -static BDBREC *tcbdbsearchrec(TCBDB *bdb, BDBLEAF *leaf, const char *kbuf, int ksiz, int *ip){ - assert(bdb && leaf && kbuf && ksiz >= 0); - BDBCMP cmp = bdb->cmp; - void *cmpop = bdb->cmpop; - TCLIST *recs = leaf->recs; - int ln = TCLISTNUM(recs); - int left = 0; - int right = ln; - int i = (left + right) / 2; - while(right >= left && i < ln){ - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, i); - int rv; - if(cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, recp->kbuf, recp->ksiz); - } else { - rv = cmp(kbuf, ksiz, recp->kbuf, recp->ksiz, cmpop); - } - if(rv == 0){ - if(ip) *ip = i; - return recp; - } else if(rv <= 0){ - right = i - 1; - } else { - left = i + 1; - } - i = (left + right) / 2; - } - if(ip) *ip = i; - return NULL; -} - - -/* Adjust the caches for leaves and nodes. - `bdb' specifies the B+ tree database object. - The return value is true if successful, else, it is false. */ -static bool tcbdbcacheadjust(TCBDB *bdb){ - bool err = false; - if(TCMAPRNUM(bdb->leafc) > bdb->lcnum){ - TCDODEBUG(bdb->cnt_adjleafc++); - bool clk = BDBLOCKCACHE(bdb); - TCMAP *leafc = bdb->leafc; - tcmapiterinit(leafc); - for(int i = 0; i < BDBCACHEOUT; i++){ - int rsiz; - if(!tcbdbleafcacheout(bdb, (BDBLEAF *)tcmapiterval(tcmapiternext(leafc, &rsiz), &rsiz))) - err = true; - } - if(clk) BDBUNLOCKCACHE(bdb); - } - if(TCMAPRNUM(bdb->nodec) > bdb->ncnum){ - TCDODEBUG(bdb->cnt_adjnodec++); - bool clk = BDBLOCKCACHE(bdb); - TCMAP *nodec = bdb->nodec; - tcmapiterinit(nodec); - for(int i = 0; i < BDBCACHEOUT; i++){ - int rsiz; - if(!tcbdbnodecacheout(bdb, (BDBNODE *)tcmapiterval(tcmapiternext(nodec, &rsiz), &rsiz))) - err = true; - } - if(clk) BDBUNLOCKCACHE(bdb); - } - return !err; -} - - -/* Purge dirty pages of caches for leaves and nodes. - `bdb' specifies the B+ tree database object. */ -static void tcbdbcachepurge(TCBDB *bdb){ - bool clk = BDBLOCKCACHE(bdb); - int tsiz; - const char *tmp; - tcmapiterinit(bdb->leafc); - while((tmp = tcmapiternext(bdb->leafc, &tsiz)) != NULL){ - int lsiz; - BDBLEAF *leaf = (BDBLEAF *)tcmapiterval(tmp, &lsiz); - if(!leaf->dirty) continue; - TCLIST *recs = leaf->recs; - int ln = TCLISTNUM(recs); - for(int i = 0; i < ln; i++){ - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, i); - free(recp->kbuf); - free(recp->vbuf); - if(recp->rest) tclistdel(recp->rest); - } - tclistdel(recs); - tcmapout(bdb->leafc, tmp, tsiz); - } - tcmapiterinit(bdb->nodec); - while((tmp = tcmapiternext(bdb->nodec, &tsiz)) != NULL){ - int nsiz; - BDBNODE *node = (BDBNODE *)tcmapiterval(tmp, &nsiz); - if(!node->dirty) continue; - TCLIST *idxs = node->idxs; - int ln = TCLISTNUM(idxs); - for(int i = 0; i < ln; i++){ - BDBIDX *idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - free(idxp->kbuf); - } - tclistdel(idxs); - tcmapout(bdb->nodec, tmp, tsiz); - } - if(clk) BDBUNLOCKCACHE(bdb); -} - - -/* Open a database file and connect a B+ tree database object. - `bdb' specifies the B+ tree database object. - `path' specifies the path of the internal database file. - `omode' specifies the connection mode. - If successful, the return value is true, else, it is false. */ -static bool tcbdbopenimpl(TCBDB *bdb, const char *path, int omode){ - assert(bdb && path); - int homode = HDBOREADER; - if(omode & BDBOWRITER){ - homode = HDBOWRITER; - if(omode & BDBOCREAT) homode |= HDBOCREAT; - if(omode & BDBOTRUNC) homode |= HDBOTRUNC; - bdb->wmode = true; - } else { - bdb->wmode = false; - } - if(omode & BDBONOLCK) homode |= HDBONOLCK; - if(omode & BDBOLCKNB) homode |= HDBOLCKNB; - tchdbsettype(bdb->hdb, HDBTBTREE); - if(!tchdbopen(bdb->hdb, path, homode)) return false; - bdb->root = 0; - bdb->first = 0; - bdb->last = 0; - bdb->lnum = 0; - bdb->nnum = 0; - bdb->rnum = 0; - bdb->opaque = tchdbopaque(bdb->hdb); - bdb->leafc = tcmapnew2(bdb->lcnum * 2 + 1); - bdb->nodec = tcmapnew2(bdb->ncnum * 2 + 1); - if(bdb->wmode && tchdbrnum(bdb->hdb) < 1){ - BDBLEAF *leaf = tcbdbleafnew(bdb, 0, 0); - bdb->root = leaf->id; - bdb->first = leaf->id; - bdb->last = leaf->id; - bdb->lnum = 1; - bdb->nnum = 0; - bdb->rnum = 0; - if(!bdb->cmp){ - bdb->cmp = tcbdbcmplexical; - bdb->cmpop = NULL; - } - tcdumpmeta(bdb); - if(!tcbdbleafsave(bdb, leaf)){ - tcmapdel(bdb->nodec); - tcmapdel(bdb->leafc); - tchdbclose(bdb->hdb); - return false; - } - } - tcloadmeta(bdb); - if(!bdb->cmp){ - tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__); - tcmapdel(bdb->nodec); - tcmapdel(bdb->leafc); - tchdbclose(bdb->hdb); - return false; - } - if(bdb->lmemb < BDBMINLMEMB || bdb->nmemb < BDBMINNMEMB || - bdb->root < 1 || bdb->first < 1 || bdb->last < 1 || - bdb->lnum < 0 || bdb->nnum < 0 || bdb->rnum < 0){ - tcbdbsetecode(bdb, TCEMETA, __FILE__, __LINE__, __func__); - tcmapdel(bdb->nodec); - tcmapdel(bdb->leafc); - tchdbclose(bdb->hdb); - return false; - } - bdb->open = true; - uint8_t hopts = tchdbopts(bdb->hdb); - uint8_t opts = 0; - if(hopts & HDBTLARGE) opts |= BDBTLARGE; - if(hopts & HDBTDEFLATE) opts |= BDBTDEFLATE; - if(hopts & HDBTTCBS) opts |= BDBTTCBS; - bdb->opts = opts; - bdb->hleaf = 0; - bdb->lleaf = 0; - bdb->tran = false; - bdb->rbopaque = NULL; - return true; -} - - -/* Close a B+ tree database object. - `bdb' specifies the B+ tree database object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcloseimpl(TCBDB *bdb){ - assert(bdb); - if(bdb->tran){ - tcbdbcachepurge(bdb); - memcpy(bdb->opaque, bdb->rbopaque, BDBOPAQUESIZ); - tcloadmeta(bdb); - free(bdb->rbopaque); - bdb->tran = false; - bdb->rbopaque = NULL; - BDBUNLOCKTRAN(bdb); - } - bool err = false; - bdb->open = false; - const char *vbuf; - int vsiz; - TCMAP *leafc = bdb->leafc; - tcmapiterinit(leafc); - while((vbuf = tcmapiternext(leafc, &vsiz)) != NULL){ - if(!tcbdbleafcacheout(bdb, (BDBLEAF *)tcmapiterval(vbuf, &vsiz))) err = true; - } - TCMAP *nodec = bdb->nodec; - tcmapiterinit(nodec); - while((vbuf = tcmapiternext(nodec, &vsiz)) != NULL){ - if(!tcbdbnodecacheout(bdb, (BDBNODE *)tcmapiterval(vbuf, &vsiz))) err = true; - } - if(bdb->wmode) tcdumpmeta(bdb); - tcmapdel(bdb->nodec); - tcmapdel(bdb->leafc); - if(!tchdbclose(bdb->hdb)) err = true; - return !err; -} - - -/* Store a record into a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - `dmode' specifies behavior when the key overlaps. - If successful, the return value is true, else, it is false. */ -static bool tcbdbputimpl(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz, - int dmode){ - assert(bdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - BDBLEAF *leaf = NULL; - if(bdb->hleaf < 1 || !(leaf = tcbdbgethistleaf(bdb, kbuf, ksiz))){ - uint64_t pid = tcbdbsearchleaf(bdb, kbuf, ksiz); - if(pid < 1) return false; - if(!(leaf = tcbdbleafload(bdb, pid))) return false; - } - if(!tcbdbleafaddrec(bdb, leaf, dmode, kbuf, ksiz, vbuf, vsiz)){ - tcbdbsetecode(bdb, TCEKEEP, __FILE__, __LINE__, __func__); - return false; - } - int rnum = TCLISTNUM(leaf->recs); - if(rnum > bdb->lmemb || - (bdb->lsmax > 0 && rnum > BDBMINLMEMB && (bdb->lschk++ & (0x8 - 1)) == 0 && - tcbdbleafdatasize(leaf) > bdb->lsmax)){ - bdb->lschk = 0; - BDBLEAF *newleaf = tcbdbleafdivide(bdb, leaf); - if(!newleaf) return false; - if(leaf->id == bdb->last) bdb->last = newleaf->id; - uint64_t heir = leaf->id; - uint64_t pid = newleaf->id; - BDBREC *recp = (BDBREC *)TCLISTVALPTR(newleaf->recs, 0); - int ksiz = recp->ksiz; - char *kbuf; - TCMEMDUP(kbuf, recp->kbuf, ksiz); - while(true){ - BDBNODE *node; - if(bdb->hnum < 1){ - node = tcbdbnodenew(bdb, heir); - tcbdbnodeaddidx(bdb, node, true, pid, kbuf, ksiz); - bdb->root = node->id; - free(kbuf); - break; - } - uint64_t parent = bdb->hist[--bdb->hnum]; - if(!(node = tcbdbnodeload(bdb, parent))){ - free(kbuf); - return false; - } - tcbdbnodeaddidx(bdb, node, false, pid, kbuf, ksiz); - free(kbuf); - TCLIST *idxs = node->idxs; - int ln = TCLISTNUM(idxs); - if(ln <= bdb->nmemb) break; - int mid = ln / 2; - BDBIDX *idxp = (BDBIDX *)TCLISTVALPTR(idxs, mid); - BDBNODE *newnode = tcbdbnodenew(bdb, idxp->pid); - heir = node->id; - pid = newnode->id; - TCMEMDUP(kbuf, idxp->kbuf, idxp->ksiz); - ksiz = idxp->ksiz; - for(int i = mid + 1; i < ln; i++){ - idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - tcbdbnodeaddidx(bdb, newnode, true, idxp->pid, idxp->kbuf, idxp->ksiz); - } - ln = TCLISTNUM(newnode->idxs); - for(int i = 0; i < ln; i++){ - int rsiz; - idxp = (BDBIDX *)tclistpop(idxs, &rsiz); - free(idxp->kbuf); - free(idxp); - } - node->dirty = true; - } - if(bdb->capnum > 0 && bdb->rnum > bdb->capnum){ - uint64_t xnum = bdb->rnum - bdb->capnum; - BDBCUR *cur = tcbdbcurnew(bdb); - tcbdbcurfirstimpl(cur); - while((xnum--) > 0){ - if(!tcbdbcuroutimpl(cur)){ - tcbdbcurdel(cur); - return false; - } - } - tcbdbcurdel(cur); - } - } - if(!bdb->tran && !tcbdbcacheadjust(bdb)) return false; - return true; -} - - -/* Remove a record of a B+ tree database object. - `hdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. */ -static bool tcbdboutimpl(TCBDB *bdb, const char *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - BDBLEAF *leaf = NULL; - if(bdb->hleaf < 1 || !(leaf = tcbdbgethistleaf(bdb, kbuf, ksiz))){ - uint64_t pid = tcbdbsearchleaf(bdb, kbuf, ksiz); - if(pid < 1) return false; - if(!(leaf = tcbdbleafload(bdb, pid))) return false; - } - int ri; - BDBREC *recp = tcbdbsearchrec(bdb, leaf, kbuf, ksiz, &ri); - if(!recp){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; - } - if(recp->rest){ - free(recp->vbuf); - recp->vbuf = tclistshift(recp->rest, &(recp->vsiz)); - if(TCLISTNUM(recp->rest) < 1){ - tclistdel(recp->rest); - recp->rest = NULL; - } - } else { - free(recp->vbuf); - free(recp->kbuf); - int rsiz; - free(tclistremove(leaf->recs, ri, &rsiz)); - } - leaf->dirty = true; - bdb->rnum--; - if(TCLISTNUM(leaf->recs) < 1 && bdb->hnum > 0 && !tcbdbleafkill(bdb, leaf)) return false; - if(!bdb->tran && !tcbdbcacheadjust(bdb)) return false; - return true; -} - - -/* Remove records of a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. */ -static bool tcbdboutlist(TCBDB *bdb, const char *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - BDBLEAF *leaf = NULL; - if(bdb->hleaf < 1 || !(leaf = tcbdbgethistleaf(bdb, kbuf, ksiz))){ - uint64_t pid = tcbdbsearchleaf(bdb, kbuf, ksiz); - if(pid < 1) return false; - if(!(leaf = tcbdbleafload(bdb, pid))) return false; - } - int ri; - BDBREC *recp = tcbdbsearchrec(bdb, leaf, kbuf, ksiz, &ri); - if(!recp){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; - } - int rnum = 1; - if(recp->rest){ - rnum += TCLISTNUM(recp->rest); - tclistdel(recp->rest); - } - free(recp->vbuf); - free(recp->kbuf); - int rsiz; - free(tclistremove(leaf->recs, ri, &rsiz)); - leaf->dirty = true; - bdb->rnum -= rnum; - if(TCLISTNUM(leaf->recs) < 1 && bdb->hnum > 0 && !tcbdbleafkill(bdb, leaf)) return false; - if(!bdb->tran && !tcbdbcacheadjust(bdb)) return false; - return true; -} - - -/* Retrieve a record in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the corresponding - record. */ -static const char *tcbdbgetimpl(TCBDB *bdb, const char *kbuf, int ksiz, int *sp){ - assert(bdb && kbuf && ksiz >= 0 && sp); - BDBLEAF *leaf = NULL; - if(bdb->hleaf < 1 || !(leaf = tcbdbgethistleaf(bdb, kbuf, ksiz))){ - uint64_t pid = tcbdbsearchleaf(bdb, kbuf, ksiz); - if(pid < 1) return NULL; - if(!(leaf = tcbdbleafload(bdb, pid))) return NULL; - } - BDBREC *recp = tcbdbsearchrec(bdb, leaf, kbuf, ksiz, NULL); - if(!recp){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return NULL; - } - *sp = recp->vsiz; - return recp->vbuf; -} - - -/* Get the number of records corresponding a key in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is the number of the corresponding records, else, it is 0. */ -static int tcbdbgetnum(TCBDB *bdb, const char *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - BDBLEAF *leaf = NULL; - if(bdb->hleaf < 1 || !(leaf = tcbdbgethistleaf(bdb, kbuf, ksiz))){ - uint64_t pid = tcbdbsearchleaf(bdb, kbuf, ksiz); - if(pid < 1) return 0; - if(!(leaf = tcbdbleafload(bdb, pid))) return 0; - } - BDBREC *recp = tcbdbsearchrec(bdb, leaf, kbuf, ksiz, NULL); - if(!recp){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return 0; - } - return recp->rest ? TCLISTNUM(recp->rest) + 1 : 1; -} - - -/* Retrieve records in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is a list object of the values of the corresponding records. */ -static TCLIST *tcbdbgetlist(TCBDB *bdb, const char *kbuf, int ksiz){ - assert(bdb && kbuf && ksiz >= 0); - BDBLEAF *leaf = NULL; - if(bdb->hleaf < 1 || !(leaf = tcbdbgethistleaf(bdb, kbuf, ksiz))){ - uint64_t pid = tcbdbsearchleaf(bdb, kbuf, ksiz); - if(pid < 1) return NULL; - if(!(leaf = tcbdbleafload(bdb, pid))) return NULL; - } - BDBREC *recp = tcbdbsearchrec(bdb, leaf, kbuf, ksiz, NULL); - if(!recp){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return NULL; - } - TCLIST *vals; - TCLIST *rest = recp->rest; - if(rest){ - int ln = TCLISTNUM(rest); - vals = tclistnew2(ln + 1); - TCLISTPUSH(vals, recp->vbuf, recp->vsiz); - for(int i = 0; i < ln; i++){ - int vsiz; - const char *vbuf = tclistval(rest, i, &vsiz); - TCLISTPUSH(vals, vbuf, vsiz); - } - } else { - vals = tclistnew2(1); - TCLISTPUSH(vals, recp->vbuf, recp->vsiz); - } - return vals; -} - - -/* Get keys of ranged records in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `bkbuf' specifies the pointer to the region of the key of the beginning border. - `bksiz' specifies the size of the region of the beginning key. - `binc' specifies whether the beginning border is inclusive or not. - `ekbuf' specifies the pointer to the region of the key of the ending border. - `eksiz' specifies the size of the region of the ending key. - `einc' specifies whether the ending border is inclusive or not. - `max' specifies the maximum number of keys to be fetched. - `keys' specifies a list object to store the result. - If successful, the return value is true, else, it is false. */ -static bool tcbdbrangeimpl(TCBDB *bdb, const char *bkbuf, int bksiz, bool binc, - const char *ekbuf, int eksiz, bool einc, int max, TCLIST *keys){ - assert(bdb && keys); - bool err = false; - BDBCUR *cur = tcbdbcurnew(bdb); - if(bkbuf){ - tcbdbcurjumpimpl(cur, bkbuf, bksiz, true); - } else { - tcbdbcurfirstimpl(cur); - } - BDBCMP cmp = bdb->cmp; - void *cmpop = bdb->cmpop; - const char *lbuf = NULL; - int lsiz = 0; - while(cur->id > 0){ - const char *kbuf, *vbuf; - int ksiz, vsiz; - if(!tcbdbcurrecimpl(cur, &kbuf, &ksiz, &vbuf, &vsiz)){ - if(tchdbecode(bdb->hdb) != TCEINVALID && tchdbecode(bdb->hdb) != TCENOREC) err = true; - break; - } - if(bkbuf && !binc){ - if(cmp(kbuf, ksiz, bkbuf, bksiz, cmpop) == 0){ - tcbdbcurnext(cur); - continue; - } - bkbuf = NULL; - } - if(ekbuf){ - if(einc){ - if(cmp(kbuf, ksiz, ekbuf, eksiz, cmpop) > 0) break; - } else { - if(cmp(kbuf, ksiz, ekbuf, eksiz, cmpop) >= 0) break; - } - } - if(!lbuf || lsiz != ksiz || memcmp(kbuf, lbuf, ksiz)){ - TCLISTPUSH(keys, kbuf, ksiz); - if(max >= 0 && TCLISTNUM(keys) >= max) break; - lbuf = kbuf; - lsiz = ksiz; - } - tcbdbcurnextimpl(cur); - } - tcbdbcurdel(cur); - return !err; -} - - -/* Get forward matching keys in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `pbuf' specifies the pointer to the region of the prefix. - `psiz' specifies the size of the region of the prefix. - `max' specifies the maximum number of keys to be fetched. - `keys' specifies a list object to store the result. - If successful, the return value is true, else, it is false. */ -static bool tcbdbrangefwm(TCBDB *bdb, const char *pbuf, int psiz, int max, TCLIST *keys){ - assert(bdb && pbuf && psiz >= 0 && keys); - bool err = false; - if(max < 0) max = INT_MAX; - BDBCUR *cur = tcbdbcurnew(bdb); - tcbdbcurjumpimpl(cur, pbuf, psiz, true); - const char *lbuf = NULL; - int lsiz = 0; - while(cur->id > 0){ - const char *kbuf, *vbuf; - int ksiz, vsiz; - if(!tcbdbcurrecimpl(cur, &kbuf, &ksiz, &vbuf, &vsiz)){ - if(tchdbecode(bdb->hdb) != TCEINVALID && tchdbecode(bdb->hdb) != TCENOREC) err = true; - break; - } - if(ksiz < psiz || memcmp(kbuf, pbuf, psiz)) break; - if(!lbuf || lsiz != ksiz || memcmp(kbuf, lbuf, ksiz)){ - TCLISTPUSH(keys, kbuf, ksiz); - if(TCLISTNUM(keys) >= max) break; - lbuf = kbuf; - lsiz = ksiz; - } - tcbdbcurnextimpl(cur); - } - tcbdbcurdel(cur); - return !err; -} - - -/* Optimize the file of a B+ tree database object. - `bdb' specifies the B+ tree database object. - `lmemb' specifies the number of members in each leaf page. - `nmemb' specifies the number of members in each non-leaf page. - `bnum' specifies the number of elements of the bucket array. - `apow' specifies the size of record alignment by power of 2. - `fpow' specifies the maximum number of elements of the free block pool by power of 2. - `opts' specifies options by bitwise or. - If successful, the return value is true, else, it is false. */ -static bool tcbdboptimizeimpl(TCBDB *bdb, int32_t lmemb, int32_t nmemb, - int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){ - assert(bdb); - if(lmemb < 1) lmemb = bdb->lmemb; - if(nmemb < 1) nmemb = bdb->nmemb; - if(bnum < 1) bnum = tchdbrnum(bdb->hdb) * 2 + 1; - if(opts == UINT8_MAX) opts = bdb->opts; - const char *path = tchdbpath(bdb->hdb); - char *tpath = tcsprintf("%s%ctmp%c%llu", path, MYEXTCHR, MYEXTCHR, tchdbinode(bdb->hdb)); - TCBDB *tbdb = tcbdbnew(); - tcbdbsetcmpfunc(tbdb, bdb->cmp, bdb->cmpop); - tcbdbtune(tbdb, lmemb, nmemb, bnum, apow, fpow, opts); - tcbdbsetlsmax(tbdb, bdb->lsmax); - if(!tcbdbopen(tbdb, tpath, BDBOWRITER | BDBOCREAT | BDBOTRUNC)){ - tcbdbsetecode(bdb, tcbdbecode(tbdb), __FILE__, __LINE__, __func__); - tcbdbdel(tbdb); - free(tpath); - return false; - } - bool err = false; - BDBCUR *cur = tcbdbcurnew(bdb); - tcbdbcurfirstimpl(cur); - const char *kbuf, *vbuf; - int ksiz, vsiz; - while(!err && cur->id > 0 && tcbdbcurrecimpl(cur, &kbuf, &ksiz, &vbuf, &vsiz)){ - if(!tcbdbputdup(tbdb, kbuf, ksiz, vbuf, vsiz)){ - tcbdbsetecode(bdb, tcbdbecode(tbdb), __FILE__, __LINE__, __func__); - err = true; - } - tcbdbcurnextimpl(cur); - } - tcbdbcurdel(cur); - if(!tcbdbclose(tbdb)){ - tcbdbsetecode(bdb, tcbdbecode(tbdb), __FILE__, __LINE__, __func__); - err = true; - } - tcbdbdel(tbdb); - if(unlink(path) == -1){ - tcbdbsetecode(bdb, TCEUNLINK, __FILE__, __LINE__, __func__); - err = true; - } - if(rename(tpath, path) == -1){ - tcbdbsetecode(bdb, TCERENAME, __FILE__, __LINE__, __func__); - err = true; - } - free(tpath); - if(err) return false; - tpath = tcstrdup(path); - int omode = (tchdbomode(bdb->hdb) & ~BDBOCREAT) & ~BDBOTRUNC; - if(!tcbdbcloseimpl(bdb)){ - free(tpath); - return false; - } - bool rv = tcbdbopenimpl(bdb, tpath, omode); - free(tpath); - return rv; -} - - -/* Remove all records of a B+ tree database object. - `bdb' specifies the B+ tree database object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbvanishimpl(TCBDB *bdb){ - assert(bdb); - char *path = tcstrdup(tchdbpath(bdb->hdb)); - int omode = tchdbomode(bdb->hdb); - bool err = false; - if(!tcbdbcloseimpl(bdb)) err = true; - if(!tcbdbopenimpl(bdb, path, BDBOTRUNC | omode)) err = true; - free(path); - return !err; -} - - -/* Lock a method of the B+ tree database object. - `bdb' specifies the B+ tree database object. - `wr' specifies whether the lock is writer or not. - If successful, the return value is true, else, it is false. */ -static bool tcbdblockmethod(TCBDB *bdb, bool wr){ - assert(bdb); - if(wr ? pthread_rwlock_wrlock(bdb->mmtx) != 0 : pthread_rwlock_rdlock(bdb->mmtx) != 0){ - tcbdbsetecode(bdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Unlock a method of the B+ tree database object. - `hdb' specifies the B+ tree database object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbunlockmethod(TCBDB *bdb){ - assert(bdb); - if(pthread_rwlock_unlock(bdb->mmtx) != 0){ - tcbdbsetecode(bdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Lock the cache of the B+ tree database object. - `hdb' specifies the B+ tree database object. - If successful, the return value is true, else, it is false. */ -static bool tcbdblockcache(TCBDB *bdb){ - assert(bdb); - if(pthread_mutex_lock(bdb->cmtx) != 0){ - tcbdbsetecode(bdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Unlock the cache of the B+ tree database object. - `hdb' specifies the B+ tree database object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbunlockcache(TCBDB *bdb){ - assert(bdb); - if(pthread_mutex_unlock(bdb->cmtx) != 0){ - tcbdbsetecode(bdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Lock the transaction of the B+ tree database object. - `hdb' specifies the B+ tree database object. - If successful, the return value is true, else, it is false. */ -static bool tcbdblocktran(TCBDB *bdb){ - assert(bdb); - if(pthread_mutex_lock(bdb->tmtx) != 0){ - tcbdbsetecode(bdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Unlock the transaction of the B+ tree database object. - `hdb' specifies the B+ tree database object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbunlocktran(TCBDB *bdb){ - assert(bdb); - if(pthread_mutex_unlock(bdb->tmtx) != 0){ - tcbdbsetecode(bdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Move a cursor object to the first record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcurfirstimpl(BDBCUR *cur){ - assert(cur); - cur->id = cur->bdb->first; - cur->kidx = 0; - cur->vidx = 0; - return tcbdbcuradjust(cur, true); -} - - -/* Move a cursor object to the last record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcurlastimpl(BDBCUR *cur){ - assert(cur); - cur->id = cur->bdb->last; - cur->kidx = INT_MAX; - cur->vidx = INT_MAX; - return tcbdbcuradjust(cur, false); -} - - -/* Move a cursor object to around records corresponding a key. - `cur' specifies the cursor object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `forward' specifies whether the cursor is to be the front of records. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcurjumpimpl(BDBCUR *cur, const char *kbuf, int ksiz, bool forward){ - assert(cur && kbuf && ksiz >= 0); - TCBDB *bdb = cur->bdb; - uint64_t pid = tcbdbsearchleaf(bdb, kbuf, ksiz); - if(pid < 1){ - cur->id = 0; - cur->kidx = 0; - cur->vidx = 0; - return false; - } - BDBLEAF *leaf = tcbdbleafload(bdb, pid); - if(!leaf){ - cur->id = 0; - cur->kidx = 0; - cur->vidx = 0; - return false; - } - if(TCLISTNUM(leaf->recs) < 1){ - cur->id = pid; - cur->kidx = 0; - cur->vidx = 0; - return forward ? tcbdbcurnextimpl(cur) : tcbdbcurprevimpl(cur); - } - int ri; - BDBREC *recp = tcbdbsearchrec(bdb, leaf, kbuf, ksiz, &ri); - if(recp){ - cur->id = pid; - cur->kidx = ri; - if(forward){ - cur->vidx = 0; - } else { - cur->vidx = recp->rest ? TCLISTNUM(recp->rest) : 0; - } - return true; - } - cur->id = leaf->id; - if(ri > 0 && ri >= TCLISTNUM(leaf->recs)) ri = TCLISTNUM(leaf->recs) - 1; - cur->kidx = ri; - recp = (BDBREC *)TCLISTVALPTR(leaf->recs, ri); - if(forward){ - int rv; - if(bdb->cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, recp->kbuf, recp->ksiz); - } else { - rv = bdb->cmp(kbuf, ksiz, recp->kbuf, recp->ksiz, bdb->cmpop); - } - if(rv < 0) return true; - cur->vidx = recp->rest ? TCLISTNUM(recp->rest) : 0; - return tcbdbcurnextimpl(cur); - } - int rv; - if(bdb->cmp == tcbdbcmplexical){ - TCCMPLEXICAL(rv, kbuf, ksiz, recp->kbuf, recp->ksiz); - } else { - rv = bdb->cmp(kbuf, ksiz, recp->kbuf, recp->ksiz, bdb->cmpop); - } - if(rv > 0) return true; - cur->vidx = 0; - return tcbdbcurprevimpl(cur); -} - - -/* Adjust a cursor object forward to the suitable record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcuradjust(BDBCUR *cur, bool forward){ - assert(cur); - TCBDB *bdb = cur->bdb; - while(true){ - if(cur->id < 1){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - cur->id = 0; - cur->kidx = 0; - cur->vidx = 0; - return false; - } - BDBLEAF *leaf = tcbdbleafload(bdb, cur->id); - if(!leaf) return false; - TCLIST *recs = leaf->recs; - int knum = TCLISTNUM(recs); - if(cur->kidx < 0){ - if(forward){ - cur->kidx = 0; - cur->vidx = 0; - } else { - cur->id = leaf->prev; - cur->kidx = INT_MAX; - cur->vidx = INT_MAX; - } - } else if(cur->kidx >= knum){ - if(forward){ - cur->id = leaf->next; - cur->kidx = 0; - cur->vidx = 0; - } else { - cur->kidx = knum - 1; - cur->vidx = INT_MAX; - } - } else { - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, cur->kidx); - int vnum = recp->rest ? TCLISTNUM(recp->rest) + 1 : 1; - if(cur->vidx < 0){ - if(forward){ - cur->vidx = 0; - } else { - cur->kidx--; - cur->vidx = INT_MAX; - } - } else if(cur->vidx >= vnum){ - if(forward){ - cur->kidx++; - cur->vidx = 0; - if(cur->kidx >= knum){ - cur->id = leaf->next; - cur->kidx = 0; - cur->vidx = 0; - } else { - break; - } - } else { - cur->vidx = vnum - 1; - if(cur->vidx >= 0) break; - } - } else { - break; - } - } - } - return true; -} - - -/* Move a cursor object to the previous record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcurprevimpl(BDBCUR *cur){ - assert(cur); - cur->vidx--; - return tcbdbcuradjust(cur, false); -} - - -/* Move a cursor object to the next record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcurnextimpl(BDBCUR *cur){ - assert(cur); - cur->vidx++; - return tcbdbcuradjust(cur, true); -} - - -/* Insert a record around a cursor object. - `cur' specifies the cursor object. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - `cpmode' specifies detail adjustment. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcurputimpl(BDBCUR *cur, const char *vbuf, int vsiz, int cpmode){ - assert(cur && vbuf && vsiz >= 0); - TCBDB *bdb = cur->bdb; - BDBLEAF *leaf = tcbdbleafload(bdb, cur->id); - if(!leaf) return false; - TCLIST *recs = leaf->recs; - if(cur->kidx >= TCLISTNUM(recs)){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; - } - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, cur->kidx); - int vnum = recp->rest ? TCLISTNUM(recp->rest) + 1 : 1; - if(cur->vidx >= vnum){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; - } - switch(cpmode){ - case BDBCPCURRENT: - if(cur->vidx < 1){ - if(vsiz > recp->vsiz) TCREALLOC(recp->vbuf, recp->vbuf, vsiz + 1); - memcpy(recp->vbuf, vbuf, vsiz); - recp->vbuf[vsiz] = '\0'; - recp->vsiz = vsiz; - } else { - tclistover(recp->rest, cur->vidx - 1, vbuf, vsiz); - } - break; - case BDBCPBEFORE: - if(cur->vidx < 1){ - if(!recp->rest) recp->rest = tclistnew(); - tclistunshift(recp->rest, recp->vbuf, recp->vsiz); - if(vsiz > recp->vsiz) TCREALLOC(recp->vbuf, recp->vbuf, vsiz + 1); - memcpy(recp->vbuf, vbuf, vsiz); - recp->vbuf[vsiz] = '\0'; - recp->vsiz = vsiz; - } else { - tclistinsert(recp->rest, cur->vidx - 1, vbuf, vsiz); - } - bdb->rnum++; - break; - case BDBCPAFTER: - if(!recp->rest) recp->rest = tclistnew(); - tclistinsert(recp->rest, cur->vidx, vbuf, vsiz); - cur->vidx++; - bdb->rnum++; - break; - } - leaf->dirty = true; - return true; -} - - -/* Delete the record where a cursor object is. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. */ -static bool tcbdbcuroutimpl(BDBCUR *cur){ - assert(cur); - TCBDB *bdb = cur->bdb; - BDBLEAF *leaf = tcbdbleafload(bdb, cur->id); - if(!leaf) return false; - TCLIST *recs = leaf->recs; - if(cur->kidx >= TCLISTNUM(recs)){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; - } - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, cur->kidx); - int vnum = recp->rest ? TCLISTNUM(recp->rest) + 1 : 1; - if(cur->vidx >= vnum){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; - } - if(recp->rest){ - if(cur->vidx < 1){ - free(recp->vbuf); - recp->vbuf = tclistshift(recp->rest, &(recp->vsiz)); - } else { - int vsiz; - free(tclistremove(recp->rest, cur->vidx - 1, &vsiz)); - } - if(TCLISTNUM(recp->rest) < 1){ - tclistdel(recp->rest); - recp->rest = NULL; - } - } else { - if(TCLISTNUM(recs) < 2 && bdb->hnum > 0){ - uint64_t pid = tcbdbsearchleaf(bdb, recp->kbuf, recp->ksiz); - if(pid < 1) return false; - if(!(leaf = tcbdbleafload(bdb, pid))) return false; - if(!tcbdbleafkill(bdb, leaf)) return false; - } - free(recp->vbuf); - free(recp->kbuf); - int rsiz; - free(tclistremove(leaf->recs, cur->kidx, &rsiz)); - } - bdb->rnum--; - leaf->dirty = true; - return tcbdbcuradjust(cur, true) || tchdbecode(bdb->hdb) == TCENOREC; -} - - -/* Get the key and the value of the current record of the cursor object. - `cur' specifies the cursor object. - `kbp' specifies the pointer to the variable into which the pointer to the region of the key is - assgined. - `ksp' specifies the pointer to the variable into which the size of the key region is assigned. - `vbp' specifies the pointer to the variable into which the pointer to the region of the value - is assgined. - `vsp' specifies the pointer to the variable into which the size of the value region is - assigned. */ -static bool tcbdbcurrecimpl(BDBCUR *cur, const char **kbp, int *ksp, const char **vbp, int *vsp){ - assert(cur && kbp && ksp && vbp && vsp); - TCBDB *bdb = cur->bdb; - BDBLEAF *leaf = tcbdbleafload(bdb, cur->id); - if(!leaf) return false; - TCLIST *recs = leaf->recs; - if(cur->kidx >= TCLISTNUM(recs)){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; - } - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, cur->kidx); - int vnum = recp->rest ? TCLISTNUM(recp->rest) + 1 : 1; - if(cur->vidx >= vnum){ - tcbdbsetecode(bdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; - } - *kbp = recp->kbuf; - *ksp = recp->ksiz; - if(cur->vidx > 0){ - *vbp = tclistval(recp->rest, cur->vidx - 1, vsp); - } else { - *vbp = recp->vbuf; - *vsp = recp->vsiz; - } - return true; -} - - - -/************************************************************************************************* - * debugging functions - *************************************************************************************************/ - - -/* Print meta data of the header into the debugging output. - `bdb' specifies the B+ tree database object. */ -void tcbdbprintmeta(TCBDB *bdb){ - assert(bdb); - int dbgfd = tchdbdbgfd(bdb->hdb); - if(dbgfd < 0) return; - char buf[BDBPAGEBUFSIZ]; - char *wp = buf; - wp += sprintf(wp, "META:"); - wp += sprintf(wp, " mmtx=%p", (void *)bdb->mmtx); - wp += sprintf(wp, " cmtx=%p", (void *)bdb->cmtx); - wp += sprintf(wp, " tmtx=%p", (void *)bdb->tmtx); - wp += sprintf(wp, " hdb=%p", (void *)bdb->hdb); - wp += sprintf(wp, " opaque=%p", (void *)bdb->opaque); - wp += sprintf(wp, " open=%d", bdb->open); - wp += sprintf(wp, " wmode=%d", bdb->wmode); - wp += sprintf(wp, " lmemb=%u", bdb->lmemb); - wp += sprintf(wp, " nmemb=%u", bdb->nmemb); - wp += sprintf(wp, " opts=%u", bdb->opts); - wp += sprintf(wp, " root=%llu", (unsigned long long)bdb->root); - wp += sprintf(wp, " first=%llu", (unsigned long long)bdb->first); - wp += sprintf(wp, " last=%llu", (unsigned long long)bdb->last); - wp += sprintf(wp, " lnum=%llu", (unsigned long long)bdb->lnum); - wp += sprintf(wp, " nnum=%llu", (unsigned long long)bdb->nnum); - wp += sprintf(wp, " rnum=%llu", (unsigned long long)bdb->rnum); - wp += sprintf(wp, " leafc=%p", (void *)bdb->leafc); - wp += sprintf(wp, " nodec=%p", (void *)bdb->nodec); - wp += sprintf(wp, " cmp=%p", (void *)(intptr_t)bdb->cmp); - wp += sprintf(wp, " cmpop=%p", (void *)bdb->cmpop); - wp += sprintf(wp, " lcnum=%u", bdb->lcnum); - wp += sprintf(wp, " ncnum=%u", bdb->ncnum); - wp += sprintf(wp, " lsmax=%u", bdb->lsmax); - wp += sprintf(wp, " lschk=%u", bdb->lschk); - wp += sprintf(wp, " capnum=%llu", (unsigned long long)bdb->capnum); - wp += sprintf(wp, " hist=%p", (void *)bdb->hist); - wp += sprintf(wp, " hnum=%d", bdb->hnum); - wp += sprintf(wp, " hleaf=%llu", (unsigned long long)bdb->hleaf); - wp += sprintf(wp, " lleaf=%llu", (unsigned long long)bdb->lleaf); - wp += sprintf(wp, " tran=%d", bdb->tran); - wp += sprintf(wp, " rbopaque=%p", (void *)bdb->rbopaque); - wp += sprintf(wp, " cnt_saveleaf=%lld", (long long)bdb->cnt_saveleaf); - wp += sprintf(wp, " cnt_loadleaf=%lld", (long long)bdb->cnt_loadleaf); - wp += sprintf(wp, " cnt_killleaf=%lld", (long long)bdb->cnt_killleaf); - wp += sprintf(wp, " cnt_adjleafc=%lld", (long long)bdb->cnt_adjleafc); - wp += sprintf(wp, " cnt_savenode=%lld", (long long)bdb->cnt_savenode); - wp += sprintf(wp, " cnt_loadnode=%lld", (long long)bdb->cnt_loadnode); - wp += sprintf(wp, " cnt_adjnodec=%lld", (long long)bdb->cnt_adjnodec); - *(wp++) = '\n'; - tcwrite(dbgfd, buf, wp - buf); -} - - -/* Print records of a leaf object into the debugging output. - `bdb' specifies the B+ tree database object. - `leaf' specifies the leaf object. */ -void tcbdbprintleaf(TCBDB *bdb, BDBLEAF *leaf){ - assert(bdb && leaf); - int dbgfd = tchdbdbgfd(bdb->hdb); - TCLIST *recs = leaf->recs; - if(dbgfd < 0) return; - char buf[BDBPAGEBUFSIZ]; - char *wp = buf; - wp += sprintf(wp, "LEAF:"); - wp += sprintf(wp, " id:%llx", (unsigned long long)leaf->id); - wp += sprintf(wp, " prev:%llx", (unsigned long long)leaf->prev); - wp += sprintf(wp, " next:%llx", (unsigned long long)leaf->next); - wp += sprintf(wp, " dirty:%d", leaf->dirty); - wp += sprintf(wp, " dead:%d", leaf->dead); - wp += sprintf(wp, " rnum:%d", TCLISTNUM(recs)); - *(wp++) = ' '; - for(int i = 0; i < TCLISTNUM(recs); i++){ - tcwrite(dbgfd, buf, wp - buf); - wp = buf; - BDBREC *recp = (BDBREC *)TCLISTVALPTR(recs, i); - wp += sprintf(wp, " [%s:%s]", recp->kbuf, recp->vbuf); - TCLIST *rest = recp->rest; - if(rest){ - for(int j = 0; j < TCLISTNUM(rest); j++){ - wp += sprintf(wp, ":%s", (char *)TCLISTVALPTR(rest, j)); - } - } - } - *(wp++) = '\n'; - tcwrite(dbgfd, buf, wp - buf); -} - - -/* Print indexes of a node object into the debugging output. - `bdb' specifies the B+ tree database object. - `node' specifies the node object. */ -void tcbdbprintnode(TCBDB *bdb, BDBNODE *node){ - assert(bdb && node); - int dbgfd = tchdbdbgfd(bdb->hdb); - TCLIST *idxs = node->idxs; - if(dbgfd < 0) return; - char buf[BDBPAGEBUFSIZ]; - char *wp = buf; - wp += sprintf(wp, "NODE:"); - wp += sprintf(wp, " id:%llx", (unsigned long long)node->id); - wp += sprintf(wp, " heir:%llx", (unsigned long long)node->heir); - wp += sprintf(wp, " dirty:%d", node->dirty); - wp += sprintf(wp, " rnum:%d", TCLISTNUM(idxs)); - *(wp++) = ' '; - for(int i = 0; i < TCLISTNUM(idxs); i++){ - tcwrite(dbgfd, buf, wp - buf); - wp = buf; - BDBIDX *idxp = (BDBIDX *)TCLISTVALPTR(idxs, i); - wp += sprintf(wp, " [%llx:%s]", (unsigned long long)idxp->pid, idxp->kbuf); - } - *(wp++) = '\n'; - tcwrite(dbgfd, buf, wp - buf); -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcbdb.h b/bacula/src/lib/tokyocabinet/tcbdb.h deleted file mode 100644 index e4da2e603a..0000000000 --- a/bacula/src/lib/tokyocabinet/tcbdb.h +++ /dev/null @@ -1,1027 +0,0 @@ -/************************************************************************************************* - * The B+ tree database API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#ifndef _TCBDB_H /* duplication check */ -#define _TCBDB_H - -#if defined(__cplusplus) -#define __TCBDB_CLINKAGEBEGIN extern "C" { -#define __TCBDB_CLINKAGEEND } -#else -#define __TCBDB_CLINKAGEBEGIN -#define __TCBDB_CLINKAGEEND -#endif -__TCBDB_CLINKAGEBEGIN - - -#include -#include -#include -#include -#include -#include - - - -/************************************************************************************************* - * API - *************************************************************************************************/ - - -/* type of the pointer to a comparison function. - `aptr' specifies the pointer to the region of one key. - `asiz' specifies the size of the region of one key. - `bptr' specifies the pointer to the region of the other key. - `bsiz' specifies the size of the region of the other key. - `op' specifies the pointer to the optional opaque object. - The return value is positive if the former is big, negative if the latter is big, 0 if both - are equivalent. */ -typedef int (*BDBCMP)(const char *aptr, int asiz, const char *bptr, int bsiz, void *op); - -typedef struct { /* type of structure for a B+ tree database */ - void *mmtx; /* mutex for method */ - void *cmtx; /* mutex for cache */ - void *tmtx; /* mutex for transaction */ - TCHDB *hdb; /* internal database object */ - char *opaque; /* opaque buffer */ - bool open; /* whether the internal database is opened */ - bool wmode; /* whether to be writable */ - uint32_t lmemb; /* number of members in each leaf */ - uint32_t nmemb; /* number of members in each node */ - uint8_t opts; /* options */ - uint64_t root; /* ID number of the root page */ - uint64_t first; /* ID number of the first leaf */ - uint64_t last; /* ID number of the last leaf */ - uint64_t lnum; /* number of leaves */ - uint64_t nnum; /* number of nodes */ - uint64_t rnum; /* number of records */ - TCMAP *leafc; /* cache for leaves */ - TCMAP *nodec; /* cache for nodes */ - BDBCMP cmp; /* pointer to the comparison function */ - void *cmpop; /* opaque object for the comparison function */ - uint32_t lcnum; /* max number of cached leaves */ - uint32_t ncnum; /* max number of cached nodes */ - uint32_t lsmax; /* max size of each leaf */ - uint32_t lschk; /* counter for leaf size checking */ - uint64_t capnum; /* capacity number of records */ - uint64_t *hist; /* history array of visited nodes */ - int hnum; /* number of element of the history array */ - uint64_t hleaf; /* ID number of the leaf referred by the history */ - uint64_t lleaf; /* ID number of the last visited leaf */ - bool tran; /* whether in the transaction */ - char *rbopaque; /* opaque for rollback */ - int64_t cnt_saveleaf; /* tesing counter for leaf save times */ - int64_t cnt_loadleaf; /* tesing counter for leaf load times */ - int64_t cnt_killleaf; /* tesing counter for leaf kill times */ - int64_t cnt_adjleafc; /* tesing counter for node cache adjust times */ - int64_t cnt_savenode; /* tesing counter for node save times */ - int64_t cnt_loadnode; /* tesing counter for node load times */ - int64_t cnt_adjnodec; /* tesing counter for node cache adjust times */ -} TCBDB; - -enum { /* enumeration for additional flags */ - BDBFOPEN = HDBFOPEN, /* whether opened */ - BDBFFATAL = HDBFFATAL /* whetehr with fatal error */ -}; - -enum { /* enumeration for tuning options */ - BDBTLARGE = 1 << 0, /* use 64-bit bucket array */ - BDBTDEFLATE = 1 << 1, /* compress each page with Deflate */ - BDBTTCBS = 1 << 2 /* compress each page with TCBS */ -}; - -enum { /* enumeration for open modes */ - BDBOREADER = 1 << 0, /* open as a reader */ - BDBOWRITER = 1 << 1, /* open as a writer */ - BDBOCREAT = 1 << 2, /* writer creating */ - BDBOTRUNC = 1 << 3, /* writer truncating */ - BDBONOLCK = 1 << 4, /* open without locking */ - BDBOLCKNB = 1 << 5 /* lock without blocking */ -}; - -typedef struct { /* type of structure for a B+ tree cursor */ - TCBDB *bdb; /* database object */ - uint64_t id; /* ID number of the leaf */ - int32_t kidx; /* number of the key */ - int32_t vidx; /* number of the value */ -} BDBCUR; - -enum { /* enumeration for cursor put mode */ - BDBCPCURRENT, /* current */ - BDBCPBEFORE, /* before */ - BDBCPAFTER /* after */ -}; - - -/* Get the message string corresponding to an error code. - `ecode' specifies the error code. - The return value is the message string of the error code. */ -const char *tcbdberrmsg(int ecode); - - -/* Create a B+ tree database object. - The return value is the new B+ tree database object. */ -TCBDB *tcbdbnew(void); - - -/* Delete a B+ tree database object. - `bdb' specifies the B+ tree database object. - If the database is not closed, it is closed implicitly. Note that the deleted object and its - derivatives can not be used anymore. */ -void tcbdbdel(TCBDB *bdb); - - -/* Get the last happened error code of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the last happened error code. - The following error code is defined: `TCESUCCESS' for success, `TCETHREAD' for threading - error, `TCEINVALID' for invalid operation, `TCENOFILE' for file not found, `TCENOPERM' for no - permission, `TCEMETA' for invalid meta data, `TCERHEAD' for invalid record header, `TCEOPEN' - for open error, `TCECLOSE' for close error, `TCETRUNC' for trunc error, `TCESYNC' for sync - error, `TCESTAT' for stat error, `TCESEEK' for seek error, `TCEREAD' for read error, - `TCEWRITE' for write error, `TCEMMAP' for mmap error, `TCELOCK' for lock error, `TCEUNLINK' - for unlink error, `TCERENAME' for rename error, `TCEMKDIR' for mkdir error, `TCERMDIR' for - rmdir error, `TCEKEEP' for existing record, `TCENOREC' for no record found, and `TCEMISC' for - miscellaneous error. */ -int tcbdbecode(TCBDB *bdb); - - -/* Set mutual exclusion control of a B+ tree database object for threading. - `bdb' specifies the B+ tree database object which is not opened. - If successful, the return value is true, else, it is false. - Note that the mutual exclusion control is needed if the object is shared by plural threads and - this function should should be called before the database is opened. */ -bool tcbdbsetmutex(TCBDB *bdb); - - -/* Set the custom comparison function of a B+ tree database object. - `bdb' specifies the B+ tree database object which is not opened. - `cmp' specifies the pointer to the custom comparison function. - `cmpop' specifies an arbitrary pointer to be given as a parameter of the comparison function. - If it is not needed, `NULL' can be specified. - If successful, the return value is true, else, it is false. - The default comparison function compares keys of two records by lexical order. The functions - `tcbdbcmplexical' (dafault), `tcbdbcmpdecimal', `tcbdbcmpint32', and `tcbdbcmpint64' are - built-in. Note that the comparison function should be set before the database is opened. - Moreover, user-defined comparison functions should be set every time the database is being - opened. */ -bool tcbdbsetcmpfunc(TCBDB *bdb, BDBCMP cmp, void *cmpop); - - -/* Set the tuning parameters of a B+ tree database object. - `bdb' specifies the B+ tree database object which is not opened. - `lmemb' specifies the number of members in each leaf page. If it is not more than 0, the - default value is specified. The default value is 128. - `nmemb' specifies the number of members in each non-leaf page. If it is not more than 0, the - default value is specified. The default value is 256. - `bnum' specifies the number of elements of the bucket array. If it is not more than 0, the - default value is specified. The default value is 16381. Suggested size of the bucket array - is about from 1 to 4 times of the number of all pages to be stored. - `apow' specifies the size of record alignment by power of 2. If it is negative, the default - value is specified. The default value is 8 standing for 2^8=256. - `fpow' specifies the maximum number of elements of the free block pool by power of 2. If it - is negative, the default value is specified. The default value is 10 standing for 2^10=1024. - `opts' specifies options by bitwise or: `BDBTLARGE' specifies that the size of the database - can be larger than 2GB by using 64-bit bucket array, `BDBTDEFLATE' specifies that each page - is compressed with Deflate encoding, `BDBTTCBS' specifies that each page is compressed with - TCBS encoding. - If successful, the return value is true, else, it is false. - Note that the tuning parameters should be set before the database is opened. */ -bool tcbdbtune(TCBDB *bdb, int32_t lmemb, int32_t nmemb, - int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts); - - -/* Set the caching parameters of a B+ tree database object. - `bdb' specifies the B+ tree database object which is not opened. - `lcnum' specifies the maximum number of leaf nodes to be cached. If it is not more than 0, - the default value is specified. The default value is 1024. - `ncnum' specifies the maximum number of non-leaf nodes to be cached. If it is not more than 0, - the default value is specified. The default value is 512. - If successful, the return value is true, else, it is false. - Note that the caching parameters should be set before the database is opened. */ -bool tcbdbsetcache(TCBDB *bdb, int32_t lcnum, int32_t ncnum); - - -/* Open a database file and connect a B+ tree database object. - `bdb' specifies the B+ tree database object which is not opened. - `path' specifies the path of the database file. - `omode' specifies the connection mode: `BDBOWRITER' as a writer, `BDBOREADER' as a reader. - If the mode is `BDBOWRITER', the following may be added by bitwise or: `BDBOCREAT', which - means it creates a new database if not exist, `BDBOTRUNC', which means it creates a new database - regardless if one exists. Both of `BDBOREADER' and `BDBOWRITER' can be added to by - bitwise or: `BDBONOLCK', which means it opens the database file without file locking, or - `BDBOLCKNB', which means locking is performed without blocking. - If successful, the return value is true, else, it is false. */ -bool tcbdbopen(TCBDB *bdb, const char *path, int omode); - - -/* Close a B+ tree database object. - `bdb' specifies the B+ tree database object. - If successful, the return value is true, else, it is false. - Update of a database is assured to be written when the database is closed. If a writer opens - a database but does not close it appropriately, the database will be broken. */ -bool tcbdbclose(TCBDB *bdb); - - -/* Store a record into a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, it is overwritten. */ -bool tcbdbput(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a string record into a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, it is overwritten. */ -bool tcbdbput2(TCBDB *bdb, const char *kstr, const char *vstr); - - -/* Store a new record into a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tcbdbputkeep(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a new string record into a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tcbdbputkeep2(TCBDB *bdb, const char *kstr, const char *vstr); - - -/* Concatenate a value at the end of the existing record in a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If there is no corresponding record, a new record is created. */ -bool tcbdbputcat(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Concatenate a string value at the end of the existing record in a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If there is no corresponding record, a new record is created. */ -bool tcbdbputcat2(TCBDB *bdb, const char *kstr, const char *vstr); - - -/* Store a record into a B+ tree database object with allowing duplication of keys. - `bdb' specifies the B+ tree database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, the new record is placed after the - existing one. */ -bool tcbdbputdup(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a string record into a B+ tree database object with allowing duplication of keys. - `bdb' specifies the B+ tree database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, the new record is placed after the - existing one. */ -bool tcbdbputdup2(TCBDB *bdb, const char *kstr, const char *vstr); - - -/* Store records into a B+ tree database object with allowing duplication of keys. - `bdb' specifies the B+ tree database object connected as a writer. - `kbuf' specifies the pointer to the region of the common key. - `ksiz' specifies the size of the region of the common key. - `vals' specifies a list object containing values. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, the new records are placed after the - existing one. */ -bool tcbdbputdup3(TCBDB *bdb, const void *kbuf, int ksiz, const TCLIST *vals); - - -/* Remove a record of a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. - If the key of duplicated records is specified, the first one is selected. */ -bool tcbdbout(TCBDB *bdb, const void *kbuf, int ksiz); - - -/* Remove a string record of a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kstr' specifies the string of the key. - If successful, the return value is true, else, it is false. - If the key of duplicated records is specified, the first one is selected. */ -bool tcbdbout2(TCBDB *bdb, const char *kstr); - - -/* Remove records of a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. - If the key of duplicated records is specified, all of them are removed. */ -bool tcbdbout3(TCBDB *bdb, const void *kbuf, int ksiz); - - -/* Retrieve a record in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the corresponding - record. `NULL' is returned if no record corresponds. - If the key of duplicated records is specified, the first one is selected. Because an - additional zero code is appended at the end of the region of the return value, the return - value can be treated as a character string. Because the region of the return value is - allocated with the `malloc' call, it should be released with the `free' call when it is no - longer in use. */ -void *tcbdbget(TCBDB *bdb, const void *kbuf, int ksiz, int *sp); - - -/* Retrieve a string record in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kstr' specifies the string of the key. - If successful, the return value is the string of the value of the corresponding record. - `NULL' is returned if no record corresponds. - If the key of duplicated records is specified, the first one is selected. Because the region - of the return value is allocated with the `malloc' call, it should be released with the `free' - call when it is no longer in use. */ -char *tcbdbget2(TCBDB *bdb, const char *kstr); - - -/* Retrieve a record in a B+ tree database object as a volatile buffer. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the corresponding - record. `NULL' is returned if no record corresponds. - If the key of duplicated records is specified, the first one is selected. Because an - additional zero code is appended at the end of the region of the return value, the return - value can be treated as a character string. Because the region of the return value is - volatile and it may be spoiled by another operation of the database, the data should be copied - into another involatile buffer immediately. */ -const void *tcbdbget3(TCBDB *bdb, const void *kbuf, int ksiz, int *sp); - - -/* Retrieve records in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is a list object of the values of the corresponding records. - `NULL' is returned if no record corresponds. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcbdbget4(TCBDB *bdb, const void *kbuf, int ksiz); - - -/* Get the number of records corresponding a key in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is the number of the corresponding records, else, it is 0. */ -int tcbdbvnum(TCBDB *bdb, const void *kbuf, int ksiz); - - -/* Get the number of records corresponding a string key in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kstr' specifies the string of the key. - If successful, the return value is the number of the corresponding records, else, it is 0. */ -int tcbdbvnum2(TCBDB *bdb, const char *kstr); - - -/* Get the size of the value of a record in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. - If the key of duplicated records is specified, the first one is selected. */ -int tcbdbvsiz(TCBDB *bdb, const void *kbuf, int ksiz); - - -/* Get the size of the value of a string record in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `kstr' specifies the string of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. - If the key of duplicated records is specified, the first one is selected. */ -int tcbdbvsiz2(TCBDB *bdb, const char *kstr); - - -/* Get keys of ranged records in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `bkbuf' specifies the pointer to the region of the key of the beginning border. If it is - `NULL', the first record is specified. - `bksiz' specifies the size of the region of the beginning key. - `binc' specifies whether the beginning border is inclusive or not. - `ekbuf' specifies the pointer to the region of the key of the ending border. If it is `NULL', - the last record is specified. - `eksiz' specifies the size of the region of the ending key. - `einc' specifies whether the ending border is inclusive or not. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the keys of the corresponding records. This function - does never fail and return an empty list even if no record corresponds. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcbdbrange(TCBDB *bdb, const void *bkbuf, int bksiz, bool binc, - const void *ekbuf, int eksiz, bool einc, int max); - - -/* Get string keys of ranged records in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `bkstr' specifies the string of the key of the beginning border. If it is `NULL', the first - record is specified. - `binc' specifies whether the beginning border is inclusive or not. - `ekstr' specifies the string of the key of the ending border. If it is `NULL', the last - record is specified. - `einc' specifies whether the ending border is inclusive or not. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the keys of the corresponding records. This function - does never fail and return an empty list even if no record corresponds. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcbdbrange2(TCBDB *bdb, const char *bkstr, bool binc, - const char *ekstr, bool einc, int max); - - -/* Get forward matching keys in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `pbuf' specifies the pointer to the region of the prefix. - `psiz' specifies the size of the region of the prefix. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the corresponding keys. This function does never fail - and return an empty list even if no key corresponds. - Because the object of the return value is created with the function `tclistnew', it should be - deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcbdbfwmkeys(TCBDB *bdb, const void *pbuf, int psiz, int max); - - -/* Get forward matching string keys in a B+ tree database object. - `bdb' specifies the B+ tree database object. - `pstr' specifies the string of the prefix. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the corresponding keys. This function does never fail - and return an empty list even if no key corresponds. - Because the object of the return value is created with the function `tclistnew', it should be - deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcbdbfwmkeys2(TCBDB *bdb, const char *pstr, int max); - - -/* Synchronize updated contents of a B+ tree database object with the file and the device. - `bdb' specifies the B+ tree database object connected as a writer. - If successful, the return value is true, else, it is false. - This function is useful when another process connects the same database file. */ -bool tcbdbsync(TCBDB *bdb); - - -/* Optimize the file of a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - `lmemb' specifies the number of members in each leaf page. If it is not more than 0, the - current setting is not changed. - `nmemb' specifies the number of members in each non-leaf page. If it is not more than 0, the - current setting is not changed. - `bnum' specifies the number of elements of the bucket array. If it is not more than 0, the - default value is specified. The default value is two times of the number of pages. - `apow' specifies the size of record alignment by power of 2. If it is negative, the current - setting is not changed. - `fpow' specifies the maximum number of elements of the free block pool by power of 2. If it - is negative, the current setting is not changed. - `opts' specifies options by bitwise or: `BDBTLARGE' specifies that the size of the database - can be larger than 2GB by using 64-bit bucket array, `BDBTDEFLATE' specifies that each record - is compressed with Deflate encoding, `BDBTTCBS' specifies that each page is compressed with - TCBS encoding. If it is `UINT8_MAX', the current setting is not changed. - If successful, the return value is true, else, it is false. - This function is useful to reduce the size of the database file with data fragmentation by - successive updating. */ -bool tcbdboptimize(TCBDB *bdb, int32_t lmemb, int32_t nmemb, - int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts); - - -/* Remove all records of a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - If successful, the return value is true, else, it is false. */ -bool tcbdbvanish(TCBDB *bdb); - - -/* Copy the database file of a B+ tree database object. - `bdb' specifies the B+ tree database object. - `path' specifies the path of the destination file. If it begins with `@', the trailing - substring is executed as a command line. - If successful, the return value is true, else, it is false. False is returned if the executed - command returns non-zero code. - The database file is assured to be kept synchronized and not modified while the copying or - executing operation is in progress. So, this function is useful to create a backup file of - the database file. */ -bool tcbdbcopy(TCBDB *bdb, const char *path); - - -/* Begin the transaction of a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - If successful, the return value is true, else, it is false. - The database is locked by the thread while the transaction so that only one transaction can be - activated with a database object at the same time. Thus, the serializable isolation level is - assumed if every database operation is performed in the transaction. If the database is - closed during transaction, the transaction is aborted implicitly. */ -bool tcbdbtranbegin(TCBDB *bdb); - - -/* Commit the transaction of a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - If successful, the return value is true, else, it is false. - Update in the transaction is fixed when it is committed successfully. */ -bool tcbdbtrancommit(TCBDB *bdb); - - -/* Abort the transaction of a B+ tree database object. - `bdb' specifies the B+ tree database object connected as a writer. - If successful, the return value is true, else, it is false. - Update in the transaction is discarded when it is aborted. The state of the database is - rollbacked to before transaction. */ -bool tcbdbtranabort(TCBDB *bdb); - - -/* Get the file path of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the path of the database file or `NULL' if the object does not connect to - any database file. */ -const char *tcbdbpath(TCBDB *bdb); - - -/* Get the number of records of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the number of records or 0 if the object does not connect to any database - file. */ -uint64_t tcbdbrnum(TCBDB *bdb); - - -/* Get the size of the database file of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the size of the database file or 0 if the object does not connect to any - database file. */ -uint64_t tcbdbfsiz(TCBDB *bdb); - - -/* Create a cursor object. - `bdb' specifies the B+ tree database object. - The return value is the new cursor object. - Note that the cursor is available only after initialization with the `tcbdbcurfirst' or the - `tcbdbcurjump' functions and so on. Moreover, the position of the cursor will be indefinite - when the database is updated after the initialization of the cursor. */ -BDBCUR *tcbdbcurnew(TCBDB *bdb); - - -/* Delete a cursor object. - `cur' specifies the cursor object. */ -void tcbdbcurdel(BDBCUR *cur); - - -/* Move a cursor object to the first record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. False is returned if there is - no record in the database. */ -bool tcbdbcurfirst(BDBCUR *cur); - - -/* Move a cursor object to the last record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. False is returned if there is - no record in the database. */ -bool tcbdbcurlast(BDBCUR *cur); - - -/* Move a cursor object to the front of records corresponding a key. - `cur' specifies the cursor object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. False is returned if there is - no record corresponding the condition. - The cursor is set to the first record corresponding the key or the next substitute if - completely matching record does not exist. */ -bool tcbdbcurjump(BDBCUR *cur, const void *kbuf, int ksiz); - - -/* Move a cursor object to the front of records corresponding a key string. - `cur' specifies the cursor object. - `kstr' specifies the string of the key. - If successful, the return value is true, else, it is false. False is returned if there is - no record corresponding the condition. - The cursor is set to the first record corresponding the key or the next substitute if - completely matching record does not exist. */ -bool tcbdbcurjump2(BDBCUR *cur, const char *kstr); - - -/* Move a cursor object to the previous record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. False is returned if there is - no previous record. */ -bool tcbdbcurprev(BDBCUR *cur); - - -/* Move a cursor object to the next record. - `cur' specifies the cursor object. - If successful, the return value is true, else, it is false. False is returned if there is - no next record. */ -bool tcbdbcurnext(BDBCUR *cur); - - -/* Insert a record around a cursor object. - `cur' specifies the cursor object of writer connection. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - `cpmode' specifies detail adjustment: `BDBCPCURRENT', which means that the value of the - current record is overwritten, `BDBCPBEFORE', which means that the new record is inserted - before the current record, `BDBCPAFTER', which means that the new record is inserted after the - current record. - If successful, the return value is true, else, it is false. False is returned when the cursor - is at invalid position. - After insertion, the cursor is moved to the inserted record. */ -bool tcbdbcurput(BDBCUR *cur, const void *vbuf, int vsiz, int cpmode); - - -/* Insert a string record around a cursor object. - `cur' specifies the cursor object of writer connection. - `vstr' specifies the string of the value. - `cpmode' specifies detail adjustment: `BDBCPCURRENT', which means that the value of the - current record is overwritten, `BDBCPBEFORE', which means that the new record is inserted - before the current record, `BDBCPAFTER', which means that the new record is inserted after the - current record. - If successful, the return value is true, else, it is false. False is returned when the cursor - is at invalid position. - After insertion, the cursor is moved to the inserted record. */ -bool tcbdbcurput2(BDBCUR *cur, const char *vstr, int cpmode); - - -/* Delete the record where a cursor object is. - `cur' specifies the cursor object of writer connection. - If successful, the return value is true, else, it is false. False is returned when the cursor - is at invalid position. - After deletion, the cursor is moved to the next record if possible. */ -bool tcbdbcurout(BDBCUR *cur); - - -/* Get the key of the record where the cursor object is. - `cur' specifies the cursor object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the key, else, it is `NULL'. - `NULL' is returned when the cursor is at invalid position. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -char *tcbdbcurkey(BDBCUR *cur, int *sp); - - -/* Get the key string of the record where the cursor object is. - `cur' specifies the cursor object. - If successful, the return value is the string of the key, else, it is `NULL'. `NULL' is - returned when the cursor is at invalid position. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcbdbcurkey2(BDBCUR *cur); - - -/* Get the key of the record where the cursor object is, as a volatile buffer. - `cur' specifies the cursor object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the key, else, it is `NULL'. - `NULL' is returned when the cursor is at invalid position. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return value - is volatile and it may be spoiled by another operation of the database, the data should be - copied into another involatile buffer immediately. */ -const char *tcbdbcurkey3(BDBCUR *cur, int *sp); - - -/* Get the value of the record where the cursor object is. - `cur' specifies the cursor object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value, else, it is `NULL'. - `NULL' is returned when the cursor is at invalid position. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -char *tcbdbcurval(BDBCUR *cur, int *sp); - - -/* Get the value string of the record where the cursor object is. - `cur' specifies the cursor object. - If successful, the return value is the string of the value, else, it is `NULL'. `NULL' is - returned when the cursor is at invalid position. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcbdbcurval2(BDBCUR *cur); - - -/* Get the value of the record where the cursor object is, as a volatile buffer. - `cur' specifies the cursor object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value, else, it is `NULL'. - `NULL' is returned when the cursor is at invalid position. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return value - is volatile and it may be spoiled by another operation of the database, the data should be - copied into another involatile buffer immediately. */ -const char *tcbdbcurval3(BDBCUR *cur, int *sp); - - -/* Get the key and the value of the record where the cursor object is. - `cur' specifies the cursor object. - `kxstr' specifies the object into which the key is wrote down. - `vxstr' specifies the object into which the value is wrote down. - If successful, the return value is true, else, it is false. False is returned when the cursor - is at invalid position. */ -bool tcbdbcurrec(BDBCUR *cur, TCXSTR *kxstr, TCXSTR *vxstr); - - - -/************************************************************************************************* - * features for experts - *************************************************************************************************/ - - -/* Set the error code of a B+ tree database object. - `bdb' specifies the B+ tree database object. - `ecode' specifies the error code. - `file' specifies the file name of the code. - `line' specifies the line number of the code. - `func' specifies the function name of the code. */ -void tcbdbsetecode(TCBDB *bdb, int ecode, const char *filename, int line, const char *func); - - -/* Set the file descriptor for debugging output. - `bdb' specifies the B+ tree database object. - `fd' specifies the file descriptor for debugging output. */ -void tcbdbsetdbgfd(TCBDB *bdb, int fd); - - -/* Get the file descriptor for debugging output. - `bdb' specifies the B+ tree database object. - The return value is the file descriptor for debugging output. */ -int tcbdbdbgfd(TCBDB *bdb); - - -/* Synchronize updating contents on memory. - `bdb' specifies the B+ tree database object connected as a writer. - `phys' specifies whether to synchronize physically. - If successful, the return value is true, else, it is false. */ -bool tcbdbmemsync(TCBDB *bdb, bool phys); - - -/* Get the comparison function of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the pointer to the comparison function. */ -BDBCMP tcbdbcmpfunc(TCBDB *bdb); - - -/* Get the opaque object for the comparison function of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the opaque object for the comparison function. */ -void *tcbdbcmpop(TCBDB *bdb); - - -/* Get the maximum number of cached leaf nodes of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the maximum number of cached leaf nodes. */ -uint32_t tcbdblmemb(TCBDB *bdb); - - -/* Get the maximum number of cached non-leaf nodes of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the maximum number of cached non-leaf nodes. */ -uint32_t tcbdbnmemb(TCBDB *bdb); - - -/* Get the number of the leaf nodes of B+ tree database object. - `bdb' specifies the B+ tree database object. - If successful, the return value is the number of the leaf nodes or 0 if the object does not - connect to any database file. */ -uint64_t tcbdblnum(TCBDB *bdb); - - -/* Get the number of the non-leaf nodes of B+ tree database object. - `bdb' specifies the B+ tree database object. - If successful, the return value is the number of the non-leaf nodes or 0 if the object does - not connect to any database file. */ -uint64_t tcbdbnnum(TCBDB *bdb); - - -/* Get the number of elements of the bucket array of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the number of elements of the bucket array or 0 if the object does not - connect to any database file. */ -uint64_t tcbdbbnum(TCBDB *bdb); - - -/* Get the record alignment of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the record alignment or 0 if the object does not connect to any database - file. */ -uint32_t tcbdbalign(TCBDB *bdb); - - -/* Get the maximum number of the free block pool of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the maximum number of the free block pool or 0 if the object does not - connect to any database file. */ -uint32_t tcbdbfbpmax(TCBDB *bdb); - - -/* Get the inode number of the database file of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the inode number of the database file or 0 the object does not connect to - any database file. */ -uint64_t tcbdbinode(TCBDB *bdb); - - -/* Get the modification time of the database file of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the inode number of the database file or 0 the object does not connect to - any database file. */ -time_t tcbdbmtime(TCBDB *bdb); - - -/* Get the additional flags of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the additional flags. */ -uint8_t tcbdbflags(TCBDB *bdb); - - -/* Get the options of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the options. */ -uint8_t tcbdbopts(TCBDB *bdb); - - -/* Get the pointer to the opaque field of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the pointer to the opaque field whose size is 128 bytes. */ -char *tcbdbopaque(TCBDB *bdb); - - -/* Get the number of used elements of the bucket array of a B+ tree database object. - `bdb' specifies the B+ tree database object. - The return value is the number of used elements of the bucket array or 0 if the object does not - connect to any database file. */ -uint64_t tcbdbbnumused(TCBDB *bdb); - - -/* Set the maximum size of each leaf node. - `bdb' specifies the B+ tree database object which is not opened. - `lsmax' specifies the maximum size of each leaf node. If it is not more than 0, the maximum - size is unlimited. - If successful, the return value is true, else, it is false. - Note that the tuning parameters of the database should be set before the database is opened. */ -bool tcbdbsetlsmax(TCBDB *bdb, uint32_t lsmax); - - -/* Set the capacity number of records. - `bdb' specifies the B+ tree database object which is not opened. - `capnum' specifies the capacity number of records. If it is not more than 0, the capacity is - unlimited. - If successful, the return value is true, else, it is false. - When the number of records exceeds the capacity, forehand records are removed implicitly. - Note that the tuning parameters of the database should be set before the database is opened. */ -bool tcbdbsetcapnum(TCBDB *bdb, uint64_t capnum); - - -/* Store a new record into a B+ tree database object with backward duplication. - `bdb' specifies the B+ tree database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, the new record is placed after the - existing one. */ -bool tcbdbputdupback(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a new string record into a B+ tree database object with backward duplication. - `bdb' specifies the B+ tree database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, the new record is placed after the - existing one. */ -bool tcbdbputdupback2(TCBDB *bdb, const char *kstr, const char *vstr); - - -/* Move a cursor object to the rear of records corresponding a key. - `cur' specifies the cursor object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. False is returned if there is - no record corresponding the condition. - The cursor is set to the last record corresponding the key or the previous substitute if - completely matching record does not exist. */ -bool tcbdbcurjumpback(BDBCUR *cur, const void *kbuf, int ksiz); - - -/* Move a cursor object to the rear of records corresponding a key string. - `cur' specifies the cursor object. - `kstr' specifies the string of the key. - If successful, the return value is true, else, it is false. False is returned if there is - no record corresponding the condition. - The cursor is set to the last record corresponding the key or the previous substitute if - completely matching record does not exist. */ -bool tcbdbcurjumpback2(BDBCUR *cur, const char *kstr); - - -/* Compare two keys by lexical order. - `aptr' specifies the pointer to the region of one key. - `asiz' specifies the size of the region of one key. - `bptr' specifies the pointer to the region of the other key. - `bsiz' specifies the size of the region of the other key. - `op' specifies the pointer to the optional opaque object. - The return value is positive if the former is big, negative if the latter is big, 0 if both - are equivalent. */ -int tcbdbcmplexical(const char *aptr, int asiz, const char *bptr, int bsiz, void *op); - - -/* Compare two keys as decimal strings of real numbers. - `aptr' specifies the pointer to the region of one key. - `asiz' specifies the size of the region of one key. - `bptr' specifies the pointer to the region of the other key. - `bsiz' specifies the size of the region of the other key. - `op' is ignored. - The return value is positive if the former is big, negative if the latter is big, 0 if both - are equivalent. */ -int tcbdbcmpdecimal(const char *aptr, int asiz, const char *bptr, int bsiz, void *op); - - -/* Compare two keys as 32-bit integers in the native byte order. - `aptr' specifies the pointer to the region of one key. - `asiz' specifies the size of the region of one key. - `bptr' specifies the pointer to the region of the other key. - `bsiz' specifies the size of the region of the other key. - `op' is ignored. - The return value is positive if the former is big, negative if the latter is big, 0 if both - are equivalent. */ -int tcbdbcmpint32(const char *aptr, int asiz, const char *bptr, int bsiz, void *op); - - -/* Compare two keys as 64-bit integers in the native byte order. - `aptr' specifies the pointer to the region of one key. - `asiz' specifies the size of the region of one key. - `bptr' specifies the pointer to the region of the other key. - `bsiz' specifies the size of the region of the other key. - `op' is ignored. - The return value is positive if the former is big, negative if the latter is big, 0 if both - are equivalent. */ -int tcbdbcmpint64(const char *aptr, int asiz, const char *bptr, int bsiz, void *op); - - -/* tricks for backward compatibility */ -#define tcbdbrange3 tcbdbfwmkeys2 - - - -__TCBDB_CLINKAGEEND -#endif /* duplication check */ - - -/* END OF FILE */ diff --git a/bacula/src/lib/tokyocabinet/tcbmgr.c b/bacula/src/lib/tokyocabinet/tcbmgr.c deleted file mode 100644 index 6cb796cb9e..0000000000 --- a/bacula/src/lib/tokyocabinet/tcbmgr.c +++ /dev/null @@ -1,977 +0,0 @@ -/************************************************************************************************* - * The command line utility of the B+ tree database API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include -#include "myconf.h" - - -/* global variables */ -const char *g_progname; // program name -int g_dbgfd; // debugging output - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void printerr(TCBDB *bdb); -static int printdata(const char *ptr, int size, bool px); -static char *hextoobj(const char *str, int *sp); -static char *mygetline(FILE *ifp); -static int mycmpfunc(const char *aptr, int asiz, const char *bptr, int bsiz, void *op); -static int runcreate(int argc, char **argv); -static int runinform(int argc, char **argv); -static int runput(int argc, char **argv); -static int runout(int argc, char **argv); -static int runget(int argc, char **argv); -static int runlist(int argc, char **argv); -static int runoptimize(int argc, char **argv); -static int runimporttsv(int argc, char **argv); -static int runversion(int argc, char **argv); -static int proccreate(const char *path, int lmemb, int nmemb, - int bnum, int apow, int fpow, BDBCMP cmp, int opts); -static int procinform(const char *path, int omode); -static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - BDBCMP cmp, int omode, int dmode); -static int procout(const char *path, const char *kbuf, int ksiz, BDBCMP cmp, int omode); -static int procget(const char *path, const char *kbuf, int ksiz, BDBCMP cmp, int omode, - bool px, bool pz); -static int proclist(const char *path, BDBCMP cmp, int omode, int max, bool pv, bool px, bool bk, - const char *jstr, const char *bstr, const char *estr, const char *fmstr); -static int procoptimize(const char *path, int lmemb, int nmemb, - int bnum, int apow, int fpow, BDBCMP cmp, int opts, int omode); -static int procimporttsv(const char *path, const char *file, int omode, bool sc); -static int procversion(void); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - g_dbgfd = -1; - const char *ebuf = getenv("TCDBGFD"); - if(ebuf) g_dbgfd = atoi(ebuf); - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "create")){ - rv = runcreate(argc, argv); - } else if(!strcmp(argv[1], "inform")){ - rv = runinform(argc, argv); - } else if(!strcmp(argv[1], "put")){ - rv = runput(argc, argv); - } else if(!strcmp(argv[1], "out")){ - rv = runout(argc, argv); - } else if(!strcmp(argv[1], "get")){ - rv = runget(argc, argv); - } else if(!strcmp(argv[1], "list")){ - rv = runlist(argc, argv); - } else if(!strcmp(argv[1], "optimize")){ - rv = runoptimize(argc, argv); - } else if(!strcmp(argv[1], "importtsv")){ - rv = runimporttsv(argc, argv); - } else if(!strcmp(argv[1], "version") || !strcmp(argv[1], "--version")){ - rv = runversion(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: the command line utility of the B+ tree database API\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s create [-cd|-ci|-cj] [-tl] [-td|-tb] path" - " [lmemb [nmemb [bnum [apow [fpow]]]]]\n", g_progname); - fprintf(stderr, " %s inform [-nl|-nb] path\n", g_progname); - fprintf(stderr, " %s put [-cd|-ci|-cj] [-nl|-nb] [-sx] [-dk|-dc|-dd|-db] path" - " key value\n", g_progname); - fprintf(stderr, " %s out [-cd|-ci|-cj] [-nl|-nb] [-sx] path key\n", g_progname); - fprintf(stderr, " %s get [-cd|-ci|-cj] [-nl|-nb] [-sx] [-px] [-pz] path key\n", g_progname); - fprintf(stderr, " %s list [-cd|-ci|-cj] [-nl|-nb] [-m num] [-bk] [-pv] [-px] [-j str]" - " [-rb bkey ekey] [-fm str] path\n", g_progname); - fprintf(stderr, " %s optimize [-cd|-ci|-cj] [-tl] [-td|-tb] [-tz] [-nl|-nb] path" - " [lmemb [nmemb [bnum [apow [fpow]]]]]\n", g_progname); - fprintf(stderr, " %s importtsv [-nl|-nb] [-sc] path [file]\n", g_progname); - fprintf(stderr, " %s version\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print error information */ -static void printerr(TCBDB *bdb){ - const char *path = tcbdbpath(bdb); - int ecode = tcbdbecode(bdb); - fprintf(stderr, "%s: %s: %d: %s\n", g_progname, path ? path : "-", ecode, tcbdberrmsg(ecode)); -} - - -/* print record data */ -static int printdata(const char *ptr, int size, bool px){ - int len = 0; - while(size-- > 0){ - if(px){ - if(len > 0) putchar(' '); - len += printf("%02X", *(unsigned char *)ptr); - } else { - putchar(*ptr); - len++; - } - ptr++; - } - return len; -} - - -/* create a binary object from a hexadecimal string */ -static char *hextoobj(const char *str, int *sp){ - int len = strlen(str); - char *buf = tcmalloc(len + 1); - int j = 0; - for(int i = 0; i < len; i += 2){ - while(strchr(" \n\r\t\f\v", str[i])){ - i++; - } - char mbuf[3]; - if((mbuf[0] = str[i]) == '\0') break; - if((mbuf[1] = str[i+1]) == '\0') break; - mbuf[2] = '\0'; - buf[j++] = (char)strtol(mbuf, NULL, 16); - } - buf[j] = '\0'; - *sp = j; - return buf; -} - - -/* read a line from a file descriptor */ -static char *mygetline(FILE *ifp){ - char *buf; - int c, len, blen; - buf = NULL; - len = 0; - blen = 256; - while((c = fgetc(ifp)) != EOF){ - if(blen <= len) blen *= 2; - buf = tcrealloc(buf, blen + 1); - if(c == '\n' || c == '\r') c = '\0'; - buf[len++] = c; - if(c == '\0') break; - } - if(!buf) return NULL; - buf[len] = '\0'; - return buf; -} - - -/* dummy comparison function */ -static int mycmpfunc(const char *aptr, int asiz, const char *bptr, int bsiz, void *op){ - return 0; -} - - -/* parse arguments of create command */ -static int runcreate(int argc, char **argv){ - char *path = NULL; - char *lmstr = NULL; - char *nmstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - BDBCMP cmp = NULL; - int opts = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!lmstr){ - lmstr = argv[i]; - } else if(!nmstr){ - nmstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int lmemb = lmstr ? atoi(lmstr) : -1; - int nmemb = nmstr ? atoi(nmstr) : -1; - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = proccreate(path, lmemb, nmemb, bnum, apow, fpow, cmp, opts); - return rv; -} - - -/* parse arguments of inform command */ -static int runinform(int argc, char **argv){ - char *path = NULL; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = procinform(path, omode); - return rv; -} - - -/* parse arguments of put command */ -static int runput(int argc, char **argv){ - char *path = NULL; - char *key = NULL; - char *value = NULL; - BDBCMP cmp = NULL; - int omode = 0; - int dmode = 0; - bool sx = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-dk")){ - dmode = -1; - } else if(!strcmp(argv[i], "-dc")){ - dmode = 1; - } else if(!strcmp(argv[i], "-dd")){ - dmode = 2; - } else if(!strcmp(argv[i], "-db")){ - dmode = 3; - } else if(!strcmp(argv[i], "-sx")){ - sx = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!key){ - key = argv[i]; - } else if(!value){ - value = argv[i]; - } else { - usage(); - } - } - if(!path || !key || !value) usage(); - int ksiz, vsiz; - char *kbuf, *vbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - vbuf = hextoobj(value, &vsiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - vsiz = strlen(value); - vbuf = tcmemdup(value, vsiz); - } - int rv = procput(path, kbuf, ksiz, vbuf, vsiz, cmp, omode, dmode); - free(vbuf); - free(kbuf); - return rv; -} - - -/* parse arguments of out command */ -static int runout(int argc, char **argv){ - char *path = NULL; - char *key = NULL; - BDBCMP cmp = NULL; - int omode = 0; - bool sx = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-sx")){ - sx = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!key){ - key = argv[i]; - } else { - usage(); - } - } - if(!path || !key) usage(); - int ksiz; - char *kbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - } - int rv = procout(path, kbuf, ksiz, cmp, omode); - free(kbuf); - return rv; -} - - -/* parse arguments of get command */ -static int runget(int argc, char **argv){ - char *path = NULL; - char *key = NULL; - BDBCMP cmp = NULL; - int omode = 0; - bool sx = false; - bool px = false; - bool pz = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-sx")){ - sx = true; - } else if(!strcmp(argv[i], "-px")){ - px = true; - } else if(!strcmp(argv[i], "-pz")){ - pz = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!key){ - key = argv[i]; - } else { - usage(); - } - } - if(!path || !key) usage(); - int ksiz; - char *kbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - } - int rv = procget(path, kbuf, ksiz, cmp, omode, px, pz); - free(kbuf); - return rv; -} - - -/* parse arguments of list command */ -static int runlist(int argc, char **argv){ - char *path = NULL; - BDBCMP cmp = NULL; - int omode = 0; - int max = -1; - bool pv = false; - bool px = false; - bool bk = false; - char *jstr = NULL; - char *bstr = NULL; - char *estr = NULL; - char *fmstr = NULL; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-m")){ - if(++i >= argc) usage(); - max = atoi(argv[i]); - } else if(!strcmp(argv[i], "-bk")){ - bk = true; - } else if(!strcmp(argv[i], "-pv")){ - pv = true; - } else if(!strcmp(argv[i], "-px")){ - px = true; - } else if(!strcmp(argv[i], "-j")){ - if(++i >= argc) usage(); - jstr = argv[i]; - } else if(!strcmp(argv[i], "-rb")){ - if(++i >= argc) usage(); - bstr = argv[i]; - if(++i >= argc) usage(); - estr = argv[i]; - } else if(!strcmp(argv[i], "-fm")){ - if(++i >= argc) usage(); - fmstr = argv[i]; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = proclist(path, cmp, omode, max, pv, px, bk, jstr, bstr, estr, fmstr); - return rv; -} - - -/* parse arguments of optimize command */ -static int runoptimize(int argc, char **argv){ - char *path = NULL; - char *lmstr = NULL; - char *nmstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - BDBCMP cmp = NULL; - int opts = UINT8_MAX; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-tl")){ - if(opts == UINT8_MAX) opts = 0; - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - if(opts == UINT8_MAX) opts = 0; - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - if(opts == UINT8_MAX) opts = 0; - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-tz")){ - if(opts == UINT8_MAX) opts = 0; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!lmstr){ - lmstr = argv[i]; - } else if(!nmstr){ - nmstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int lmemb = lmstr ? atoi(lmstr) : -1; - int nmemb = nmstr ? atoi(nmstr) : -1; - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procoptimize(path, lmemb, nmemb, bnum, apow, fpow, cmp, opts, omode); - return rv; -} - - -/* parse arguments of importtsv command */ -static int runimporttsv(int argc, char **argv){ - char *path = NULL; - char *file = NULL; - int omode = 0; - bool sc = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-sc")){ - sc = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!file){ - file = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = procimporttsv(path, file, omode, sc); - return rv; -} - - -/* parse arguments of version command */ -static int runversion(int argc, char **argv){ - int rv = procversion(); - return rv; -} - - -/* perform create command */ -static int proccreate(const char *path, int lmemb, int nmemb, - int bnum, int apow, int fpow, BDBCMP cmp, int opts){ - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb); - if(!tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - bool err = false; - if(!tcbdbclose(bdb)){ - printerr(bdb); - err = true; - } - tcbdbdel(bdb); - return err ? 1 : 0; -} - - -/* perform inform command */ -static int procinform(const char *path, int omode){ - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - tcbdbsetcmpfunc(bdb, mycmpfunc, NULL); - if(!tcbdbopen(bdb, path, BDBOREADER | omode)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - bool err = false; - const char *npath = tcbdbpath(bdb); - if(!npath) npath = "(unknown)"; - printf("path: %s\n", npath); - printf("database type: btree\n"); - uint8_t flags = tcbdbflags(bdb); - printf("additional flags:"); - if(flags & BDBFOPEN) printf(" open"); - if(flags & BDBFFATAL) printf(" fatal"); - printf("\n"); - BDBCMP cmp = tcbdbcmpfunc(bdb); - printf("comparison function: "); - if(cmp == tcbdbcmplexical){ - printf("lexical"); - } else if(cmp == tcbdbcmpdecimal){ - printf("decimal"); - } else if(cmp == tcbdbcmpint32){ - printf("int32"); - } else if(cmp == tcbdbcmpint64){ - printf("int64"); - } else { - printf("custom"); - } - printf("\n"); - printf("max leaf member: %d\n", tcbdblmemb(bdb)); - printf("max node member: %d\n", tcbdbnmemb(bdb)); - printf("leaf number: %llu\n", (unsigned long long)tcbdblnum(bdb)); - printf("node number: %llu\n", (unsigned long long)tcbdbnnum(bdb)); - printf("bucket number: %llu\n", (unsigned long long)tcbdbbnum(bdb)); - if(bdb->hdb->cnt_writerec >= 0) - printf("used bucket number: %lld\n", (long long)tcbdbbnumused(bdb)); - printf("alignment: %u\n", tcbdbalign(bdb)); - printf("free block pool: %u\n", tcbdbfbpmax(bdb)); - printf("inode number: %lld\n", (long long)tcbdbinode(bdb)); - char date[48]; - tcdatestrwww(tcbdbmtime(bdb), INT_MAX, date); - printf("modified time: %s\n", date); - uint8_t opts = tcbdbopts(bdb); - printf("options:"); - if(opts & BDBTLARGE) printf(" large"); - if(opts & BDBTDEFLATE) printf(" deflate"); - if(opts & BDBTTCBS) printf(" tcbs"); - printf("\n"); - printf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - printf("file size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - if(!tcbdbclose(bdb)){ - if(!err) printerr(bdb); - err = true; - } - tcbdbdel(bdb); - return err ? 1 : 0; -} - - -/* perform put command */ -static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - BDBCMP cmp, int omode, int dmode){ - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb); - if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - bool err = false; - switch(dmode){ - case -1: - if(!tcbdbputkeep(bdb, kbuf, ksiz, vbuf, vsiz)){ - printerr(bdb); - err = true; - } - break; - case 1: - if(!tcbdbputcat(bdb, kbuf, ksiz, vbuf, vsiz)){ - printerr(bdb); - err = true; - } - break; - case 2: - if(!tcbdbputdup(bdb, kbuf, ksiz, vbuf, vsiz)){ - printerr(bdb); - err = true; - } - break; - case 3: - if(!tcbdbputdupback(bdb, kbuf, ksiz, vbuf, vsiz)){ - printerr(bdb); - err = true; - } - break; - default: - if(!tcbdbput(bdb, kbuf, ksiz, vbuf, vsiz)){ - printerr(bdb); - err = true; - } - break; - } - if(!tcbdbclose(bdb)){ - if(!err) printerr(bdb); - err = true; - } - tcbdbdel(bdb); - return err ? 1 : 0; -} - - -/* perform out command */ -static int procout(const char *path, const char *kbuf, int ksiz, BDBCMP cmp, int omode){ - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb); - if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - bool err = false; - if(!tcbdbout(bdb, kbuf, ksiz)){ - printerr(bdb); - err = true; - } - if(!tcbdbclose(bdb)){ - if(!err) printerr(bdb); - err = true; - } - tcbdbdel(bdb); - return err ? 1 : 0; -} - - -/* perform get command */ -static int procget(const char *path, const char *kbuf, int ksiz, BDBCMP cmp, int omode, - bool px, bool pz){ - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb); - if(!tcbdbopen(bdb, path, BDBOREADER | omode)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - bool err = false; - int vsiz; - char *vbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz); - if(vbuf){ - printdata(vbuf, vsiz, px); - if(!pz) putchar('\n'); - free(vbuf); - } else { - printerr(bdb); - err = true; - } - if(!tcbdbclose(bdb)){ - if(!err) printerr(bdb); - err = true; - } - tcbdbdel(bdb); - return err ? 1 : 0; -} - - -/* perform list command */ -static int proclist(const char *path, BDBCMP cmp, int omode, int max, bool pv, bool px, bool bk, - const char *jstr, const char *bstr, const char *estr, const char *fmstr){ - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb); - if(!tcbdbopen(bdb, path, BDBOREADER | omode)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - bool err = false; - if(bstr || fmstr){ - TCLIST *keys = fmstr ? tcbdbfwmkeys2(bdb, fmstr, max) : - tcbdbrange(bdb, bstr, strlen(bstr), true, estr, strlen(estr), true, max); - int cnt = 0; - for(int i = 0; i < tclistnum(keys); i++){ - int ksiz; - const char *kbuf = tclistval(keys, i, &ksiz); - if(pv){ - TCLIST *vals = tcbdbget4(bdb, kbuf, ksiz); - if(vals){ - for(int j = 0; j < tclistnum(vals); j++){ - int vsiz; - const char *vbuf = tclistval(vals, j, &vsiz); - printdata(kbuf, ksiz, px); - putchar('\t'); - printdata(vbuf, vsiz, px); - putchar('\n'); - if(max >= 0 && ++cnt >= max) break; - } - tclistdel(vals); - } - } else { - int num = tcbdbvnum(bdb, kbuf, ksiz); - for(int j = 0; j < num; j++){ - printdata(kbuf, ksiz, px); - putchar('\n'); - if(max >= 0 && ++cnt >= max) break; - } - } - if(max >= 0 && cnt >= max) break; - } - tclistdel(keys); - } else { - BDBCUR *cur = tcbdbcurnew(bdb); - if(bk){ - if(jstr){ - if(!tcbdbcurjumpback(cur, jstr, strlen(jstr)) && tcbdbecode(bdb) != TCENOREC){ - printerr(bdb); - err = true; - } - } else { - if(!tcbdbcurlast(cur) && tcbdbecode(bdb) != TCENOREC){ - printerr(bdb); - err = true; - } - } - } else { - if(jstr){ - if(!tcbdbcurjump(cur, jstr, strlen(jstr)) && tcbdbecode(bdb) != TCENOREC){ - printerr(bdb); - err = true; - } - } else { - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - printerr(bdb); - err = true; - } - } - } - TCXSTR *key = tcxstrnew(); - TCXSTR *val = tcxstrnew(); - int cnt = 0; - while(tcbdbcurrec(cur, key, val)){ - printdata(tcxstrptr(key), tcxstrsize(key), px); - if(pv){ - putchar('\t'); - printdata(tcxstrptr(val), tcxstrsize(val), px); - } - putchar('\n'); - if(bk){ - if(!tcbdbcurprev(cur) && tcbdbecode(bdb) != TCENOREC){ - printerr(bdb); - err = true; - } - } else { - if(!tcbdbcurnext(cur) && tcbdbecode(bdb) != TCENOREC){ - printerr(bdb); - err = true; - } - } - if(max >= 0 && ++cnt >= max) break; - } - tcxstrdel(val); - tcxstrdel(key); - tcbdbcurdel(cur); - } - if(!tcbdbclose(bdb)){ - if(!err) printerr(bdb); - err = true; - } - tcbdbdel(bdb); - return err ? 1 : 0; -} - - -/* perform optimize command */ -static int procoptimize(const char *path, int lmemb, int nmemb, - int bnum, int apow, int fpow, BDBCMP cmp, int opts, int omode){ - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb); - if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - bool err = false; - if(!tcbdboptimize(bdb, lmemb, nmemb, bnum, apow, fpow, opts)){ - printerr(bdb); - err = true; - } - if(!tcbdbclose(bdb)){ - if(!err) printerr(bdb); - err = true; - } - tcbdbdel(bdb); - return err ? 1 : 0; -} - - -/* perform importtsv command */ -static int procimporttsv(const char *path, const char *file, int omode, bool sc){ - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - FILE *ifp = file ? fopen(file, "rb") : stdin; - if(!ifp){ - fprintf(stderr, "%s: could not open\n", file ? file : "(stdin)"); - tcbdbdel(bdb); - return 1; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | omode)){ - printerr(bdb); - tcbdbdel(bdb); - return 1; - } - bool err = false; - char *line; - int cnt = 0; - while(!err && (line = mygetline(ifp)) != NULL){ - char *pv = strchr(line, '\t'); - if(!pv) continue; - *pv = '\0'; - if(sc) tcstrtolower(line); - if(!tcbdbputdup2(bdb, line, pv + 1) && tcbdbecode(bdb) != TCEKEEP){ - printerr(bdb); - err = true; - } - free(line); - if(cnt > 0 && cnt % 100 == 0){ - putchar('.'); - fflush(stdout); - if(cnt % 5000 == 0) printf(" (%08d)\n", cnt); - } - cnt++; - } - printf(" (%08d)\n", cnt); - if(!tcbdbclose(bdb)){ - if(!err) printerr(bdb); - err = true; - } - tcbdbdel(bdb); - if(ifp != stdin) fclose(ifp); - return err ? 1 : 0; -} - - -/* perform version command */ -static int procversion(void){ - printf("Tokyo Cabinet version %s (%d:%s)\n", tcversion, _TC_LIBVER, _TC_FORMATVER); - printf("Copyright (C) 2006-2008 Mikio Hirabayashi\n"); - return 0; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcbmttest.c b/bacula/src/lib/tokyocabinet/tcbmttest.c deleted file mode 100644 index 5f8ae0112b..0000000000 --- a/bacula/src/lib/tokyocabinet/tcbmttest.c +++ /dev/null @@ -1,1325 +0,0 @@ -/************************************************************************************************* - * The test cases of the B+ tree database API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include -#include "myconf.h" - -#define RECBUFSIZ 32 // buffer for records - -typedef struct { // type of structure for write thread - TCBDB *bdb; - int rnum; - bool rnd; - int id; -} TARGWRITE; - -typedef struct { // type of structure for read thread - TCBDB *bdb; - int rnum; - bool wb; - bool rnd; - int id; -} TARGREAD; - -typedef struct { // type of structure for remove thread - TCBDB *bdb; - int rnum; - bool rnd; - int id; -} TARGREMOVE; - -typedef struct { // type of structure for wicked thread - TCBDB *bdb; - int rnum; - bool nc; - int id; - TCMAP *map; -} TARGWICKED; - -typedef struct { // type of structure for typical thread - TCBDB *bdb; - int rnum; - bool nc; - int rratio; - int id; -} TARGTYPICAL; - - -/* global variables */ -const char *g_progname; // program name -int g_dbgfd; // debugging output - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void iprintf(const char *format, ...); -static void eprint(TCBDB *bdb, const char *func); -static void mprint(TCBDB *bdb); -static int myrand(int range); -static int myrandnd(int range); -static int runwrite(int argc, char **argv); -static int runread(int argc, char **argv); -static int runremove(int argc, char **argv); -static int runwicked(int argc, char **argv); -static int runtypical(int argc, char **argv); -static int procwrite(const char *path, int tnum, int rnum, int lmemb, int nmemb, - int bnum, int apow, int fpow, int opts, int omode, bool rnd); -static int procread(const char *path, int tnum, int omode, bool wb, bool rnd); -static int procremove(const char *path, int tnum, int omode, bool rnd); -static int procwicked(const char *path, int tnum, int rnum, int opts, int omode, bool nc); -static int proctypical(const char *path, int tnum, int rnum, int lmemb, int nmemb, - int bnum, int apow, int fpow, int opts, int omode, bool nc, int rratio); -static void *threadwrite(void *targ); -static void *threadread(void *targ); -static void *threadremove(void *targ); -static void *threadwicked(void *targ); -static void *threadtypical(void *targ); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - g_dbgfd = -1; - const char *ebuf = getenv("TCDBGFD"); - if(ebuf) g_dbgfd = atoi(ebuf); - srand((unsigned int)(tctime() * 1000) % UINT_MAX); - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "write")){ - rv = runwrite(argc, argv); - } else if(!strcmp(argv[1], "read")){ - rv = runread(argc, argv); - } else if(!strcmp(argv[1], "remove")){ - rv = runremove(argc, argv); - } else if(!strcmp(argv[1], "wicked")){ - rv = runwicked(argc, argv); - } else if(!strcmp(argv[1], "typical")){ - rv = runtypical(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: test cases of the B+ tree database API of Tokyo Cabinet\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s write [-tl] [-td|-tb] [-nl|-nb] [-rnd] path tnum rnum" - " [lmemb [nmemb [bnum [apow [fpow]]]]]\n", g_progname); - fprintf(stderr, " %s read [-nl|-nb] [-wb] [-rnd] path tnum\n", g_progname); - fprintf(stderr, " %s remove [-nl|-nb] [-rnd] path tnum\n", g_progname); - fprintf(stderr, " %s wicked [-tl] [-td|-tb] [-nl|-nb] [-nc] path tnum rnum\n", - g_progname); - fprintf(stderr, " %s typical [-tl] [-td|-tb] [-nl|-nb] [-nc] [-rr] path tnum rnum" - " [lmemb [nmemb [bnum [apow [fpow]]]]]\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print formatted information string and flush the buffer */ -static void iprintf(const char *format, ...){ - va_list ap; - va_start(ap, format); - vprintf(format, ap); - fflush(stdout); - va_end(ap); -} - - -/* print error message of hash database */ -static void eprint(TCBDB *bdb, const char *func){ - const char *path = tcbdbpath(bdb); - int ecode = tcbdbecode(bdb); - fprintf(stderr, "%s: %s: %s: error: %d: %s\n", - g_progname, path ? path : "-", func, ecode, tcbdberrmsg(ecode)); -} - - -/* print members of hash database */ -static void mprint(TCBDB *bdb){ - if(bdb->hdb->cnt_writerec < 0) return; - iprintf("max leaf member: %d\n", tcbdblmemb(bdb)); - iprintf("max node member: %d\n", tcbdbnmemb(bdb)); - iprintf("leaf number: %d\n", tcbdblnum(bdb)); - iprintf("node number: %d\n", tcbdbnnum(bdb)); - iprintf("bucket number: %lld\n", (long long)tcbdbbnum(bdb)); - iprintf("used bucket number: %lld\n", (long long)tcbdbbnumused(bdb)); - iprintf("cnt_saveleaf: %lld\n", (long long)bdb->cnt_saveleaf); - iprintf("cnt_loadleaf: %lld\n", (long long)bdb->cnt_loadleaf); - iprintf("cnt_killleaf: %lld\n", (long long)bdb->cnt_killleaf); - iprintf("cnt_adjleafc: %lld\n", (long long)bdb->cnt_adjleafc); - iprintf("cnt_savenode: %lld\n", (long long)bdb->cnt_savenode); - iprintf("cnt_loadnode: %lld\n", (long long)bdb->cnt_loadnode); - iprintf("cnt_adjnodec: %lld\n", (long long)bdb->cnt_adjnodec); - iprintf("cnt_writerec: %lld\n", (long long)bdb->hdb->cnt_writerec); - iprintf("cnt_reuserec: %lld\n", (long long)bdb->hdb->cnt_reuserec); - iprintf("cnt_moverec: %lld\n", (long long)bdb->hdb->cnt_moverec); - iprintf("cnt_readrec: %lld\n", (long long)bdb->hdb->cnt_readrec); - iprintf("cnt_searchfbp: %lld\n", (long long)bdb->hdb->cnt_searchfbp); - iprintf("cnt_insertfbp: %lld\n", (long long)bdb->hdb->cnt_insertfbp); - iprintf("cnt_splicefbp: %lld\n", (long long)bdb->hdb->cnt_splicefbp); - iprintf("cnt_dividefbp: %lld\n", (long long)bdb->hdb->cnt_dividefbp); - iprintf("cnt_mergefbp: %lld\n", (long long)bdb->hdb->cnt_mergefbp); - iprintf("cnt_reducefbp: %lld\n", (long long)bdb->hdb->cnt_reducefbp); - iprintf("cnt_appenddrp: %lld\n", (long long)bdb->hdb->cnt_appenddrp); - iprintf("cnt_deferdrp: %lld\n", (long long)bdb->hdb->cnt_deferdrp); - iprintf("cnt_flushdrp: %lld\n", (long long)bdb->hdb->cnt_flushdrp); - iprintf("cnt_adjrecc: %lld\n", (long long)bdb->hdb->cnt_adjrecc); -} - - -/* get a random number */ -static int myrand(int range){ - return (int)((double)range * rand() / (RAND_MAX + 1.0)); -} - - -/* get a random number based on normal distribution */ -static int myrandnd(int range){ - int num = (int)tcdrandnd(range >> 1, range / 10); - return (num < 0 || num >= range) ? 0 : num; -} - - -/* parse arguments of write command */ -static int runwrite(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - char *rstr = NULL; - char *lmstr = NULL; - char *nmstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - int opts = 0; - int omode = 0; - bool rnd = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-rnd")){ - rnd = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!lmstr){ - lmstr = argv[i]; - } else if(!nmstr){ - nmstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr || !rstr) usage(); - int tnum = atoi(tstr); - int rnum = atoi(rstr); - if(tnum < 1 || rnum < 1) usage(); - int lmemb = lmstr ? atoi(lmstr) : -1; - int nmemb = nmstr ? atoi(nmstr) : -1; - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procwrite(path, tnum, rnum, lmemb, nmemb, bnum, apow, fpow, opts, omode, rnd); - return rv; -} - - -/* parse arguments of read command */ -static int runread(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - int omode = 0; - bool rnd = false; - bool wb = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-wb")){ - wb = true; - } else if(!strcmp(argv[i], "-rnd")){ - rnd = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr) usage(); - int tnum = atoi(tstr); - if(tnum < 1) usage(); - int rv = procread(path, tnum, omode, wb, rnd); - return rv; -} - - -/* parse arguments of remove command */ -static int runremove(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - int omode = 0; - bool rnd = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-rnd")){ - rnd = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr) usage(); - int tnum = atoi(tstr); - if(tnum < 1) usage(); - int rv = procremove(path, tnum, omode, rnd); - return rv; -} - - -/* parse arguments of wicked command */ -static int runwicked(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - char *rstr = NULL; - int opts = 0; - int omode = 0; - bool nc = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-nc")){ - nc = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr || !rstr) usage(); - int tnum = atoi(tstr); - int rnum = atoi(rstr); - if(tnum < 1 || rnum < 1) usage(); - int rv = procwicked(path, tnum, rnum, opts, omode, nc); - return rv; -} - - -/* parse arguments of typical command */ -static int runtypical(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - char *rstr = NULL; - char *lmstr = NULL; - char *nmstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - int opts = 0; - int omode = 0; - int rratio = -1; - bool nc = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-nc")){ - nc = true; - } else if(!strcmp(argv[i], "-rr")){ - if(++i >= argc) usage(); - rratio = atoi(argv[i]); - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!lmstr){ - lmstr = argv[i]; - } else if(!nmstr){ - nmstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr || !rstr) usage(); - int tnum = atoi(tstr); - int rnum = atoi(rstr); - if(tnum < 1 || rnum < 1) usage(); - int lmemb = lmstr ? atoi(lmstr) : -1; - int nmemb = nmstr ? atoi(nmstr) : -1; - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = proctypical(path, tnum, rnum, lmemb, nmemb, bnum, apow, fpow, opts, omode, nc, rratio); - return rv; -} - - -/* perform write command */ -static int procwrite(const char *path, int tnum, int rnum, int lmemb, int nmemb, - int bnum, int apow, int fpow, int opts, int omode, bool rnd){ - iprintf("\n path=%s tnum=%d rnum=%d lmemb=%d nmemb=%d" - " bnum=%d apow=%d fpow=%d opts=%d omode=%d rnd=%d\n\n", - path, tnum, rnum, lmemb, nmemb, bnum, apow, fpow, opts, omode, rnd); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(!tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(!tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts)){ - eprint(bdb, "tcbdbtune"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - TARGWRITE targs[tnum]; - pthread_t threads[tnum]; - if(tnum == 1){ - targs[0].bdb = bdb; - targs[0].rnum = rnum; - targs[0].rnd = rnd; - targs[0].id = 0; - if(threadwrite(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].bdb = bdb; - targs[i].rnum = rnum; - targs[i].rnd = rnd; - targs[i].id = i; - if(pthread_create(threads + i, NULL, threadwrite, targs + i) != 0){ - eprint(bdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(bdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform read command */ -static int procread(const char *path, int tnum, int omode, bool wb, bool rnd){ - iprintf("\n path=%s tnum=%d omode=%d wb=%d rnd=%d\n\n", - path, tnum, omode, wb, rnd); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(!tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOREADER | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - int rnum = tcbdbrnum(bdb) / tnum; - TARGREAD targs[tnum]; - pthread_t threads[tnum]; - if(tnum == 1){ - targs[0].bdb = bdb; - targs[0].rnum = rnum; - targs[0].wb = wb; - targs[0].rnd = rnd; - targs[0].id = 0; - if(threadread(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].bdb = bdb; - targs[i].rnum = rnum; - targs[i].wb = wb; - targs[i].rnd = rnd; - targs[i].id = i; - if(pthread_create(threads + i, NULL, threadread, targs + i) != 0){ - eprint(bdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(bdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform remove command */ -static int procremove(const char *path, int tnum, int omode, bool rnd){ - iprintf("\n path=%s tnum=%d omode=%d rnd=%d\n\n", path, tnum, omode, rnd); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(!tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - int rnum = tcbdbrnum(bdb) / tnum; - TARGREMOVE targs[tnum]; - pthread_t threads[tnum]; - if(tnum == 1){ - targs[0].bdb = bdb; - targs[0].rnum = rnum; - targs[0].rnd = rnd; - targs[0].id = 0; - if(threadremove(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].bdb = bdb; - targs[i].rnum = rnum; - targs[i].rnd = rnd; - targs[i].id = i; - if(pthread_create(threads + i, NULL, threadremove, targs + i) != 0){ - eprint(bdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(bdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform wicked command */ -static int procwicked(const char *path, int tnum, int rnum, int opts, int omode, bool nc){ - iprintf("\n path=%s tnum=%d rnum=%d opts=%d omode=%d nc=%d\n\n", - path, tnum, rnum, opts, omode, nc); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(!tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(!tcbdbtune(bdb, 10, 10, rnum / 50, 10, -1, opts)){ - eprint(bdb, "tcbdbtune"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - TARGWICKED targs[tnum]; - pthread_t threads[tnum]; - TCMAP *map = tcmapnew(); - if(tnum == 1){ - targs[0].bdb = bdb; - targs[0].rnum = rnum; - targs[0].nc = nc; - targs[0].id = 0; - targs[0].map = map; - if(threadwicked(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].bdb = bdb; - targs[i].rnum = rnum; - targs[i].nc = nc; - targs[i].id = i; - targs[i].map = map; - targs[i].map = map; - if(pthread_create(threads + i, NULL, threadwicked, targs + i) != 0){ - eprint(bdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(bdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - if(!nc){ - if(!tcbdbsync(bdb)){ - eprint(bdb, "tcbdbsync"); - err = true; - } - if(tcbdbrnum(bdb) != tcmaprnum(map)){ - eprint(bdb, "(validation)"); - err = true; - } - int end = rnum * tnum; - for(int i = 1; i <= end && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", i - 1); - int vsiz; - const char *vbuf = tcmapget(map, kbuf, ksiz, &vsiz); - int rsiz; - char *rbuf = tcbdbget(bdb, kbuf, ksiz, &rsiz); - if(vbuf){ - putchar('.'); - if(!rbuf){ - eprint(bdb, "tcbdbget"); - err = true; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(bdb, "(validation)"); - err = true; - } - } else { - putchar('*'); - if(rbuf || tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "(validation)"); - err = true; - } - } - free(rbuf); - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - } - tcmapdel(map); - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform typical command */ -static int proctypical(const char *path, int tnum, int rnum, int lmemb, int nmemb, - int bnum, int apow, int fpow, int opts, int omode, bool nc, int rratio){ - iprintf("\n path=%s tnum=%d rnum=%d lmemb=%d nmemb=%d" - " bnum=%d apow=%d fpow=%d opts=%d omode=%d nc=%d rratio=%d\n\n", - path, tnum, rnum, lmemb, nmemb, bnum, apow, fpow, opts, omode, nc, rratio); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(!tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(!tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts)){ - eprint(bdb, "tcbdbtune"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - TARGTYPICAL targs[tnum]; - pthread_t threads[tnum]; - if(tnum == 1){ - targs[0].bdb = bdb; - targs[0].rnum = rnum; - targs[0].nc = nc; - targs[0].rratio = rratio; - targs[0].id = 0; - if(threadtypical(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].bdb = bdb; - targs[i].rnum = rnum; - targs[i].nc = nc; - targs[i].rratio = rratio; - targs[i].id = i; - if(pthread_create(threads + i, NULL, threadtypical, targs + i) != 0){ - eprint(bdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(bdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* thread the write function */ -static void *threadwrite(void *targ){ - TCBDB *bdb = ((TARGWRITE *)targ)->bdb; - int rnum = ((TARGWRITE *)targ)->rnum; - bool rnd = ((TARGWRITE *)targ)->rnd; - int id = ((TARGWRITE *)targ)->id; - bool err = false; - int base = id * rnum; - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", base + (rnd ? myrand(i) : i)); - if(!tcbdbput(bdb, buf, len, buf, len)){ - eprint(bdb, "tcbdbput"); - err = true; - break; - } - if(id <= 0 && rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - return err ? "error" : NULL; -} - - -/* thread the read function */ -static void *threadread(void *targ){ - TCBDB *bdb = ((TARGREAD *)targ)->bdb; - int rnum = ((TARGREAD *)targ)->rnum; - bool wb = ((TARGREAD *)targ)->wb; - bool rnd = ((TARGREAD *)targ)->rnd; - int id = ((TARGREAD *)targ)->id; - bool err = false; - int base = id * rnum; - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", base + (rnd ? myrandnd(i) : i)); - int vsiz; - if(wb){ - int vsiz; - const char *vbuf = tcbdbget3(bdb, kbuf, ksiz, &vsiz); - if(!vbuf && (!rnd || tcbdbecode(bdb) != TCENOREC)){ - eprint(bdb, "tcbdbget3"); - err = true; - } - } else { - char *vbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz); - if(!vbuf && (!rnd || tcbdbecode(bdb) != TCENOREC)){ - eprint(bdb, "tcbdbget"); - err = true; - } - free(vbuf); - } - if(id == 0 && rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - return err ? "error" : NULL; -} - - -/* thread the remove function */ -static void *threadremove(void *targ){ - TCBDB *bdb = ((TARGREMOVE *)targ)->bdb; - int rnum = ((TARGREMOVE *)targ)->rnum; - bool rnd = ((TARGREMOVE *)targ)->rnd; - int id = ((TARGREMOVE *)targ)->id; - bool err = false; - int base = id * rnum; - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", base + (rnd ? myrand(i + 1) : i)); - if(!tcbdbout(bdb, kbuf, ksiz) && (!rnd || tcbdbecode(bdb) != TCENOREC)){ - eprint(bdb, "tcbdbout"); - err = true; - break; - } - if(id == 0 && rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - return err ? "error" : NULL; -} - - -/* thread the wicked function */ -static void *threadwicked(void *targ){ - TCBDB *bdb = ((TARGWICKED *)targ)->bdb; - int rnum = ((TARGWICKED *)targ)->rnum; - bool nc = ((TARGWICKED *)targ)->nc; - int id = ((TARGWICKED *)targ)->id; - TCMAP *map = ((TARGWICKED *)targ)->map; - BDBCUR *cur = tcbdbcurnew(bdb); - bool err = false; - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum * (id + 1))); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '*', vsiz); - vbuf[vsiz] = '\0'; - char *rbuf; - if(!nc) tcglobalmutexlock(); - switch(myrand(16)){ - case 0: - if(id == 0) putchar('0'); - if(!tcbdbput(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbput"); - err = true; - } - if(!nc) tcmapput(map, kbuf, ksiz, vbuf, vsiz); - break; - case 1: - if(id == 0) putchar('1'); - if(!tcbdbput2(bdb, kbuf, vbuf)){ - eprint(bdb, "tcbdbput2"); - err = true; - } - if(!nc) tcmapput2(map, kbuf, vbuf); - break; - case 2: - if(id == 0) putchar('2'); - if(!tcbdbputkeep(bdb, kbuf, ksiz, vbuf, vsiz) && tcbdbecode(bdb) != TCEKEEP){ - eprint(bdb, "tcbdbputkeep"); - err = true; - } - if(!nc) tcmapputkeep(map, kbuf, ksiz, vbuf, vsiz); - break; - case 3: - if(id == 0) putchar('3'); - if(!tcbdbputkeep2(bdb, kbuf, vbuf) && tcbdbecode(bdb) != TCEKEEP){ - eprint(bdb, "tcbdbputkeep2"); - err = true; - } - if(!nc) tcmapputkeep2(map, kbuf, vbuf); - break; - case 4: - if(id == 0) putchar('4'); - if(!tcbdbputcat(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputcat"); - err = true; - } - if(!nc) tcmapputcat(map, kbuf, ksiz, vbuf, vsiz); - break; - case 5: - if(id == 0) putchar('5'); - if(!tcbdbputcat2(bdb, kbuf, vbuf)){ - eprint(bdb, "tcbdbputcat2"); - err = true; - } - if(!nc) tcmapputcat2(map, kbuf, vbuf); - break; - case 6: - if(id == 0) putchar('6'); - if(nc){ - if(!tcbdbputdup(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputdup"); - err = true; - } - } - break; - case 7: - if(id == 0) putchar('7'); - if(nc){ - if(!tcbdbputdup2(bdb, kbuf, vbuf)){ - eprint(bdb, "tcbdbputdup2"); - err = true; - } - } - break; - case 8: - if(id == 0) putchar('8'); - if(myrand(10) == 0){ - if(!tcbdbout(bdb, kbuf, ksiz) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout"); - err = true; - } - if(!nc) tcmapout(map, kbuf, ksiz); - } - break; - case 9: - if(id == 0) putchar('9'); - if(myrand(10) == 0){ - if(!tcbdbout2(bdb, kbuf) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout2"); - err = true; - } - if(!nc) tcmapout2(map, kbuf); - } - break; - case 10: - if(id == 0) putchar('A'); - if(!(rbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz))){ - if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - rbuf = tcsprintf("[%d]", myrand(i + 1)); - vsiz = strlen(rbuf); - } - vsiz += myrand(vsiz); - if(myrand(3) == 0) vsiz += PATH_MAX; - rbuf = tcrealloc(rbuf, vsiz + 1); - for(int j = 0; j < vsiz; j++){ - rbuf[j] = myrand(0x100); - } - if(!tcbdbput(bdb, kbuf, ksiz, rbuf, vsiz)){ - eprint(bdb, "tcbdbput"); - err = true; - } - if(!nc) tcmapput(map, kbuf, ksiz, rbuf, vsiz); - free(rbuf); - break; - case 11: - if(id == 0) putchar('B'); - if(!(rbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz)) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - free(rbuf); - break; - case 12: - if(id == 0) putchar('C'); - if(!(rbuf = tcbdbget2(bdb, kbuf)) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - free(rbuf); - break; - case 13: - if(id == 0) putchar('D'); - if(!tcbdbget3(bdb, kbuf, ksiz, &vsiz) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - break; - case 14: - if(id == 0) putchar('E'); - if(myrand(rnum / 50) == 0){ - switch(myrand(5)){ - case 0: - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - break; - case 1: - if(!tcbdbcurlast(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - break; - default: - if(!tcbdbcurjump(cur, kbuf, ksiz) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurjump"); - err = true; - } - break; - } - } - TCXSTR *ikey = tcxstrnew(); - TCXSTR *ival = tcxstrnew(); - for(int j = myrand(rnum) / 1000 + 1; j >= 0; j--){ - if(j % 3 == 0){ - if(!tcbdbcurrec(cur, ikey, ival)){ - int ecode = tcbdbecode(bdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(bdb, "tcbdbcurrec"); - err = true; - } - } - } else { - int iksiz; - if(!tcbdbcurkey3(cur, &iksiz)){ - int ecode = tcbdbecode(bdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(bdb, "tcbdbcurkey3"); - err = true; - } - } - } - if(myrand(5) == 0){ - if(!tcbdbcurprev(cur)){ - int ecode = tcbdbecode(bdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(bdb, "tcbdbcurprev"); - err = true; - } - } - } else { - if(!tcbdbcurnext(cur)){ - int ecode = tcbdbecode(bdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(bdb, "tcbdbcurnext"); - err = true; - } - } - } - } - tcxstrdel(ival); - tcxstrdel(ikey); - break; - default: - if(id == 0) putchar('@'); - if(myrand(10000) == 0) srand((unsigned int)(tctime() * 1000) % UINT_MAX); - break; - } - if(!nc) tcglobalmutexunlock(); - if(id == 0){ - if(i % 50 == 0) iprintf(" (%08d)\n", i); - if(id == 0 && i == rnum / 4){ - if(!tcbdboptimize(bdb, -1, -1, -1, -1, -1, -1)){ - eprint(bdb, "tcbdboptimize"); - err = true; - } - if(!tcbdbcurfirst(cur)){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - } - } - } - tcbdbcurdel(cur); - return err ? "error" : NULL; -} - - -/* thread the typical function */ -static void *threadtypical(void *targ){ - TCBDB *bdb = ((TARGTYPICAL *)targ)->bdb; - int rnum = ((TARGTYPICAL *)targ)->rnum; - bool nc = ((TARGTYPICAL *)targ)->nc; - int rratio = ((TARGTYPICAL *)targ)->rratio; - int id = ((TARGTYPICAL *)targ)->id; - bool err = false; - TCMAP *map = (!nc && id == 0) ? tcmapnew2(rnum + 1) : NULL; - int base = id * rnum; - int mrange = tclmax(50 + rratio, 100); - BDBCUR *cur = tcbdbcurnew(bdb); - for(int i = 1; !err && i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", base + myrandnd(i)); - int rnd = myrand(mrange); - if(rnd < 10){ - if(!tcbdbput(bdb, buf, len, buf, len)){ - eprint(bdb, "tcbdbput"); - err = true; - } - if(map) tcmapput(map, buf, len, buf, len); - } else if(rnd < 15){ - if(!tcbdbputkeep(bdb, buf, len, buf, len) && tcbdbecode(bdb) != TCEKEEP){ - eprint(bdb, "tcbdbputkeep"); - err = true; - } - if(map) tcmapputkeep(map, buf, len, buf, len); - } else if(rnd < 20){ - if(!tcbdbputcat(bdb, buf, len, buf, len)){ - eprint(bdb, "tcbdbputcat"); - err = true; - } - if(map) tcmapputcat(map, buf, len, buf, len); - } else if(rnd < 25){ - if(!tcbdbout(bdb, buf, len) && tcbdbecode(bdb) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout"); - err = true; - } - if(map) tcmapout(map, buf, len); - } else if(rnd < 27){ - switch(myrand(3)){ - case 0: - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - for(int j = 0; !err && j < 10; j++){ - int ksiz; - char *kbuf = tcbdbcurkey(cur, &ksiz); - if(kbuf){ - int vsiz; - char *vbuf = tcbdbcurval(cur, &vsiz); - if(vbuf){ - free(vbuf); - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurval"); - err = true; - } - free(kbuf); - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurkey"); - err = true; - } - tcbdbcurnext(cur); - } - break; - case 1: - if(!tcbdbcurlast(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurlast"); - err = true; - } - for(int j = 0; !err && j < 10; j++){ - int ksiz; - char *kbuf = tcbdbcurkey(cur, &ksiz); - if(kbuf){ - int vsiz; - char *vbuf = tcbdbcurval(cur, &vsiz); - if(vbuf){ - free(vbuf); - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurval"); - err = true; - } - free(kbuf); - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurkey"); - err = true; - } - tcbdbcurprev(cur); - } - break; - case 2: - if(!tcbdbcurjump(cur, buf, len) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurjump"); - err = true; - } - for(int j = 0; !err && j < 10; j++){ - int ksiz; - char *kbuf = tcbdbcurkey(cur, &ksiz); - if(kbuf){ - int vsiz; - char *vbuf = tcbdbcurval(cur, &vsiz); - if(vbuf){ - free(vbuf); - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurval"); - err = true; - } - free(kbuf); - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurkey"); - err = true; - } - tcbdbcurnext(cur); - } - break; - } - } else { - int vsiz; - char *vbuf = tcbdbget(bdb, buf, len, &vsiz); - if(vbuf){ - if(map){ - int msiz; - const char *mbuf = tcmapget(map, buf, len, &msiz); - if(msiz != vsiz || memcmp(mbuf, vbuf, vsiz)){ - eprint(bdb, "(validation)"); - err = true; - } - } - free(vbuf); - } else { - if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - if(map && tcmapget(map, buf, len, &vsiz)){ - eprint(bdb, "(validation)"); - err = true; - } - } - } - if(id == 0 && rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - tcbdbcurdel(cur); - if(map){ - tcmapiterinit(map); - int ksiz; - const char *kbuf; - while(!err && (kbuf = tcmapiternext(map, &ksiz)) != NULL){ - int vsiz; - char *vbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz); - if(vbuf){ - int msiz; - const char *mbuf = tcmapget(map, kbuf, ksiz, &msiz); - if(!mbuf || msiz != vsiz || memcmp(mbuf, vbuf, vsiz)){ - eprint(bdb, "(validation)"); - err = true; - } - free(vbuf); - } else { - eprint(bdb, "(validation)"); - err = true; - } - } - tcmapdel(map); - } - return err ? "error" : NULL; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcbtest.c b/bacula/src/lib/tokyocabinet/tcbtest.c deleted file mode 100644 index dd31991ced..0000000000 --- a/bacula/src/lib/tokyocabinet/tcbtest.c +++ /dev/null @@ -1,2030 +0,0 @@ -/************************************************************************************************* - * The test cases of the B+ tree database API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include -#include "myconf.h" - -#define RECBUFSIZ 32 // buffer for records - - -/* global variables */ -const char *g_progname; // program name -int g_dbgfd; // debugging output - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void iprintf(const char *format, ...); -static void eprint(TCBDB *bdb, const char *func); -static void mprint(TCBDB *bdb); -static int myrand(int range); -static int runwrite(int argc, char **argv); -static int runread(int argc, char **argv); -static int runremove(int argc, char **argv); -static int runrcat(int argc, char **argv); -static int runqueue(int argc, char **argv); -static int runmisc(int argc, char **argv); -static int runwicked(int argc, char **argv); -static int procwrite(const char *path, int rnum, int lmemb, int nmemb, int bnum, - int apow, int fpow, bool mt, BDBCMP cmp, int opts, - int lcnum, int ncnum, int lsmax, int capnum, int omode); -static int procread(const char *path, bool mt, BDBCMP cmp, int lcnum, int ncnum, - int omode, bool wb); -static int procremove(const char *path, bool mt, BDBCMP cmp, int lcnum, int ncnum, int omode); -static int procrcat(const char *path, int rnum, - int lmemb, int nmemb, int bnum, int apow, int fpow, - bool mt, BDBCMP cmp, int opts, int lcnum, int ncnum, int lsmax, int capnum, - int omode, int pnum, bool rl); -static int procqueue(const char *path, int rnum, int lmemb, int nmemb, int bnum, - int apow, int fpow, bool mt, BDBCMP cmp, int opts, - int lcnum, int ncnum, int lsmax, int capnum, int omode); -static int procmisc(const char *path, int rnum, bool mt, int opts, int omode); -static int procwicked(const char *path, int rnum, bool mt, int opts, int omode); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - g_dbgfd = -1; - const char *ebuf = getenv("TCDBGFD"); - if(ebuf) g_dbgfd = atoi(ebuf); - srand((unsigned int)(tctime() * 1000) % UINT_MAX); - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "write")){ - rv = runwrite(argc, argv); - } else if(!strcmp(argv[1], "read")){ - rv = runread(argc, argv); - } else if(!strcmp(argv[1], "remove")){ - rv = runremove(argc, argv); - } else if(!strcmp(argv[1], "rcat")){ - rv = runrcat(argc, argv); - } else if(!strcmp(argv[1], "queue")){ - rv = runqueue(argc, argv); - } else if(!strcmp(argv[1], "misc")){ - rv = runmisc(argc, argv); - } else if(!strcmp(argv[1], "wicked")){ - rv = runwicked(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: test cases of the B+ tree database API of Tokyo Cabinet\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s write [-mt] [-cd|-ci|-cj] [-tl] [-td|-tb] [-lc num] [-nc num]" - " [-ls num] [-ca num] [-nl|-nb] path rnum [lmemb [nmemb [bnum [apow [fpow]]]]]\n", - g_progname); - fprintf(stderr, " %s read [-mt] [-cd|-ci|-cj] [-lc num] [-nc num] [-nl|-nb] [-wb]" - " path\n", g_progname); - fprintf(stderr, " %s remove [-mt] [-cd|-ci|-cj] [-lc num] [-nc num] [-nl|-nb]" - " path\n", g_progname); - fprintf(stderr, " %s rcat [-mt] [-cd|-ci|-cj] [-tl] [-td|-tb] [-lc num] [-nc num]" - " [-ls num] [-ca num] [-nl|-nb] [-pn num] [-rl] path rnum" - " [lmemb [nmemb [bnum [apow [fpow]]]]]\n", g_progname); - fprintf(stderr, " %s queue [-mt] [-cd|-ci|-cj] [-tl] [-td|-tb] [-lc num] [-nc num]" - " [-ls num] [-ca num] [-nl|-nb] path rnum [lmemb [nmemb [bnum [apow [fpow]]]]]\n", - g_progname); - fprintf(stderr, " %s misc [-mt] [-tl] [-td|-tb] [-nl|-nb] path rnum\n", g_progname); - fprintf(stderr, " %s wicked [-mt] [-tl] [-td|-tb] [-nl|-nb] path rnum\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print formatted information string and flush the buffer */ -static void iprintf(const char *format, ...){ - va_list ap; - va_start(ap, format); - vprintf(format, ap); - fflush(stdout); - va_end(ap); -} - - -/* print error message of hash database */ -static void eprint(TCBDB *bdb, const char *func){ - const char *path = tcbdbpath(bdb); - int ecode = tcbdbecode(bdb); - fprintf(stderr, "%s: %s: %s: error: %d: %s\n", - g_progname, path ? path : "-", func, ecode, tcbdberrmsg(ecode)); -} - - -/* print members of B+ tree database */ -static void mprint(TCBDB *bdb){ - if(bdb->hdb->cnt_writerec < 0) return; - iprintf("max leaf member: %d\n", tcbdblmemb(bdb)); - iprintf("max node member: %d\n", tcbdbnmemb(bdb)); - iprintf("leaf number: %d\n", tcbdblnum(bdb)); - iprintf("node number: %d\n", tcbdbnnum(bdb)); - iprintf("bucket number: %lld\n", (long long)tcbdbbnum(bdb)); - iprintf("used bucket number: %lld\n", (long long)tcbdbbnumused(bdb)); - iprintf("cnt_saveleaf: %lld\n", (long long)bdb->cnt_saveleaf); - iprintf("cnt_loadleaf: %lld\n", (long long)bdb->cnt_loadleaf); - iprintf("cnt_killleaf: %lld\n", (long long)bdb->cnt_killleaf); - iprintf("cnt_adjleafc: %lld\n", (long long)bdb->cnt_adjleafc); - iprintf("cnt_savenode: %lld\n", (long long)bdb->cnt_savenode); - iprintf("cnt_loadnode: %lld\n", (long long)bdb->cnt_loadnode); - iprintf("cnt_adjnodec: %lld\n", (long long)bdb->cnt_adjnodec); - iprintf("cnt_writerec: %lld\n", (long long)bdb->hdb->cnt_writerec); - iprintf("cnt_reuserec: %lld\n", (long long)bdb->hdb->cnt_reuserec); - iprintf("cnt_moverec: %lld\n", (long long)bdb->hdb->cnt_moverec); - iprintf("cnt_readrec: %lld\n", (long long)bdb->hdb->cnt_readrec); - iprintf("cnt_searchfbp: %lld\n", (long long)bdb->hdb->cnt_searchfbp); - iprintf("cnt_insertfbp: %lld\n", (long long)bdb->hdb->cnt_insertfbp); - iprintf("cnt_splicefbp: %lld\n", (long long)bdb->hdb->cnt_splicefbp); - iprintf("cnt_dividefbp: %lld\n", (long long)bdb->hdb->cnt_dividefbp); - iprintf("cnt_mergefbp: %lld\n", (long long)bdb->hdb->cnt_mergefbp); - iprintf("cnt_reducefbp: %lld\n", (long long)bdb->hdb->cnt_reducefbp); - iprintf("cnt_appenddrp: %lld\n", (long long)bdb->hdb->cnt_appenddrp); - iprintf("cnt_deferdrp: %lld\n", (long long)bdb->hdb->cnt_deferdrp); - iprintf("cnt_flushdrp: %lld\n", (long long)bdb->hdb->cnt_flushdrp); - iprintf("cnt_adjrecc: %lld\n", (long long)bdb->hdb->cnt_adjrecc); -} - - -/* get a random number */ -static int myrand(int range){ - return (int)((double)range * rand() / (RAND_MAX + 1.0)); -} - - -/* parse arguments of write command */ -static int runwrite(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - char *lmstr = NULL; - char *nmstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - bool mt = false; - BDBCMP cmp = NULL; - int opts = 0; - int lcnum = 0; - int ncnum = 0; - int lsmax = 0; - int capnum = 0; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-lc")){ - if(++i >= argc) usage(); - lcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nc")){ - if(++i >= argc) usage(); - ncnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-ls")){ - if(++i >= argc) usage(); - lsmax = atoi(argv[i]); - } else if(!strcmp(argv[i], "-ca")){ - if(++i >= argc) usage(); - capnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!lmstr){ - lmstr = argv[i]; - } else if(!nmstr){ - nmstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int lmemb = lmstr ? atoi(lmstr) : -1; - int nmemb = nmstr ? atoi(nmstr) : -1; - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procwrite(path, rnum, lmemb, nmemb, bnum, apow, fpow, - mt, cmp, opts, lcnum, ncnum, lsmax, capnum, omode); - return rv; -} - - -/* parse arguments of read command */ -static int runread(int argc, char **argv){ - char *path = NULL; - bool mt = false; - BDBCMP cmp = NULL; - int lcnum = 0; - int ncnum = 0; - int omode = 0; - bool wb = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-lc")){ - if(++i >= argc) usage(); - lcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nc")){ - if(++i >= argc) usage(); - ncnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-wb")){ - wb = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = procread(path, mt, cmp, lcnum, ncnum, omode, wb); - return rv; -} - - -/* parse arguments of remove command */ -static int runremove(int argc, char **argv){ - char *path = NULL; - bool mt = false; - BDBCMP cmp = NULL; - int lcnum = 0; - int ncnum = 0; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-lc")){ - if(++i >= argc) usage(); - lcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nc")){ - if(++i >= argc) usage(); - ncnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = procremove(path, mt, cmp, lcnum, ncnum, omode); - return rv; -} - - -/* parse arguments of rcat command */ -static int runrcat(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - char *lmstr = NULL; - char *nmstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - bool mt = false; - BDBCMP cmp = NULL; - int opts = 0; - int lcnum = 0; - int ncnum = 0; - int lsmax = 0; - int capnum = 0; - int omode = 0; - int pnum = 0; - bool rl = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-lc")){ - if(++i >= argc) usage(); - lcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nc")){ - if(++i >= argc) usage(); - ncnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-ls")){ - if(++i >= argc) usage(); - lsmax = atoi(argv[i]); - } else if(!strcmp(argv[i], "-ca")){ - if(++i >= argc) usage(); - capnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else if(!strcmp(argv[i], "-pn")){ - if(++i >= argc) usage(); - pnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-rl")){ - rl = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!lmstr){ - lmstr = argv[i]; - } else if(!nmstr){ - nmstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int lmemb = lmstr ? atoi(lmstr) : -1; - int nmemb = nmstr ? atoi(nmstr) : -1; - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procrcat(path, rnum, lmemb, nmemb, bnum, apow, fpow, mt, cmp, opts, - lcnum, ncnum, lsmax, capnum, omode, pnum, rl); - return rv; -} - - -/* parse arguments of queue command */ -static int runqueue(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - char *lmstr = NULL; - char *nmstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - bool mt = false; - BDBCMP cmp = NULL; - int opts = 0; - int lcnum = 0; - int ncnum = 0; - int lsmax = 0; - int capnum = 0; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-cd")){ - cmp = tcbdbcmpdecimal; - } else if(!strcmp(argv[i], "-ci")){ - cmp = tcbdbcmpint32; - } else if(!strcmp(argv[i], "-cj")){ - cmp = tcbdbcmpint64; - } else if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-lc")){ - if(++i >= argc) usage(); - lcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nc")){ - if(++i >= argc) usage(); - ncnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-ls")){ - if(++i >= argc) usage(); - lsmax = atoi(argv[i]); - } else if(!strcmp(argv[i], "-ca")){ - if(++i >= argc) usage(); - capnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!lmstr){ - lmstr = argv[i]; - } else if(!nmstr){ - nmstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int lmemb = lmstr ? atoi(lmstr) : -1; - int nmemb = nmstr ? atoi(nmstr) : -1; - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procqueue(path, rnum, lmemb, nmemb, bnum, apow, fpow, - mt, cmp, opts, lcnum, ncnum, lsmax, capnum, omode); - return rv; -} - - -/* parse arguments of misc command */ -static int runmisc(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - bool mt = false; - int opts = 0; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int rv = procmisc(path, rnum, mt, opts, omode); - return rv; -} - - -/* parse arguments of wicked command */ -static int runwicked(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - bool mt = false; - int opts = 0; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-tl")){ - opts |= BDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= BDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= BDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= BDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= BDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int rv = procwicked(path, rnum, mt, opts, omode); - return rv; -} - - -/* perform write command */ -static int procwrite(const char *path, int rnum, int lmemb, int nmemb, int bnum, - int apow, int fpow, bool mt, BDBCMP cmp, int opts, - int lcnum, int ncnum, int lsmax, int capnum, int omode){ - iprintf("\n path=%s rnum=%d lmemb=%d nmemb=%d bnum=%d apow=%d fpow=%d" - " mt=%d cmp=%p opts=%d lcnum=%d ncnum=%d lsmax=%d capnum=%d omode=%d\n\n", - path, rnum, lmemb, nmemb, bnum, apow, fpow, mt, (void *)(intptr_t)cmp, - opts, lcnum, ncnum, lsmax, capnum, omode); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(mt && !tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)){ - eprint(bdb, "tcbdbsetcmpfunc"); - err = true; - } - if(!tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts)){ - eprint(bdb, "tcbdbtune"); - err = true; - } - if(!tcbdbsetcache(bdb, lcnum, ncnum)){ - eprint(bdb, "tcbdbsetcache"); - err = true; - } - if(!tcbdbsetlsmax(bdb, lsmax)){ - eprint(bdb, "tcbdbsetlsmax"); - err = true; - } - if(!tcbdbsetcapnum(bdb, capnum)){ - eprint(bdb, "tcbdbsetcapnum"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len; - if(cmp == tcbdbcmpdecimal){ - len = sprintf(buf, "%d", i); - } else if(cmp == tcbdbcmpint32){ - int32_t lnum = i; - memcpy(buf, &lnum, sizeof(lnum)); - len = sizeof(lnum); - } else if(cmp == tcbdbcmpint64){ - int64_t llnum = i; - memcpy(buf, &llnum, sizeof(llnum)); - len = sizeof(llnum); - } else { - len = sprintf(buf, "%08d", i); - } - if(!tcbdbput(bdb, buf, len, buf, len)){ - eprint(bdb, "tcbdbput"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform read command */ -static int procread(const char *path, bool mt, BDBCMP cmp, int lcnum, int ncnum, - int omode, bool wb){ - iprintf("\n path=%s mt=%d cmp=%p lcnum=%d ncnum=%d omode=%d wb=%d\n", - path, mt, (void *)(intptr_t)cmp, lcnum, ncnum, omode, wb); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(mt && !tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)){ - eprint(bdb, "tcbdbsetcmpfunc"); - err = true; - } - if(!tcbdbsetcache(bdb, lcnum, ncnum)){ - eprint(bdb, "tcbdbsetcache"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOREADER | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - int rnum = tcbdbrnum(bdb); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz; - if(cmp == tcbdbcmpdecimal){ - ksiz = sprintf(kbuf, "%d", i); - } else if(cmp == tcbdbcmpint32){ - int32_t lnum = i; - memcpy(kbuf, &lnum, sizeof(lnum)); - ksiz = sizeof(lnum); - } else if(cmp == tcbdbcmpint64){ - int64_t llnum = i; - memcpy(kbuf, &llnum, sizeof(llnum)); - ksiz = sizeof(llnum); - } else { - ksiz = sprintf(kbuf, "%08d", i); - } - int vsiz; - if(wb){ - int vsiz; - const char *vbuf = tcbdbget3(bdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(bdb, "tcbdbget3"); - err = true; - break; - } - } else { - char *vbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(bdb, "tcbdbget"); - err = true; - break; - } - free(vbuf); - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform remove command */ -static int procremove(const char *path, bool mt, BDBCMP cmp, int lcnum, int ncnum, int omode){ - iprintf("\n path=%s mt=%d cmp=%p lcnum=%d ncnum=%d omode=%d\n", - path, mt, (void *)(intptr_t)cmp, lcnum, ncnum, omode); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(mt && !tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)){ - eprint(bdb, "tcbdbsetcmpfunc"); - err = true; - } - if(!tcbdbsetcache(bdb, lcnum, ncnum)){ - eprint(bdb, "tcbdbsetcache"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - int rnum = tcbdbrnum(bdb); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz; - if(cmp == tcbdbcmpdecimal){ - ksiz = sprintf(kbuf, "%d", i); - } else if(cmp == tcbdbcmpint32){ - int32_t lnum = i; - memcpy(kbuf, &lnum, sizeof(lnum)); - ksiz = sizeof(lnum); - } else if(cmp == tcbdbcmpint64){ - int64_t llnum = i; - memcpy(kbuf, &llnum, sizeof(llnum)); - ksiz = sizeof(llnum); - } else { - ksiz = sprintf(kbuf, "%08d", i); - } - if(!tcbdbout(bdb, kbuf, ksiz)){ - eprint(bdb, "tcbdbout"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform rcat command */ -static int procrcat(const char *path, int rnum, - int lmemb, int nmemb, int bnum, int apow, int fpow, - bool mt, BDBCMP cmp, int opts, int lcnum, int ncnum, int lsmax, int capnum, - int omode, int pnum, bool rl){ - iprintf("\n" - " path=%s rnum=%d lmemb=%d nmemb=%d bnum=%d apow=%d fpow=%d" - " mt=%d cmp=%p opts=%d lcnum=%d ncnum=%d lsmax=%d capnum=%d" - " omode=%d pnum=%d rl=%d\n\n", - path, rnum, lmemb, nmemb, bnum, apow, fpow, mt, (void *)(intptr_t)cmp, - opts, lcnum, ncnum, lsmax, capnum, omode, pnum, rl); - if(pnum < 1) pnum = rnum; - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(mt && !tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(!tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts)){ - eprint(bdb, "tcbdbtune"); - err = true; - } - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)){ - eprint(bdb, "tcbdbsetcmpfunc"); - err = true; - } - if(!tcbdbsetcache(bdb, lcnum, ncnum)){ - eprint(bdb, "tcbdbsetcache"); - err = true; - } - if(!tcbdbsetlsmax(bdb, lsmax)){ - eprint(bdb, "tcbdbsetlsmax"); - err = true; - } - if(!tcbdbsetcapnum(bdb, capnum)){ - eprint(bdb, "tcbdbsetcapnum"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz; - if(cmp == tcbdbcmpdecimal){ - ksiz = sprintf(kbuf, "%d", myrand(pnum)); - } else if(cmp == tcbdbcmpint32){ - int32_t lnum = myrand(pnum); - memcpy(kbuf, &lnum, sizeof(lnum)); - ksiz = sizeof(lnum); - } else if(cmp == tcbdbcmpint64){ - int64_t llnum = myrand(pnum); - memcpy(kbuf, &llnum, sizeof(llnum)); - ksiz = sizeof(llnum); - } else { - ksiz = sprintf(kbuf, "%08d", myrand(pnum)); - } - if(rl){ - char vbuf[PATH_MAX]; - int vsiz = myrand(PATH_MAX); - for(int j = 0; j < vsiz; j++){ - vbuf[j] = myrand(0x100); - } - if(!tcbdbputcat(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputcat"); - err = true; - break; - } - } else { - if(!tcbdbputcat(bdb, kbuf, ksiz, kbuf, ksiz)){ - eprint(bdb, "tcbdbputcat"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform queue command */ -static int procqueue(const char *path, int rnum, int lmemb, int nmemb, int bnum, - int apow, int fpow, bool mt, BDBCMP cmp, int opts, - int lcnum, int ncnum, int lsmax, int capnum, int omode){ - iprintf("\n path=%s rnum=%d lmemb=%d nmemb=%d bnum=%d apow=%d fpow=%d" - " mt=%d cmp=%p opts=%d lcnum=%d ncnum=%d lsmax=%d capnum=%d omode=%d\n\n", - path, rnum, lmemb, nmemb, bnum, apow, fpow, mt, (void *)(intptr_t)cmp, - opts, lcnum, ncnum, lsmax, capnum, omode); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(mt && !tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)){ - eprint(bdb, "tcbdbsetcmpfunc"); - err = true; - } - if(!tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts)){ - eprint(bdb, "tcbdbtune"); - err = true; - } - if(!tcbdbsetcache(bdb, lcnum, ncnum)){ - eprint(bdb, "tcbdbsetcache"); - err = true; - } - if(!tcbdbsetlsmax(bdb, lsmax)){ - eprint(bdb, "tcbdbsetlsmax"); - err = true; - } - if(!tcbdbsetcapnum(bdb, capnum)){ - eprint(bdb, "tcbdbsetcapnum"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - int deqfreq = (lmemb > 0) ? lmemb * 2 : 256; - BDBCUR *cur = tcbdbcurnew(bdb); - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len; - if(cmp == tcbdbcmpdecimal){ - len = sprintf(buf, "%d", i); - } else if(cmp == tcbdbcmpint32){ - int32_t lnum = i; - memcpy(buf, &lnum, sizeof(lnum)); - len = sizeof(lnum); - } else if(cmp == tcbdbcmpint64){ - int64_t llnum = i; - memcpy(buf, &llnum, sizeof(llnum)); - len = sizeof(llnum); - } else { - len = sprintf(buf, "%08d", i); - } - if(!tcbdbput(bdb, buf, len, buf, len)){ - eprint(bdb, "tcbdbput"); - err = true; - break; - } - if(myrand(deqfreq) == 0){ - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - break; - } - int num = myrand(deqfreq * 2 + 1); - while(num >= 0){ - if(tcbdbcurout(cur)){ - num--; - } else { - if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurout"); - err = true; - } - break; - } - } - if(err) break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - while(true){ - if(tcbdbcurout(cur)) continue; - if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurout"); - err = true; - } - break; - } - tcbdbcurdel(cur); - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform misc command */ -static int procmisc(const char *path, int rnum, bool mt, int opts, int omode){ - iprintf("\n path=%s rnum=%d mt=%d opts=%d omode=%d\n\n", - path, rnum, mt, opts, omode); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(mt && !tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(!tcbdbtune(bdb, 10, 10, rnum / 50, 100, -1, opts)){ - eprint(bdb, "tcbdbtune"); - err = true; - } - if(!tcbdbsetcache(bdb, 128, 256)){ - eprint(bdb, "tcbdbsetcache"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - iprintf("writing:\n"); - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", i); - if(!tcbdbputkeep(bdb, buf, len, buf, len)){ - eprint(bdb, "tcbdbputkeep"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("reading:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - int vsiz; - char *vbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(bdb, "tcbdbget"); - err = true; - break; - } else if(vsiz != ksiz || memcmp(vbuf, kbuf, vsiz)){ - eprint(bdb, "(validation)"); - err = true; - free(vbuf); - break; - } - free(vbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(tcbdbrnum(bdb) != rnum){ - eprint(bdb, "(validation)"); - err = true; - } - iprintf("random writing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '*', vsiz); - if(!tcbdbput(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbput"); - err = true; - break; - } - int rsiz; - char *rbuf = tcbdbget(bdb, kbuf, ksiz, &rsiz); - if(!rbuf){ - eprint(bdb, "tcbdbget"); - err = true; - break; - } - if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(bdb, "(validation)"); - err = true; - free(rbuf); - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - free(rbuf); - } - iprintf("word writing:\n"); - const char *words[] = { - "a", "A", "bb", "BB", "ccc", "CCC", "dddd", "DDDD", "eeeee", "EEEEEE", - "mikio", "hirabayashi", "tokyo", "cabinet", "hyper", "estraier", "19780211", "birth day", - "one", "first", "two", "second", "three", "third", "four", "fourth", "five", "fifth", - "_[1]_", "uno", "_[2]_", "dos", "_[3]_", "tres", "_[4]_", "cuatro", "_[5]_", "cinco", - "[\xe5\xb9\xb3\xe6\x9e\x97\xe5\xb9\xb9\xe9\x9b\x84]", "[\xe9\xa6\xac\xe9\xb9\xbf]", NULL - }; - for(int i = 0; words[i] != NULL; i += 2){ - const char *kbuf = words[i]; - int ksiz = strlen(kbuf); - const char *vbuf = words[i+1]; - int vsiz = strlen(vbuf); - if(!tcbdbputkeep(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputkeep"); - err = true; - break; - } - if(rnum > 250) putchar('.'); - } - if(rnum > 250) iprintf(" (%08d)\n", sizeof(words) / sizeof(*words)); - iprintf("random erasing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - if(!tcbdbout(bdb, kbuf, ksiz) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("writing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "[%d]", i); - char vbuf[RECBUFSIZ]; - int vsiz = i % RECBUFSIZ; - memset(vbuf, '*', vsiz); - if(!tcbdbputkeep(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputkeep"); - err = true; - break; - } - if(vsiz < 1){ - char tbuf[PATH_MAX]; - for(int j = 0; j < PATH_MAX; j++){ - tbuf[j] = myrand(0x100); - } - if(!tcbdbput(bdb, kbuf, ksiz, tbuf, PATH_MAX)){ - eprint(bdb, "tcbdbput"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("erasing:\n"); - for(int i = 1; i <= rnum; i++){ - if(i % 2 == 1){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "[%d]", i); - if(!tcbdbout(bdb, kbuf, ksiz)){ - eprint(bdb, "tcbdbout"); - err = true; - break; - } - if(tcbdbout(bdb, kbuf, ksiz) || tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("random writing and reopening:\n"); - for(int i = 1; i <= rnum; i++){ - if(myrand(10) == 0){ - int ksiz, vsiz; - char *kbuf, *vbuf; - ksiz = (myrand(5) == 0) ? myrand(UINT16_MAX) : myrand(RECBUFSIZ); - kbuf = tcmalloc(ksiz + 1); - for(int j = 0; j < ksiz; j++){ - kbuf[j] = 128 + myrand(128); - } - vsiz = (myrand(5) == 0) ? myrand(UINT16_MAX) : myrand(RECBUFSIZ); - vbuf = tcmalloc(vsiz + 1); - for(int j = 0; j < vsiz; j++){ - vbuf[j] = myrand(256); - } - switch(myrand(5)){ - case 0: - if(!tcbdbput(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbput"); - err = true; - } - break; - case 1: - if(!tcbdbputcat(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputcat"); - err = true; - } - break; - case 2: - if(!tcbdbputdup(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputdup"); - err = true; - } - break; - case 3: - if(!tcbdbputdupback(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputdupback"); - err = true; - } - break; - default: - if(!tcbdbout(bdb, kbuf, ksiz) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout"); - err = true; - } - break; - } - free(vbuf); - free(kbuf); - } else { - char kbuf[RECBUFSIZ]; - int ksiz = myrand(RECBUFSIZ); - memset(kbuf, '@', ksiz); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '@', vsiz); - if(!tcbdbput(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputcat"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - iprintf("checking:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "[%d]", i); - int vsiz; - char *vbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz); - if(i % 2 == 0){ - if(!vbuf){ - eprint(bdb, "tcbdbget"); - err = true; - break; - } - if(vsiz != i % RECBUFSIZ && vsiz != PATH_MAX){ - eprint(bdb, "(validation)"); - err = true; - free(vbuf); - break; - } - } else { - if(vbuf || tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "(validation)"); - err = true; - free(vbuf); - break; - } - } - free(vbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("writing:\n"); - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", i); - if(!tcbdbput(bdb, buf, len, buf, len)){ - eprint(bdb, "tcbdbput"); - err = true; - break; - } - if(i % 10 == 0){ - TCLIST *vals = tclistnew(); - for(int j = myrand(5) + 1; j >= 0; j--){ - tclistpush(vals, buf, len); - } - if(!tcbdbputdup3(bdb, buf, len, vals)){ - eprint(bdb, "tcbdbput3"); - err = true; - break; - } - tclistdel(vals); - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("reading:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - int vsiz; - char *vbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(bdb, "tcbdbget"); - err = true; - break; - } else if(vsiz != ksiz || memcmp(vbuf, kbuf, vsiz)){ - eprint(bdb, "(validation)"); - err = true; - free(vbuf); - break; - } - free(vbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("word checking:\n"); - for(int i = 0; words[i] != NULL; i += 2){ - const char *kbuf = words[i]; - int ksiz = strlen(kbuf); - const char *vbuf = words[i+1]; - int vsiz = strlen(vbuf); - int rsiz; - char *rbuf = tcbdbget(bdb, kbuf, ksiz, &rsiz); - if(!rbuf){ - eprint(bdb, "tcbdbget"); - err = true; - break; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(bdb, "(validation)"); - err = true; - free(rbuf); - break; - } - free(rbuf); - if(rnum > 250) putchar('.'); - } - if(rnum > 250) iprintf(" (%08d)\n", sizeof(words) / sizeof(*words)); - iprintf("cursor checking:\n"); - BDBCUR *cur = tcbdbcurnew(bdb); - if(!tcbdbcurfirst(cur)){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - char *kbuf; - int ksiz; - int inum = 0; - for(int i = 1; (kbuf = tcbdbcurkey(cur, &ksiz)) != NULL; i++, inum++){ - int vsiz; - char *vbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(bdb, "tcbdbget"); - err = true; - free(kbuf); - break; - } - free(vbuf); - free(kbuf); - tcbdbcurnext(cur); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(rnum > 250) iprintf(" (%08d)\n", inum); - if(tcbdbecode(bdb) != TCENOREC || inum != tcbdbrnum(bdb)){ - eprint(bdb, "(validation)"); - err = true; - } - iprintf("cursor updating:\n"); - if(!tcbdbcurfirst(cur)){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - inum = 0; - for(int i = 1; !err && (kbuf = tcbdbcurkey(cur, &ksiz)) != NULL; i++, inum++){ - switch(myrand(6)){ - case 0: - if(!tcbdbputdup(bdb, kbuf, ksiz, "0123456789", 10)){ - eprint(bdb, "tcbdbputcat"); - err = true; - } - break; - case 1: - if(!tcbdbout(bdb, kbuf, ksiz)){ - eprint(bdb, "tcbdbout"); - err = true; - } - break; - case 2: - if(!tcbdbcurput(cur, kbuf, ksiz, BDBCPCURRENT)){ - eprint(bdb, "tcbdbcurput"); - err = true; - } - break; - case 3: - if(!tcbdbcurput(cur, kbuf, ksiz, BDBCPBEFORE)){ - eprint(bdb, "tcbdbcurput"); - err = true; - } - break; - case 4: - if(!tcbdbcurput(cur, kbuf, ksiz, BDBCPAFTER)){ - eprint(bdb, "tcbdbcurput"); - err = true; - } - break; - default: - if(!tcbdbcurout(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurout"); - err = true; - } - break; - } - free(kbuf); - tcbdbcurnext(cur); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(rnum > 250) iprintf(" (%08d)\n", inum); - if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "(validation)"); - err = true; - } - if(!tcbdbsync(bdb)){ - eprint(bdb, "tcbdbsync"); - err = true; - } - iprintf("cursor updating from empty:\n"); - tcbdbcurfirst(cur); - inum = 0; - for(int i = 1; (kbuf = tcbdbcurkey(cur, &ksiz)) != NULL; i++, inum++){ - free(kbuf); - if(!tcbdbcurout(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurout"); - err = true; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(rnum > 250) iprintf(" (%08d)\n", inum); - if(tcbdbrnum(bdb) != 0){ - eprint(bdb, "(validation)"); - err = true; - } - if(!tcbdbput2(bdb, "one", "first")){ - eprint(bdb, "tcbdbput"); - err = true; - } - if(!tcbdbcurlast(cur)){ - eprint(bdb, "tcbdbcurlast"); - err = true; - } - if(!tcbdbcurput2(cur, "second", BDBCPCURRENT) || !tcbdbcurput2(cur, "first", BDBCPBEFORE) || - !tcbdbcurput2(cur, "zero", BDBCPBEFORE) || !tcbdbcurput2(cur, "top", BDBCPBEFORE)){ - eprint(bdb, "tcbdbcurput2"); - err = true; - } - if(!tcbdbcurlast(cur)){ - eprint(bdb, "tcbdbcurlast"); - err = true; - } - if(!tcbdbcurput2(cur, "third", BDBCPAFTER) || !tcbdbcurput2(cur, "fourth", BDBCPAFTER) || - !tcbdbcurput2(cur, "end", BDBCPCURRENT) || !tcbdbcurput2(cur, "bottom", BDBCPAFTER)){ - eprint(bdb, "tcbdbcurput2"); - err = true; - } - iprintf("checking transaction commit:\n"); - if(!tcbdbtranbegin(bdb)){ - eprint(bdb, "tcbdbtranbegin"); - err = true; - } - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - if(!tcbdbputdup(bdb, kbuf, ksiz, kbuf, ksiz)){ - eprint(bdb, "tcbdbputdup"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(!tcbdbtrancommit(bdb)){ - eprint(bdb, "tcbdbtrancommit"); - err = true; - } - iprintf("checking transaction abort:\n"); - uint64_t ornum = tcbdbrnum(bdb); - if(!tcbdbtranbegin(bdb)){ - eprint(bdb, "tcbdbtranbegin"); - err = true; - } - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - if(!tcbdbout(bdb, kbuf, ksiz) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(!tcbdbtranabort(bdb)){ - eprint(bdb, "tcbdbtranabort"); - err = true; - } - if(tcbdbrnum(bdb) != ornum){ - eprint(bdb, "(validation)"); - err = true; - } - if(ornum > 1000){ - if(!tcbdbcurfirst(cur)){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - for(int i = 1; i < 500 && !err && (kbuf = tcbdbcurkey(cur, &ksiz)) != NULL; i++){ - int vsiz; - if(myrand(20) == 0){ - if(!tcbdbget3(bdb, kbuf, ksiz, &vsiz)){ - eprint(bdb, "tcbdbget3"); - err = true; - } - if(myrand(2) == 0 && !tcbdbout(bdb, kbuf, ksiz)){ - eprint(bdb, "tcbdbget3"); - err = true; - } - if(myrand(2) == 0 && !tcbdbputdup(bdb, kbuf, ksiz, kbuf, ksiz)){ - eprint(bdb, "tcbdbput"); - err = true; - } - } else { - if(!tcbdbcurout(cur)){ - eprint(bdb, "tcbdbcurout"); - err = true; - } - } - free(kbuf); - if(myrand(30) == 0 && !tcbdbcurfirst(cur)){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - } - } - if(!tcbdbvanish(bdb)){ - eprint(bdb, "tcbdbvanish"); - err = true; - } - if(!tcbdbtranbegin(bdb)){ - eprint(bdb, "tcbdbtranbegin"); - err = true; - } - if(!tcbdbput2(bdb, "mikio", "hirabayashi")){ - eprint(bdb, "tcbdbput2"); - err = true; - } - tcbdbcurdel(cur); - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform wicked command */ -static int procwicked(const char *path, int rnum, bool mt, int opts, int omode){ - iprintf("\n path=%s rnum=%d mt=%d opts=%d omode=%d\n\n", - path, rnum, mt, opts, omode); - bool err = false; - double stime = tctime(); - TCBDB *bdb = tcbdbnew(); - if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd); - if(mt && !tcbdbsetmutex(bdb)){ - eprint(bdb, "tcbdbsetmutex"); - err = true; - } - if(!tcbdbtune(bdb, 10, 10, rnum / 50, 100, -1, opts)){ - eprint(bdb, "tcbdbtune"); - err = true; - } - if(!tcbdbsetcache(bdb, 128, 256)){ - eprint(bdb, "tcbdbsetcache"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | BDBOTRUNC | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - BDBCUR *cur = tcbdbcurnew(bdb); - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - TCMAP *map = tcmapnew2(rnum / 5); - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '*', vsiz); - vbuf[vsiz] = '\0'; - char *rbuf; - switch(myrand(16)){ - case 0: - putchar('0'); - if(!tcbdbput(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbput"); - err = true; - } - tcmapput(map, kbuf, ksiz, vbuf, vsiz); - break; - case 1: - putchar('1'); - if(!tcbdbput2(bdb, kbuf, vbuf)){ - eprint(bdb, "tcbdbput2"); - err = true; - } - tcmapput2(map, kbuf, vbuf); - break; - case 2: - putchar('2'); - if(!tcbdbputkeep(bdb, kbuf, ksiz, vbuf, vsiz) && tcbdbecode(bdb) != TCEKEEP){ - eprint(bdb, "tcbdbputkeep"); - err = true; - } - tcmapputkeep(map, kbuf, ksiz, vbuf, vsiz); - break; - case 3: - putchar('3'); - if(!tcbdbputkeep2(bdb, kbuf, vbuf) && tcbdbecode(bdb) != TCEKEEP){ - eprint(bdb, "tcbdbputkeep2"); - err = true; - } - tcmapputkeep2(map, kbuf, vbuf); - break; - case 4: - putchar('4'); - if(!tcbdbputcat(bdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(bdb, "tcbdbputcat"); - err = true; - } - tcmapputcat(map, kbuf, ksiz, vbuf, vsiz); - break; - case 5: - putchar('5'); - if(!tcbdbputcat2(bdb, kbuf, vbuf)){ - eprint(bdb, "tcbdbputcat2"); - err = true; - } - tcmapputcat2(map, kbuf, vbuf); - break; - case 6: - putchar('6'); - if(myrand(10) == 0){ - if(!tcbdbout(bdb, kbuf, ksiz) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout"); - err = true; - } - tcmapout(map, kbuf, ksiz); - } - break; - case 7: - putchar('7'); - if(myrand(10) == 0){ - if(!tcbdbout2(bdb, kbuf) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout2"); - err = true; - } - tcmapout2(map, kbuf); - } - break; - case 8: - putchar('8'); - if(!(rbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz))){ - if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - rbuf = tcsprintf("[%d]", myrand(i + 1)); - vsiz = strlen(rbuf); - } - vsiz += myrand(vsiz); - if(myrand(3) == 0) vsiz += PATH_MAX; - rbuf = tcrealloc(rbuf, vsiz + 1); - for(int j = 0; j < vsiz; j++){ - rbuf[j] = myrand(0x100); - } - if(!tcbdbput(bdb, kbuf, ksiz, rbuf, vsiz)){ - eprint(bdb, "tcbdbput"); - err = true; - } - tcmapput(map, kbuf, ksiz, rbuf, vsiz); - free(rbuf); - break; - case 9: - putchar('9'); - if(!(rbuf = tcbdbget(bdb, kbuf, ksiz, &vsiz)) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - free(rbuf); - break; - case 10: - putchar('A'); - if(!(rbuf = tcbdbget2(bdb, kbuf)) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - free(rbuf); - break; - case 11: - putchar('B'); - if(myrand(1) == 0) vsiz = 1; - if(!tcbdbget3(bdb, kbuf, ksiz, &vsiz) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbget"); - err = true; - } - break; - case 12: - putchar('C'); - if(myrand(rnum / 50) == 0){ - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - } - TCXSTR *ikey = tcxstrnew(); - TCXSTR *ival = tcxstrnew(); - for(int j = myrand(rnum) / 1000 + 1; j >= 0; j--){ - if(j % 3 == 0){ - if(tcbdbcurrec(cur, ikey, ival)){ - if(tcbdbvnum(bdb, tcxstrptr(ikey), tcxstrsize(ikey)) != 1){ - eprint(bdb, "(validation)"); - err = true; - } - if(tcxstrsize(ival) != tcbdbvsiz(bdb, tcxstrptr(ikey), tcxstrsize(ikey))){ - eprint(bdb, "(validation)"); - err = true; - } - } else { - int ecode = tcbdbecode(bdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(bdb, "tcbdbcurrec"); - err = true; - } - } - } else { - int iksiz; - char *ikbuf = tcbdbcurkey(cur, &iksiz); - if(ikbuf){ - free(ikbuf); - } else { - int ecode = tcbdbecode(bdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(bdb, "tcbdbcurkey"); - err = true; - } - } - } - tcbdbcurnext(cur); - } - tcxstrdel(ival); - tcxstrdel(ikey); - break; - default: - putchar('@'); - if(myrand(10000) == 0) srand((unsigned int)(tctime() * 1000) % UINT_MAX); - if(myrand(rnum / 32 + 1) == 0){ - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - int cnt = myrand(30); - for(int j = 0; j < rnum && !err; j++){ - ksiz = sprintf(kbuf, "%d", i + j); - if(myrand(4) == 0){ - if(tcbdbout3(bdb, kbuf, ksiz)){ - cnt--; - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout3"); - err = true; - } - tcmapout(map, kbuf, ksiz); - } else if(myrand(30) == 0){ - int tksiz; - char *tkbuf = tcbdbcurkey(cur, &tksiz); - if(tkbuf){ - if(tcbdbcurout(cur)){ - cnt--; - } else { - eprint(bdb, "tcbdbcurout"); - err = true; - } - tcmapout(map, tkbuf, tksiz); - free(tkbuf); - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - } else { - if(tcbdbout(bdb, kbuf, ksiz)){ - cnt--; - } else if(tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbout"); - err = true; - } - tcmapout(map, kbuf, ksiz); - } - if(cnt < 0) break; - } - } - break; - } - if(i % 50 == 0) iprintf(" (%08d)\n", i); - if(i == rnum / 2){ - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){ - eprint(bdb, "tcbdbopen"); - err = true; - } - } else if(i == rnum / 4){ - char *npath = tcsprintf("%s-tmp", path); - if(!tcbdbcopy(bdb, npath)){ - eprint(bdb, "tcbdbcopy"); - err = true; - } - TCBDB *nbdb = tcbdbnew(); - if(!tcbdbopen(nbdb, npath, BDBOREADER | omode)){ - eprint(nbdb, "tcbdbopen"); - err = true; - } - tcbdbdel(nbdb); - unlink(npath); - free(npath); - if(!tcbdboptimize(bdb, -1, -1, -1, -1, -1, -1)){ - eprint(bdb, "tcbdboptimize"); - err = true; - } - if(!tcbdbcurfirst(cur) && tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "tcbdbcurfirst"); - err = true; - } - } else if(i == rnum / 8){ - if(!tcbdbtranbegin(bdb)){ - eprint(bdb, "tcbdbtranbegin"); - err = true; - } - } else if(i == rnum / 8 + rnum / 16){ - if(!tcbdbtrancommit(bdb)){ - eprint(bdb, "tcbdbtrancommit"); - err = true; - } - } - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - if(!tcbdbsync(bdb)){ - eprint(bdb, "tcbdbsync"); - err = true; - } - if(tcbdbrnum(bdb) != tcmaprnum(map)){ - eprint(bdb, "(validation)"); - err = true; - } - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", i - 1); - int vsiz; - const char *vbuf = tcmapget(map, kbuf, ksiz, &vsiz); - int rsiz; - char *rbuf = tcbdbget(bdb, kbuf, ksiz, &rsiz); - if(vbuf){ - putchar('.'); - if(!rbuf){ - eprint(bdb, "tcbdbget"); - err = true; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(bdb, "(validation)"); - err = true; - } - } else { - putchar('*'); - if(rbuf || tcbdbecode(bdb) != TCENOREC){ - eprint(bdb, "(validation)"); - err = true; - } - } - free(rbuf); - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - tcmapiterinit(map); - int ksiz; - const char *kbuf; - for(int i = 1; (kbuf = tcmapiternext(map, &ksiz)) != NULL; i++){ - putchar('+'); - int vsiz; - const char *vbuf = tcmapiterval(kbuf, &vsiz); - int rsiz; - char *rbuf = tcbdbget(bdb, kbuf, ksiz, &rsiz); - if(!rbuf){ - eprint(bdb, "tcbdbget"); - err = true; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(bdb, "(validation)"); - err = true; - } - free(rbuf); - if(!tcbdbout(bdb, kbuf, ksiz)){ - eprint(bdb, "tcbdbout"); - err = true; - } - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - int mrnum = tcmaprnum(map); - if(mrnum % 50 > 0) iprintf(" (%08d)\n", mrnum); - if(tcbdbrnum(bdb) != 0){ - eprint(bdb, "(validation)"); - err = true; - } - tcbdbcurdel(cur); - iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb)); - iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb)); - mprint(bdb); - tcmapdel(map); - if(!tcbdbclose(bdb)){ - eprint(bdb, "tcbdbclose"); - err = true; - } - tcbdbdel(bdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tchdb.c b/bacula/src/lib/tokyocabinet/tchdb.c deleted file mode 100644 index c13956aa8b..0000000000 --- a/bacula/src/lib/tokyocabinet/tchdb.c +++ /dev/null @@ -1,3093 +0,0 @@ -/************************************************************************************************* - * The hash database API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include "tcutil.h" -#include "tchdb.h" -#include "myconf.h" - -#define HDBFILEMODE 00644 // permission of created files -#define HDBIOBUFSIZ 8192 // size of an I/O buffer - -#define HDBMAGICDATA "ToKyO CaBiNeT" // magic data for identification -#define HDBHEADSIZ 256 // size of the reagion of the header -#define HDBTYPEOFF 32 // offset of the region for the database type -#define HDBFLAGSOFF 33 // offset of the region for the additional flags -#define HDBAPOWOFF 34 // offset of the region for the alignment power -#define HDBFPOWOFF 35 // offset of the region for the free block pool power -#define HDBOPTSOFF 36 // offset of the region for the options -#define HDBBNUMOFF 40 // offset of the region for the bucket number -#define HDBRNUMOFF 48 // offset of the region for the record number -#define HDBFSIZOFF 56 // offset of the region for the file size -#define HDBFRECOFF 64 // offset of the region for the first record offset -#define HDBOPAQUEOFF 128 // offset of the region for the opaque field - -#define HDBDEFBNUM 16381 // default bucket number -#define HDBDEFAPOW 4 // default alignment power -#define HDBMAXAPOW 16 // maximum alignment power -#define HDBDEFFPOW 10 // default free block pool power -#define HDBMAXFPOW 20 // maximum free block pool power -#define HDBMINRUNIT 48 // minimum record reading unit -#define HDBMAXHSIZ 32 // maximum record header size -#define HDBFBPBSIZ 64 // base region size of the free block pool -#define HDBFBPESIZ 4 // size of each region of the free block pool -#define HDBFBPMGFREQ 256 // frequency to merge the free block pool -#define HDBDRPUNIT 65536 // unit size of the delayed record pool -#define HDBDRPLAT 2048 // latitude size of the delayed record pool -#define HDBCACHEOUT 128 // number of records in a process of cacheout - -typedef struct { // type of structure for a record - uint64_t off; // offset of the record - uint32_t rsiz; // size of the whole record - uint8_t magic; // magic number - uint8_t hash; // second hash value - uint64_t left; // offset of the left child record - uint64_t right; // offset of the right child record - uint32_t ksiz; // size of the key - uint32_t vsiz; // size of the value - uint16_t psiz; // size of the padding - const char *kbuf; // pointer to the key - const char *vbuf; // pointer to the value - uint64_t boff; // offset of the body - char *bbuf; // buffer of the body -} TCHREC; - -typedef struct { // type of structure for a free block - uint64_t off; // offset of the block - uint32_t rsiz; // size of the block -} HDBFB; - -enum { // enumeration for magic data - HDBMAGICREC = 0xc8, // for data block - HDBMAGICFB = 0xb0 // for free block -}; - -enum { // enumeration for duplication behavior - HDBPDOVER, // overwrite an existing value - HDBPDKEEP, // keep the existing value - HDBPDCAT // concatenate values -}; - - -/* private macros */ -#define HDBLOCKMETHOD(TC_hdb, TC_wr) \ - ((TC_hdb)->mmtx ? tchdblockmethod((TC_hdb), (TC_wr)) : true) -#define HDBUNLOCKMETHOD(TC_hdb) \ - ((TC_hdb)->mmtx ? tchdbunlockmethod(TC_hdb) : true) -#define HDBLOCKDRP(TC_hdb) \ - ((TC_hdb)->mmtx ? tchdblockdrp(TC_hdb) : true) -#define HDBUNLOCKDRP(TC_hdb) \ - ((TC_hdb)->mmtx ? tchdbunlockdrp(TC_hdb) : true) - - -/* private function prototypes */ -static bool tcseekwrite(TCHDB *hdb, off_t off, const void *buf, size_t size); -static bool tcseekread(TCHDB *hdb, off_t off, void *buf, size_t size); -static void tcdumpmeta(TCHDB *hdb, char *hbuf); -static void tcloadmeta(TCHDB *hdb, const char *hbuf); -static uint64_t tcgetprime(uint64_t num); -static void tchdbclear(TCHDB *hdb); -static int32_t tchdbpadsize(TCHDB *hdb); -static void tchdbsetflag(TCHDB *hdb, int flag, bool sign); -static uint64_t tchdbbidx(TCHDB *hdb, const char *kbuf, int ksiz, uint8_t *hp); -static off_t tchdbgetbucket(TCHDB *hdb, uint64_t bidx); -static void tchdbsetbucket(TCHDB *hdb, uint64_t bidx, uint64_t off); -static bool tchdbsavefbp(TCHDB *hdb); -static bool tchdbloadfbp(TCHDB *hdb); -static void tcfbpsortbyoff(HDBFB *fbpool, int fbpnum); -static void tcfbpsortbyrsiz(HDBFB *fbpool, int fbpnum); -static void tchdbfbpmerge(TCHDB *hdb); -static void tchdbfbpinsert(TCHDB *hdb, uint64_t off, uint32_t rsiz); -static bool tchdbfbpsearch(TCHDB *hdb, TCHREC *rec); -static bool tchdbfbpsplice(TCHDB *hdb, TCHREC *rec, uint32_t nsiz); -static bool tchdbwritefb(TCHDB *hdb, uint64_t off, uint32_t rsiz); -static bool tchdbwriterec(TCHDB *hdb, TCHREC *rec, uint64_t bidx, off_t entoff); -static bool tchdbreadrec(TCHDB *hdb, TCHREC *rec, char *rbuf); -static bool tchdbreadrecbody(TCHDB *hdb, TCHREC *rec); -static int tcreckeycmp(const char *abuf, int asiz, const char *bbuf, int bsiz); -static bool tchdbflushdrp(TCHDB *hdb); -static void tchdbcacheadjust(TCHDB *hdb); -static bool tchdbopenimpl(TCHDB *hdb, const char *path, int omode); -static bool tchdbcloseimpl(TCHDB *hdb); -static bool tchdbputimpl(TCHDB *hdb, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - int dmode); -static void tchdbdrpappend(TCHDB *hdb, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - uint8_t hash); -static bool tchdbputasyncimpl(TCHDB *hdb, const char *kbuf, int ksiz, const char *vbuf, int vsiz); -static bool tchdboutimpl(TCHDB *hdb, const char *kbuf, int ksiz); -static char *tchdbgetimpl(TCHDB *hdb, const char *kbuf, int ksiz, int *sp); -static int tchdbgetintobuf(TCHDB *hdb, const char *kbuf, int ksiz, char *vbuf, int max); -static int tchdbvsizimpl(TCHDB *hdb, const char *kbuf, int ksiz); -static bool tchdbiterinitimpl(TCHDB *hdb); -static char *tchdbiternextimpl(TCHDB *hdb, int *sp); -static bool tchdbiternextintoxstr(TCHDB *hdb, TCXSTR *kxstr, TCXSTR *vxstr); -static bool tchdboptimizeimpl(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts); -static bool tchdbvanishimpl(TCHDB *hdb); -static bool tchdblockmethod(TCHDB *hdb, bool wr); -static bool tchdbunlockmethod(TCHDB *hdb); -static bool tchdblockdrp(TCHDB *hdb); -static bool tchdbunlockdrp(TCHDB *hdb); - - -/* debugging function prototypes */ -void tchdbprintmeta(TCHDB *hdb); -void tchdbprintrec(TCHDB *hdb, TCHREC *rec); - - - -/************************************************************************************************* - * API - *************************************************************************************************/ - - -/* Get the message string corresponding to an error code. */ -const char *tchdberrmsg(int ecode){ - switch(ecode){ - case TCESUCCESS: return "success"; - case TCETHREAD: return "threading error"; - case TCEINVALID: return "invalid operation"; - case TCENOFILE: return "file not found"; - case TCENOPERM: return "no permission"; - case TCEMETA: return "invalid meta data"; - case TCERHEAD: return "invalid record header"; - case TCEOPEN: return "open error"; - case TCECLOSE: return "close error"; - case TCETRUNC: return "trunc error"; - case TCESYNC: return "sync error"; - case TCESTAT: return "stat error"; - case TCESEEK: return "seek error"; - case TCEREAD: return "read error"; - case TCEWRITE: return "write error"; - case TCEMMAP: return "mmap error"; - case TCELOCK: return "lock error"; - case TCEUNLINK: return "unlink error"; - case TCERENAME: return "rename error"; - case TCEMKDIR: return "mkdir error"; - case TCERMDIR: return "rmdir error"; - case TCEKEEP: return "existing record"; - case TCENOREC: return "no record found"; - case TCEMISC: return "miscellaneous error"; - } - return "unknown error"; -} - - -/* Create a hash database object. */ -TCHDB *tchdbnew(void){ - TCHDB *hdb; - TCMALLOC(hdb, sizeof(*hdb)); - tchdbclear(hdb); - return hdb; -} - - -/* Delete a hash database object. */ -void tchdbdel(TCHDB *hdb){ - assert(hdb); - if(hdb->fd >= 0) tchdbclose(hdb); - if(hdb->mmtx){ - pthread_key_delete(*(pthread_key_t *)hdb->eckey); - pthread_mutex_destroy(hdb->dmtx); - pthread_rwlock_destroy(hdb->mmtx); - free(hdb->eckey); - free(hdb->dmtx); - free(hdb->mmtx); - } - free(hdb); -} - - -/* Get the last happened error code of a hash database object. */ -int tchdbecode(TCHDB *hdb){ - assert(hdb); - return hdb->mmtx ? - (int)(intptr_t)pthread_getspecific(*(pthread_key_t *)hdb->eckey) : hdb->ecode; -} - - -/* Set mutual exclusion control of a hash database object for threading. */ -bool tchdbsetmutex(TCHDB *hdb){ - assert(hdb); - if(!TCUSEPTHREAD) return true; - if(!tcglobalmutexlock()) return false; - if(hdb->mmtx || hdb->fd >= 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - tcglobalmutexunlock(); - return false; - } - pthread_mutexattr_t rma; - pthread_mutexattr_init(&rma); - TCMALLOC(hdb->mmtx, sizeof(pthread_rwlock_t)); - TCMALLOC(hdb->dmtx, sizeof(pthread_mutex_t)); - TCMALLOC(hdb->eckey, sizeof(pthread_key_t)); - if(pthread_mutexattr_settype(&rma, PTHREAD_MUTEX_RECURSIVE) != 0 || - pthread_rwlock_init(hdb->mmtx, NULL) != 0 || pthread_mutex_init(hdb->dmtx, &rma) != 0 || - pthread_key_create(hdb->eckey, NULL) != 0){ - tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__); - pthread_mutexattr_destroy(&rma); - free(hdb->eckey); - free(hdb->dmtx); - free(hdb->mmtx); - hdb->eckey = NULL; - hdb->dmtx = NULL; - hdb->mmtx = NULL; - tcglobalmutexunlock(); - return false; - } - pthread_mutexattr_destroy(&rma); - tcglobalmutexunlock(); - return true; -} - - -/* Set the tuning parameters of a hash database object. */ -bool tchdbtune(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){ - assert(hdb); - if(hdb->fd >= 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - hdb->bnum = (bnum > 0) ? tcgetprime(bnum) : HDBDEFBNUM; - hdb->apow = (apow >= 0) ? tclmin(apow, HDBMAXAPOW) : HDBDEFAPOW; - hdb->fpow = (fpow >= 0) ? tclmin(fpow, HDBMAXFPOW) : HDBDEFFPOW; - hdb->opts = opts; - if(!_tc_deflate) hdb->opts &= ~HDBTDEFLATE; - return true; -} - - -/* Set the caching parameters of a hash database object. */ -bool tchdbsetcache(TCHDB *hdb, int32_t rcnum){ - assert(hdb); - if(hdb->fd >= 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - hdb->rcnum = (rcnum > 0) ? tclmin(tclmax(rcnum, HDBCACHEOUT * 2), INT_MAX / 4) : 0; - return true; -} - - -/* Open a database file and connect a hash database object. */ -bool tchdbopen(TCHDB *hdb, const char *path, int omode){ - assert(hdb && path); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd >= 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbopenimpl(hdb, path, omode); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Close a database object. */ -bool tchdbclose(TCHDB *hdb){ - assert(hdb); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbcloseimpl(hdb); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Store a record into a hash database object. */ -bool tchdbput(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->zmode){ - char *zbuf; - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_deflate(vbuf, vsiz, &vsiz, _TCZMRAW); - } else { - zbuf = tcbsencode(vbuf, vsiz, &vsiz); - } - if(!zbuf){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbputimpl(hdb, kbuf, ksiz, zbuf, vsiz, HDBPDOVER); - free(zbuf); - HDBUNLOCKMETHOD(hdb); - return rv; - } - bool rv = tchdbputimpl(hdb, kbuf, ksiz, vbuf, vsiz, HDBPDOVER); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Store a string record into a hash database object. */ -bool tchdbput2(TCHDB *hdb, const char *kstr, const char *vstr){ - assert(hdb && kstr && vstr); - return tchdbput(hdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Store a new record into a hash database object. */ -bool tchdbputkeep(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->zmode){ - char *zbuf; - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_deflate(vbuf, vsiz, &vsiz, _TCZMRAW); - } else { - zbuf = tcbsencode(vbuf, vsiz, &vsiz); - } - if(!zbuf){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbputimpl(hdb, kbuf, ksiz, zbuf, vsiz, HDBPDKEEP); - free(zbuf); - HDBUNLOCKMETHOD(hdb); - return rv; - } - bool rv = tchdbputimpl(hdb, kbuf, ksiz, vbuf, vsiz, HDBPDKEEP); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Store a new string record into a hash database object. */ -bool tchdbputkeep2(TCHDB *hdb, const char *kstr, const char *vstr){ - return tchdbputkeep(hdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Concatenate a value at the end of the existing record in a hash database object. */ -bool tchdbputcat(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->zmode){ - char *zbuf; - int osiz; - char *obuf = tchdbgetimpl(hdb, kbuf, ksiz, &osiz); - if(obuf){ - TCREALLOC(obuf, obuf, osiz + vsiz + 1); - memcpy(obuf + osiz, vbuf, vsiz); - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_deflate(obuf, osiz + vsiz, &vsiz, _TCZMRAW); - } else { - zbuf = tcbsencode(obuf, osiz + vsiz, &vsiz); - } - free(obuf); - } else { - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_deflate(vbuf, vsiz, &vsiz, _TCZMRAW); - } else { - zbuf = tcbsencode(vbuf, vsiz, &vsiz); - } - } - if(!zbuf){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbputimpl(hdb, kbuf, ksiz, zbuf, vsiz, HDBPDOVER); - free(zbuf); - HDBUNLOCKMETHOD(hdb); - return rv; - } - bool rv = tchdbputimpl(hdb, kbuf, ksiz, vbuf, vsiz, HDBPDCAT); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Concatenate a string value at the end of the existing record in a hash database object. */ -bool tchdbputcat2(TCHDB *hdb, const char *kstr, const char *vstr){ - assert(hdb && kstr && vstr); - return tchdbputcat(hdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Store a record into a hash database object in asynchronous fashion. */ -bool tchdbputasync(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(!HDBLOCKMETHOD(hdb, true)) return false; - hdb->async = true; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->zmode){ - char *zbuf; - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_deflate(vbuf, vsiz, &vsiz, _TCZMRAW); - } else { - zbuf = tcbsencode(vbuf, vsiz, &vsiz); - } - if(!zbuf){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbputasyncimpl(hdb, kbuf, ksiz, zbuf, vsiz); - free(zbuf); - HDBUNLOCKMETHOD(hdb); - return rv; - } - bool rv = tchdbputasyncimpl(hdb, kbuf, ksiz, vbuf, vsiz); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Store a string record into a hash database object in asynchronous fashion. */ -bool tchdbputasync2(TCHDB *hdb, const char *kstr, const char *vstr){ - assert(hdb && kstr && vstr); - return tchdbputasync(hdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Remove a record of a hash database object. */ -bool tchdbout(TCHDB *hdb, const void *kbuf, int ksiz){ - assert(hdb && kbuf && ksiz >= 0); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdboutimpl(hdb, kbuf, ksiz); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Remove a string record of a hash database object. */ -bool tchdbout2(TCHDB *hdb, const char *kstr){ - assert(hdb && kstr); - return tchdbout(hdb, kstr, strlen(kstr)); -} - - -/* Retrieve a record in a hash database object. */ -void *tchdbget(TCHDB *hdb, const void *kbuf, int ksiz, int *sp){ - assert(hdb && kbuf && ksiz >= 0 && sp); - if(!HDBLOCKMETHOD(hdb, false)) return NULL; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return NULL; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return NULL; - } - char *rv = tchdbgetimpl(hdb, kbuf, ksiz, sp); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Retrieve a string record in a hash database object. */ -char *tchdbget2(TCHDB *hdb, const char *kstr){ - assert(hdb && kstr); - int vsiz; - return tchdbget(hdb, kstr, strlen(kstr), &vsiz); -} - - -/* Retrieve a record in a hash database object and write the value into a buffer. */ -int tchdbget3(TCHDB *hdb, const void *kbuf, int ksiz, void *vbuf, int max){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && max >= 0); - if(!HDBLOCKMETHOD(hdb, false)) return -1; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return -1; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return -1; - } - int rv = tchdbgetintobuf(hdb, kbuf, ksiz, vbuf, max); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Get the size of the value of a record in a hash database object. */ -int tchdbvsiz(TCHDB *hdb, const void *kbuf, int ksiz){ - assert(hdb && kbuf && ksiz >= 0); - if(!HDBLOCKMETHOD(hdb, false)) return -1; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return -1; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return -1; - } - int rv = tchdbvsizimpl(hdb, kbuf, ksiz); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Get the size of the value of a string record in a hash database object. */ -int tchdbvsiz2(TCHDB *hdb, const char *kstr){ - assert(hdb && kstr); - return tchdbvsiz(hdb, kstr, strlen(kstr)); -} - - -/* Initialize the iterator of a hash database object. */ -bool tchdbiterinit(TCHDB *hdb){ - assert(hdb); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbiterinitimpl(hdb); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Get the next key of the iterator of a hash database object. */ -void *tchdbiternext(TCHDB *hdb, int *sp){ - assert(hdb && sp); - if(!HDBLOCKMETHOD(hdb, true)) return NULL; - if(hdb->fd < 0 || hdb->iter < 1){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return NULL; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return NULL; - } - char *rv = tchdbiternextimpl(hdb, sp); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Get the next key string of the iterator of a hash database object. */ -char *tchdbiternext2(TCHDB *hdb){ - assert(hdb); - int vsiz; - return tchdbiternext(hdb, &vsiz); -} - - -/* Get the next extensible objects of the iterator of a hash database object. */ -bool tchdbiternext3(TCHDB *hdb, TCXSTR *kxstr, TCXSTR *vxstr){ - assert(hdb && kxstr && vxstr); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0 || hdb->iter < 1){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbiternextintoxstr(hdb, kxstr, vxstr); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Get forward matching keys in a hash database object. */ -TCLIST *tchdbfwmkeys(TCHDB *hdb, const void *pbuf, int psiz, int max){ - assert(hdb && pbuf && psiz >= 0); - TCLIST* keys = tclistnew(); - if(!HDBLOCKMETHOD(hdb, true)) return keys; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return keys; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return keys; - } - if(max < 0) max = INT_MAX; - uint64_t iter = hdb->iter; - tchdbiterinitimpl(hdb); - char *kbuf; - int ksiz; - while(TCLISTNUM(keys) < max && (kbuf = tchdbiternextimpl(hdb, &ksiz)) != NULL){ - if(ksiz >= psiz && !memcmp(kbuf, pbuf, psiz)){ - tclistpushmalloc(keys, kbuf, ksiz); - } else { - free(kbuf); - } - } - hdb->iter = iter; - HDBUNLOCKMETHOD(hdb); - return keys; -} - - -/* Get forward matching string keys in a hash database object. */ -TCLIST *tchdbfwmkeys2(TCHDB *hdb, const char *pstr, int max){ - assert(hdb && pstr); - return tchdbfwmkeys(hdb, pstr, strlen(pstr), max); -} - - -/* Synchronize updated contents of a hash database object with the file and the device. */ -bool tchdbsync(TCHDB *hdb){ - assert(hdb); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbmemsync(hdb, true); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Optimize the file of a hash database object. */ -bool tchdboptimize(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){ - assert(hdb); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdboptimizeimpl(hdb, bnum, apow, fpow, opts); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Remove all records of a hash database object. */ -bool tchdbvanish(TCHDB *hdb){ - assert(hdb); - if(!HDBLOCKMETHOD(hdb, true)) return false; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - bool rv = tchdbvanishimpl(hdb); - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Copy the database file of a hash database object. */ -bool tchdbcopy(TCHDB *hdb, const char *path){ - assert(hdb && path); - if(!HDBLOCKMETHOD(hdb, false)) return false; - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return false; - } - if(hdb->async && !tchdbflushdrp(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - if(!HDBLOCKDRP(hdb)){ - HDBUNLOCKMETHOD(hdb); - return false; - } - bool err = false; - hdb->flags &= ~HDBFOPEN; - if(hdb->omode & HDBOWRITER){ - if(!tchdbsavefbp(hdb)) err = true; - if(!tchdbmemsync(hdb, false)) err = true; - } - if(*path == '@'){ - int len = strlen(hdb->path); - char name[len*2+1]; - char *wp = name; - for(int i = 0; i < len; i++){ - switch(hdb->path[i]){ - case '\\': - case '$': - *(wp++) = '\\'; - *(wp++) = hdb->path[i]; - break; - default: - *(wp++) = hdb->path[i]; - break; - } - } - *wp = '\0'; - char *cmd = tcsprintf("%s \"%s\" \"%llu\"", - path + 1, name, (unsigned long long)(tctime() * 1000000)); - if(system(cmd) != 0) err = true; - free(cmd); - } else { - if(!tccopyfile(hdb->path, path)){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - err = true; - } - } - hdb->flags |= HDBFOPEN; - HDBUNLOCKDRP(hdb); - HDBUNLOCKMETHOD(hdb); - return !err; -} - - -/* Get the file path of a hash database object. */ -const char *tchdbpath(TCHDB *hdb){ - assert(hdb); - if(!HDBLOCKMETHOD(hdb, false)) return NULL; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return NULL; - } - const char *rv = hdb->path; - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Get the number of records of a hash database object. */ -uint64_t tchdbrnum(TCHDB *hdb){ - assert(hdb); - if(!HDBLOCKMETHOD(hdb, false)) return 0; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return 0; - } - uint64_t rv = hdb->rnum; - HDBUNLOCKMETHOD(hdb); - return rv; -} - - -/* Get the size of the database file of a hash database object. */ -uint64_t tchdbfsiz(TCHDB *hdb){ - assert(hdb); - if(!HDBLOCKMETHOD(hdb, false)) return 0; - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - HDBUNLOCKMETHOD(hdb); - return 0; - } - uint64_t rv = hdb->fsiz; - HDBUNLOCKMETHOD(hdb); - return rv; -} - - - -/************************************************************************************************* - * features for experts - *************************************************************************************************/ - - -/* Set the error code of a hash database object. */ -void tchdbsetecode(TCHDB *hdb, int ecode, const char *filename, int line, const char *func){ - assert(hdb && filename && line >= 1 && func); - if(!hdb->fatal){ - hdb->ecode = ecode; - if(hdb->mmtx) pthread_setspecific(*(pthread_key_t *)hdb->eckey, (void *)(intptr_t)ecode); - } - if(ecode != TCEINVALID && ecode != TCEKEEP && ecode != TCENOREC){ - hdb->fatal = true; - if(hdb->omode & HDBOWRITER) tchdbsetflag(hdb, HDBFFATAL, true); - } - if(hdb->dbgfd >= 0){ - char obuf[HDBIOBUFSIZ]; - int osiz = sprintf(obuf, "ERROR:%s:%d:%s:%s:%d:%s\n", filename, line, func, - hdb->path ? hdb->path : "-", ecode, tchdberrmsg(ecode)); - tcwrite(hdb->dbgfd, obuf, osiz); - } -} - - -/* Set the type of a hash database object. */ -void tchdbsettype(TCHDB *hdb, uint8_t type){ - assert(hdb); - if(hdb->fd >= 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return; - } - hdb->type = type; -} - - -/* Set the file descriptor for debugging output. */ -void tchdbsetdbgfd(TCHDB *hdb, int fd){ - assert(hdb && fd >= 0); - hdb->dbgfd = fd; -} - - -/* Get the file descriptor for debugging output. */ -int tchdbdbgfd(TCHDB *hdb){ - assert(hdb); - return hdb->dbgfd; -} - - -/* Synchronize updating contents on memory. */ -bool tchdbmemsync(TCHDB *hdb, bool phys){ - assert(hdb); - if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return false; - } - bool err = false; - char hbuf[HDBHEADSIZ]; - tcdumpmeta(hdb, hbuf); - memcpy(hdb->map, hbuf, HDBOPAQUEOFF); - if(phys){ - if(msync(hdb->map, hdb->msiz, MS_SYNC) == -1){ - tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__); - err = true; - } - if(fsync(hdb->fd) == -1){ - tchdbsetecode(hdb, TCESYNC, __FILE__, __LINE__, __func__); - err = true; - } - } - return !err; -} - - -/* Get the number of elements of the bucket array of a hash database object. */ -uint64_t tchdbbnum(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->bnum; -} - - -/* Get the record alignment a hash database object. */ -uint32_t tchdbalign(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->align; -} - - -/* Get the maximum number of the free block pool of a a hash database object. */ -uint32_t tchdbfbpmax(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->fbpmax; -} - - -/* Get the inode number of the database file of a hash database object. */ -uint64_t tchdbinode(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->inode; -} - - -/* Get the modification time of the database file of a hash database object. */ -time_t tchdbmtime(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->mtime; -} - - -/* Get the connection mode of a hash database object. */ -int tchdbomode(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->omode; -} - - -/* Get the database type of a hash database object. */ -uint8_t tchdbtype(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->type; -} - - -/* Get the additional flags of a hash database object. */ -uint8_t tchdbflags(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->flags; -} - - -/* Get the options of a hash database object. */ -uint8_t tchdbopts(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - return hdb->opts; -} - - -/* Get the pointer to the opaque field of a hash database object. */ -char *tchdbopaque(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return NULL; - } - return hdb->map + HDBOPAQUEOFF; -} - - -/* Get the number of used elements of the bucket array of a hash database object. */ -uint64_t tchdbbnumused(TCHDB *hdb){ - assert(hdb); - if(hdb->fd < 0){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - return 0; - } - uint64_t unum = 0; - if(hdb->ba64){ - uint64_t *buckets = hdb->ba64; - for(int i = 0; i < hdb->bnum; i++){ - if(buckets[i]) unum++; - } - } else { - uint32_t *buckets = hdb->ba32; - for(int i = 0; i < hdb->bnum; i++){ - if(buckets[i]) unum++; - } - } - return unum; -} - - - -/************************************************************************************************* - * private features - *************************************************************************************************/ - - -/* Seek and read data from a file. - `hdb' specifies the hash database object. - `off' specifies the offset of the region to seek. - `buf' specifies the buffer to store into. - `size' specifies the size of the buffer. - The return value is true if successful, else, it is false. */ -static bool tcseekwrite(TCHDB *hdb, off_t off, const void *buf, size_t size){ - assert(hdb && off >= 0 && buf && size >= 0); - while(true){ - int wb = pwrite(hdb->fd, buf, size, off); - if(wb >= size){ - return true; - } else if(wb > 0){ - buf = (char *)buf + wb; - size -= wb; - off += wb; - } else if(wb == -1){ - if(errno != EINTR){ - tchdbsetecode(hdb, TCEWRITE, __FILE__, __LINE__, __func__); - return false; - } - } else { - if(size > 0){ - tchdbsetecode(hdb, TCEWRITE, __FILE__, __LINE__, __func__); - return false; - } - } - } - return true; -} - - -/* Seek and read data from a file. - `hdb' specifies the hash database object. - `off' specifies the offset of the region to seek. - `buf' specifies the buffer to store into. - `size' specifies the size of the buffer. - The return value is true if successful, else, it is false. */ -static bool tcseekread(TCHDB *hdb, off_t off, void *buf, size_t size){ - assert(hdb && off >= 0 && buf && size >= 0); - while(true){ - int rb = pread(hdb->fd, buf, size, off); - if(rb >= size){ - break; - } else if(rb > 0){ - buf = (char *)buf + rb; - size -= rb; - off += rb; - } else if(rb == -1){ - if(errno != EINTR){ - tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__); - return false; - } - } else { - if(size > 0){ - tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__); - return false; - } - } - } - return true; -} - - -/* Serialize meta data into a buffer. - `hdb' specifies the hash database object. - `hbuf' specifies the buffer. */ -static void tcdumpmeta(TCHDB *hdb, char *hbuf){ - memset(hbuf, 0, HDBHEADSIZ); - sprintf(hbuf, "%s\n%s:%d\n", HDBMAGICDATA, _TC_FORMATVER, _TC_LIBVER); - memcpy(hbuf + HDBTYPEOFF, &(hdb->type), sizeof(hdb->type)); - memcpy(hbuf + HDBFLAGSOFF, &(hdb->flags), sizeof(hdb->flags)); - memcpy(hbuf + HDBAPOWOFF, &(hdb->apow), sizeof(hdb->apow)); - memcpy(hbuf + HDBFPOWOFF, &(hdb->fpow), sizeof(hdb->fpow)); - memcpy(hbuf + HDBOPTSOFF, &(hdb->opts), sizeof(hdb->opts)); - uint64_t llnum; - llnum = hdb->bnum; - llnum = TCHTOILL(llnum); - memcpy(hbuf + HDBBNUMOFF, &llnum, sizeof(llnum)); - llnum = hdb->rnum; - llnum = TCHTOILL(llnum); - memcpy(hbuf + HDBRNUMOFF, &llnum, sizeof(llnum)); - llnum = hdb->fsiz; - llnum = TCHTOILL(llnum); - memcpy(hbuf + HDBFSIZOFF, &llnum, sizeof(llnum)); - llnum = hdb->frec; - llnum = TCHTOILL(llnum); - memcpy(hbuf + HDBFRECOFF, &llnum, sizeof(llnum)); -} - - -/* Deserialize meta data from a buffer. - `hdb' specifies the hash database object. - `hbuf' specifies the buffer. */ -static void tcloadmeta(TCHDB *hdb, const char *hbuf){ - memcpy(&(hdb->type), hbuf + HDBTYPEOFF, sizeof(hdb->type)); - memcpy(&(hdb->flags), hbuf + HDBFLAGSOFF, sizeof(hdb->flags)); - memcpy(&(hdb->apow), hbuf + HDBAPOWOFF, sizeof(hdb->apow)); - memcpy(&(hdb->fpow), hbuf + HDBFPOWOFF, sizeof(hdb->fpow)); - memcpy(&(hdb->opts), hbuf + HDBOPTSOFF, sizeof(hdb->opts)); - uint64_t llnum; - memcpy(&llnum, hbuf + HDBBNUMOFF, sizeof(llnum)); - hdb->bnum = TCITOHLL(llnum); - memcpy(&llnum, hbuf + HDBRNUMOFF, sizeof(llnum)); - hdb->rnum = TCITOHLL(llnum); - memcpy(&llnum, hbuf + HDBFSIZOFF, sizeof(llnum)); - hdb->fsiz = TCITOHLL(llnum); - memcpy(&llnum, hbuf + HDBFRECOFF, sizeof(llnum)); - hdb->frec = TCITOHLL(llnum); -} - - -/* Get a natural prime number not less than a floor number. - `num' specified the floor number. - The return value is a prime number not less than the floor number. */ -static uint64_t tcgetprime(uint64_t num){ - uint64_t primes[] = { - 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 43, 47, 53, 59, 61, 71, 79, 83, - 89, 103, 109, 113, 127, 139, 157, 173, 191, 199, 223, 239, 251, 283, 317, 349, - 383, 409, 443, 479, 509, 571, 631, 701, 761, 829, 887, 953, 1021, 1151, 1279, - 1399, 1531, 1663, 1789, 1913, 2039, 2297, 2557, 2803, 3067, 3323, 3583, 3833, - 4093, 4603, 5119, 5623, 6143, 6653, 7159, 7673, 8191, 9209, 10223, 11261, - 12281, 13309, 14327, 15359, 16381, 18427, 20479, 22511, 24571, 26597, 28669, - 30713, 32749, 36857, 40949, 45053, 49139, 53239, 57331, 61417, 65521, 73727, - 81919, 90107, 98299, 106487, 114679, 122869, 131071, 147451, 163819, 180221, - 196597, 212987, 229373, 245759, 262139, 294911, 327673, 360439, 393209, 425977, - 458747, 491503, 524287, 589811, 655357, 720887, 786431, 851957, 917503, 982981, - 1048573, 1179641, 1310719, 1441771, 1572853, 1703903, 1835003, 1966079, - 2097143, 2359267, 2621431, 2883577, 3145721, 3407857, 3670013, 3932153, - 4194301, 4718579, 5242877, 5767129, 6291449, 6815741, 7340009, 7864301, - 8388593, 9437179, 10485751, 11534329, 12582893, 13631477, 14680063, 15728611, - 16777213, 18874367, 20971507, 23068667, 25165813, 27262931, 29360087, 31457269, - 33554393, 37748717, 41943023, 46137319, 50331599, 54525917, 58720253, 62914549, - 67108859, 75497467, 83886053, 92274671, 100663291, 109051903, 117440509, - 125829103, 134217689, 150994939, 167772107, 184549373, 201326557, 218103799, - 234881011, 251658227, 268435399, 301989881, 335544301, 369098707, 402653171, - 436207613, 469762043, 503316469, 536870909, 603979769, 671088637, 738197503, - 805306357, 872415211, 939524087, 1006632947, 1073741789, 1207959503, - 1342177237, 1476394991, 1610612711, 1744830457, 1879048183, 2013265907, - 2576980349, 3092376431, 3710851741, 4718021527, 6133428047, 7973456459, - 10365493393, 13475141413, 17517683831, 22772988923, 29604885677, 38486351381, - 50032256819, 65041933867, 84554514043, 109920868241, 0 - }; - int i; - for(i = 0; primes[i] > 0; i++){ - if(num <= primes[i]) return primes[i]; - } - return primes[i-1]; -} - - -/* Clear all members. - `hdb' specifies the hash database object. */ -static void tchdbclear(TCHDB *hdb){ - assert(hdb); - hdb->mmtx = NULL; - hdb->dmtx = NULL; - hdb->eckey = NULL; - hdb->type = HDBTHASH; - hdb->flags = 0; - hdb->bnum = HDBDEFBNUM; - hdb->apow = HDBDEFAPOW; - hdb->fpow = HDBDEFFPOW; - hdb->opts = 0; - hdb->path = NULL; - hdb->fd = -1; - hdb->omode = 0; - hdb->rnum = 0; - hdb->fsiz = 0; - hdb->frec = 0; - hdb->iter = 0; - hdb->map = NULL; - hdb->msiz = 0; - hdb->ba32 = NULL; - hdb->ba64 = NULL; - hdb->align = 0; - hdb->runit = 0; - hdb->zmode = false; - hdb->fbpmax = 0; - hdb->fbpsiz = 0; - hdb->fbpool = NULL; - hdb->fbpnum = 0; - hdb->fbpmis = 0; - hdb->async = false; - hdb->drpool = NULL; - hdb->drpdef = NULL; - hdb->drpoff = 0; - hdb->recc = NULL; - hdb->rcnum = 0; - hdb->ecode = TCESUCCESS; - hdb->fatal = false; - hdb->dbgfd = -1; - hdb->cnt_writerec = -1; - hdb->cnt_reuserec = -1; - hdb->cnt_moverec = -1; - hdb->cnt_readrec = -1; - hdb->cnt_searchfbp = -1; - hdb->cnt_insertfbp = -1; - hdb->cnt_splicefbp = -1; - hdb->cnt_dividefbp = -1; - hdb->cnt_mergefbp = -1; - hdb->cnt_reducefbp = -1; - hdb->cnt_appenddrp = -1; - hdb->cnt_deferdrp = -1; - hdb->cnt_flushdrp = -1; - hdb->cnt_adjrecc = -1; - TCDODEBUG(hdb->cnt_writerec = 0); - TCDODEBUG(hdb->cnt_reuserec = 0); - TCDODEBUG(hdb->cnt_moverec = 0); - TCDODEBUG(hdb->cnt_readrec = 0); - TCDODEBUG(hdb->cnt_searchfbp = 0); - TCDODEBUG(hdb->cnt_insertfbp = 0); - TCDODEBUG(hdb->cnt_splicefbp = 0); - TCDODEBUG(hdb->cnt_dividefbp = 0); - TCDODEBUG(hdb->cnt_mergefbp = 0); - TCDODEBUG(hdb->cnt_reducefbp = 0); - TCDODEBUG(hdb->cnt_appenddrp = 0); - TCDODEBUG(hdb->cnt_deferdrp = 0); - TCDODEBUG(hdb->cnt_flushdrp = 0); - TCDODEBUG(hdb->cnt_adjrecc = 0); -} - - -/* Get the padding size to record alignment. - `hdb' specifies the hash database object. - The return value is the padding size. */ -static int32_t tchdbpadsize(TCHDB *hdb){ - assert(hdb); - int32_t diff = hdb->fsiz & (hdb->align - 1); - return diff > 0 ? hdb->align - diff : 0; -} - - -/* Set the open flag. - `hdb' specifies the hash database object. - `flag' specifies the flag value. - `sign' specifies the sign. */ -static void tchdbsetflag(TCHDB *hdb, int flag, bool sign){ - assert(hdb); - char *fp = (char *)hdb->map + HDBFLAGSOFF; - if(sign){ - *fp |= (uint8_t)flag; - } else { - *fp &= ~(uint8_t)flag; - } - hdb->flags = *fp; -} - - -/* Get the bucket index of a record. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `hp' specifies the pointer to the variable into which the second hash value is assigned. - The return value is the bucket index. */ -static uint64_t tchdbbidx(TCHDB *hdb, const char *kbuf, int ksiz, uint8_t *hp){ - assert(hdb && kbuf && ksiz >= 0 && hp); - uint64_t idx = 19780211; - uint32_t hash = 751; - const char *rp = kbuf + ksiz; - while(ksiz--){ - idx = (idx << 5) + (idx << 2) + idx + *(uint8_t *)kbuf++; - hash = ((hash << 5) - hash) ^ *(uint8_t *)--rp; - } - *hp = hash; - return idx % hdb->bnum; -} - - -/* Get the offset of the record of a bucket element. - `hdb' specifies the hash database object. - `bidx' specifies the index of the bucket. - The return value is the offset of the record. */ -static off_t tchdbgetbucket(TCHDB *hdb, uint64_t bidx){ - assert(hdb && bidx >= 0); - if(hdb->ba64){ - uint64_t llnum = hdb->ba64[bidx]; - return TCITOHLL(llnum) << hdb->apow; - } - uint32_t lnum = hdb->ba32[bidx]; - return (off_t)TCITOHL(lnum) << hdb->apow; -} - - -/* Get the offset of the record of a bucket element. - `hdb' specifies the hash database object. - `bidx' specifies the index of the record. - `off' specifies the offset of the record. */ -static void tchdbsetbucket(TCHDB *hdb, uint64_t bidx, uint64_t off){ - assert(hdb && bidx >= 0); - if(hdb->ba64){ - uint64_t llnum = off >> hdb->apow; - hdb->ba64[bidx] = TCHTOILL(llnum); - } else { - uint32_t lnum = off >> hdb->apow; - hdb->ba32[bidx] = TCHTOIL(lnum); - } -} - - -/* Load the free block pool from the file. - The return value is true if successful, else, it is false. */ -static bool tchdbsavefbp(TCHDB *hdb){ - assert(hdb); - if(hdb->fbpnum > (hdb->fbpmax >> 1)){ - tchdbfbpmerge(hdb); - } else if(hdb->fbpnum > 1){ - tcfbpsortbyoff(hdb->fbpool, hdb->fbpnum); - } - int bsiz = hdb->fbpsiz; - char *buf; - TCMALLOC(buf, bsiz); - char *wp = buf; - HDBFB *cur = hdb->fbpool; - HDBFB *end = cur + hdb->fbpnum; - uint64_t base = 0; - bsiz -= sizeof(HDBFB) + sizeof(uint8_t) + sizeof(uint8_t); - while(cur < end && bsiz > 0){ - uint64_t noff = cur->off >> hdb->apow; - int step; - uint64_t llnum = noff - base; - TCSETVNUMBUF64(step, wp, llnum); - wp += step; - bsiz -= step; - uint32_t lnum = cur->rsiz >> hdb->apow; - TCSETVNUMBUF(step, wp, lnum); - wp += step; - bsiz -= step; - base = noff; - cur++; - } - *(wp++) = '\0'; - *(wp++) = '\0'; - if(!tcseekwrite(hdb, hdb->msiz, buf, wp - buf)){ - free(buf); - return false; - } - free(buf); - return true; -} - - -/* Save the free block pool into the file. - The return value is true if successful, else, it is false. */ -static bool tchdbloadfbp(TCHDB *hdb){ - int bsiz = hdb->fbpsiz; - char *buf; - TCMALLOC(buf, bsiz); - if(!tcseekread(hdb, hdb->msiz, buf, bsiz)){ - free(buf); - return false; - } - const char *rp = buf; - HDBFB *cur = hdb->fbpool; - HDBFB *end = cur + hdb->fbpmax; - uint64_t base = 0; - while(cur < end && *rp != '\0'){ - int step; - uint64_t llnum; - TCREADVNUMBUF64(rp, llnum, step); - base += llnum << hdb->apow; - cur->off = base; - rp += step; - uint32_t lnum; - TCREADVNUMBUF(rp, lnum, step); - cur->rsiz = lnum << hdb->apow; - rp += step; - cur++; - } - hdb->fbpnum = cur - (HDBFB *)hdb->fbpool; - free(buf); - return true; -} - - -/* Sort the free block pool by offset. - `fbpool' specifies the free block pool. - `fbpnum' specifies the number of blocks. */ -static void tcfbpsortbyoff(HDBFB *fbpool, int fbpnum){ - assert(fbpool && fbpnum >= 0); - fbpnum--; - int bottom = fbpnum / 2 + 1; - int top = fbpnum; - while(bottom > 0){ - bottom--; - int mybot = bottom; - int i = 2 * mybot; - while(i <= top){ - if(i < top && fbpool[i+1].off > fbpool[i].off) i++; - if(fbpool[mybot].off >= fbpool[i].off) break; - HDBFB swap = fbpool[mybot]; - fbpool[mybot] = fbpool[i]; - fbpool[i] = swap; - mybot = i; - i = 2 * mybot; - } - } - while(top > 0){ - HDBFB swap = fbpool[0]; - fbpool[0] = fbpool[top]; - fbpool[top] = swap; - top--; - int mybot = bottom; - int i = 2 * mybot; - while(i <= top){ - if(i < top && fbpool[i+1].off > fbpool[i].off) i++; - if(fbpool[mybot].off >= fbpool[i].off) break; - swap = fbpool[mybot]; - fbpool[mybot] = fbpool[i]; - fbpool[i] = swap; - mybot = i; - i = 2 * mybot; - } - } -} - - -/* Sort the free block pool by record size. - `fbpool' specifies the free block pool. - `fbpnum' specifies the number of blocks. */ -static void tcfbpsortbyrsiz(HDBFB *fbpool, int fbpnum){ - assert(fbpool && fbpnum >= 0); - fbpnum--; - int bottom = fbpnum / 2 + 1; - int top = fbpnum; - while(bottom > 0){ - bottom--; - int mybot = bottom; - int i = 2 * mybot; - while(i <= top){ - if(i < top && fbpool[i+1].rsiz > fbpool[i].rsiz) i++; - if(fbpool[mybot].rsiz >= fbpool[i].rsiz) break; - HDBFB swap = fbpool[mybot]; - fbpool[mybot] = fbpool[i]; - fbpool[i] = swap; - mybot = i; - i = 2 * mybot; - } - } - while(top > 0){ - HDBFB swap = fbpool[0]; - fbpool[0] = fbpool[top]; - fbpool[top] = swap; - top--; - int mybot = bottom; - int i = 2 * mybot; - while(i <= top){ - if(i < top && fbpool[i+1].rsiz > fbpool[i].rsiz) i++; - if(fbpool[mybot].rsiz >= fbpool[i].rsiz) break; - swap = fbpool[mybot]; - fbpool[mybot] = fbpool[i]; - fbpool[i] = swap; - mybot = i; - i = 2 * mybot; - } - } -} - - -/* Merge successive records in the free block pool. - `hdb' specifies the hash database object. */ -static void tchdbfbpmerge(TCHDB *hdb){ - assert(hdb); - TCDODEBUG(hdb->cnt_mergefbp++); - int32_t onum = hdb->fbpnum; - tcfbpsortbyoff(hdb->fbpool, hdb->fbpnum); - HDBFB *wp = hdb->fbpool;; - HDBFB *cur = wp; - HDBFB *end = wp + hdb->fbpnum - 1; - while(cur < end){ - if(cur->off > 0){ - HDBFB *next = cur + 1; - if(cur->off + cur->rsiz == next->off){ - if(hdb->iter == next->off) hdb->iter += next->rsiz; - cur->rsiz += next->rsiz; - next->off = 0; - } - *(wp++) = *cur; - } - cur++; - } - if(end->off > 0) *(wp++) = *end; - hdb->fbpnum = wp - (HDBFB *)hdb->fbpool; - hdb->fbpmis = (hdb->fbpnum < onum) ? 0 : hdb->fbpnum * -2; -} - - -/* Insert a block into the free block pool. - `hdb' specifies the hash database object. - `off' specifies the offset of the block. - `rsiz' specifies the size of the block. */ -static void tchdbfbpinsert(TCHDB *hdb, uint64_t off, uint32_t rsiz){ - assert(hdb && off > 0 && rsiz > 0); - TCDODEBUG(hdb->cnt_insertfbp++); - if(hdb->fpow < 1) return; - HDBFB *pv = hdb->fbpool; - if(hdb->fbpnum >= hdb->fbpmax){ - tchdbfbpmerge(hdb); - tcfbpsortbyrsiz(hdb->fbpool, hdb->fbpnum); - if(hdb->fbpnum >= hdb->fbpmax){ - TCDODEBUG(hdb->cnt_reducefbp++); - int32_t dnum = (hdb->fbpmax >> 2) + 1; - memmove(pv, pv + dnum, (hdb->fbpnum - dnum) * sizeof(*pv)); - hdb->fbpnum -= dnum; - } - hdb->fbpmis = 0; - } - pv = pv + hdb->fbpnum; - pv->off = off; - pv->rsiz = rsiz; - hdb->fbpnum++; -} - - -/* Search the free block pool for the minimum region. - `hdb' specifies the hash database object. - `rec' specifies the record object to be stored. - The return value is true if successful, else, it is false. */ -static bool tchdbfbpsearch(TCHDB *hdb, TCHREC *rec){ - assert(hdb && rec); - TCDODEBUG(hdb->cnt_searchfbp++); - if(hdb->fbpnum < 1){ - rec->off = hdb->fsiz; - rec->rsiz = 0; - return true; - } - uint32_t rsiz = rec->rsiz; - HDBFB *pv = hdb->fbpool; - HDBFB *ep = pv + hdb->fbpnum; - while(pv < ep){ - if(pv->rsiz > rsiz){ - if(pv->rsiz > (rsiz << 1)){ - uint64_t fsiz = hdb->fsiz; - hdb->fsiz = pv->off + rsiz; - uint32_t psiz = tchdbpadsize(hdb); - hdb->fsiz = fsiz; - uint64_t noff = pv->off + rsiz + psiz; - if(pv->rsiz >= ((noff - pv->off) << 1)){ - TCDODEBUG(hdb->cnt_dividefbp++); - rec->off = pv->off; - rec->rsiz = noff - pv->off; - pv->off = noff; - pv->rsiz -= rec->rsiz; - return tchdbwritefb(hdb, pv->off, pv->rsiz); - } - } - rec->off = pv->off; - rec->rsiz = pv->rsiz; - ep--; - pv->off = ep->off; - pv->rsiz = ep->rsiz; - hdb->fbpnum--; - return true; - } - pv++; - } - rec->off = hdb->fsiz; - rec->rsiz = 0; - hdb->fbpmis++; - if(hdb->fbpmis >= HDBFBPMGFREQ){ - tchdbfbpmerge(hdb); - tcfbpsortbyrsiz(hdb->fbpool, hdb->fbpnum); - } - return true; -} - - -/* Splice the trailing free block - `hdb' specifies the hash database object. - `rec' specifies the record object to be stored. - `nsiz' specifies the needed size. - The return value is whether splicing succeeded or not. */ -static bool tchdbfbpsplice(TCHDB *hdb, TCHREC *rec, uint32_t nsiz){ - assert(hdb && rec && nsiz > 0); - if(hdb->fbpnum < 1) return false; - uint64_t off = rec->off + rec->rsiz; - uint32_t rsiz = rec->rsiz; - HDBFB *pv = hdb->fbpool; - HDBFB *ep = pv + hdb->fbpnum; - while(pv < ep){ - if(pv->off == off && rsiz + pv->rsiz >= nsiz){ - if(hdb->iter == pv->off) hdb->iter += pv->rsiz; - rec->rsiz += pv->rsiz; - ep--; - pv->off = ep->off; - pv->rsiz = ep->rsiz; - hdb->fbpnum--; - return true; - } - pv++; - } - return false; -} - - -/* Write a free block into the file. - `hdb' specifies the hash database object. - `off' specifies the offset of the block. - `rsiz' specifies the size of the block. - The return value is true if successful, else, it is false. */ -static bool tchdbwritefb(TCHDB *hdb, uint64_t off, uint32_t rsiz){ - assert(hdb && off > 0 && rsiz > 0); - char rbuf[HDBMAXHSIZ]; - char *wp = rbuf; - *(uint8_t *)(wp++) = HDBMAGICFB; - uint32_t lnum = TCHTOIL(rsiz); - memcpy(wp, &lnum, sizeof(lnum)); - wp += sizeof(lnum); - if(!tcseekwrite(hdb, off, rbuf, wp - rbuf)) return false; - return true; -} - - -/* Write a record into the file. - `hdb' specifies the hash database object. - `rec' specifies the record object. - `bidx' specifies the index of the bucket. - `entoff' specifies the offset of the tree entry. - The return value is true if successful, else, it is false. */ -static bool tchdbwriterec(TCHDB *hdb, TCHREC *rec, uint64_t bidx, off_t entoff){ - assert(hdb && rec); - TCDODEBUG(hdb->cnt_writerec++); - uint64_t ofsiz = hdb->fsiz; - char stack[HDBIOBUFSIZ]; - int bsiz = rec->rsiz > 0 ? rec->rsiz : HDBMAXHSIZ + rec->ksiz + rec->vsiz + hdb->align; - char *rbuf; - if(bsiz <= HDBIOBUFSIZ){ - rbuf = stack; - } else { - TCMALLOC(rbuf, bsiz); - } - char *wp = rbuf; - *(uint8_t *)(wp++) = HDBMAGICREC; - *(uint8_t *)(wp++) = rec->hash; - if(hdb->ba64){ - uint64_t llnum; - llnum = rec->left >> hdb->apow; - llnum = TCHTOILL(llnum); - memcpy(wp, &llnum, sizeof(llnum)); - wp += sizeof(llnum); - llnum = rec->right >> hdb->apow; - llnum = TCHTOILL(llnum); - memcpy(wp, &llnum, sizeof(llnum)); - wp += sizeof(llnum); - } else { - uint32_t lnum; - lnum = rec->left >> hdb->apow; - lnum = TCHTOIL(lnum); - memcpy(wp, &lnum, sizeof(lnum)); - wp += sizeof(lnum); - lnum = rec->right >> hdb->apow; - lnum = TCHTOIL(lnum); - memcpy(wp, &lnum, sizeof(lnum)); - wp += sizeof(lnum); - } - uint16_t snum; - char *pwp = wp; - wp += sizeof(snum); - int step; - TCSETVNUMBUF(step, wp, rec->ksiz); - wp += step; - TCSETVNUMBUF(step, wp, rec->vsiz); - wp += step; - int32_t hsiz = wp - rbuf; - int32_t rsiz = hsiz + rec->ksiz + rec->vsiz; - if(rec->rsiz < 1){ - hdb->fsiz += rsiz; - uint16_t psiz = tchdbpadsize(hdb); - rec->rsiz = rsiz + psiz; - rec->psiz = psiz; - hdb->fsiz += psiz; - } else if(rsiz > rec->rsiz){ - if(rbuf != stack) free(rbuf); - if(tchdbfbpsplice(hdb, rec, rsiz)){ - TCDODEBUG(hdb->cnt_splicefbp++); - return tchdbwriterec(hdb, rec, bidx, entoff); - } - TCDODEBUG(hdb->cnt_moverec++); - if(!tchdbwritefb(hdb, rec->off, rec->rsiz)) return false; - tchdbfbpinsert(hdb, rec->off, rec->rsiz); - rec->rsiz = rsiz; - if(!tchdbfbpsearch(hdb, rec)) return false; - return tchdbwriterec(hdb, rec, bidx, entoff); - } else { - TCDODEBUG(hdb->cnt_reuserec++); - uint32_t psiz = rec->rsiz - rsiz; - if(psiz > UINT16_MAX){ - TCDODEBUG(hdb->cnt_dividefbp++); - uint64_t fsiz = hdb->fsiz; - hdb->fsiz = rec->off + rsiz; - psiz = tchdbpadsize(hdb); - hdb->fsiz = fsiz; - uint64_t noff = rec->off + rsiz + psiz; - uint32_t nsiz = rec->rsiz - rsiz - psiz; - rec->rsiz = noff - rec->off; - rec->psiz = psiz; - if(!tchdbwritefb(hdb, noff, nsiz)) return false; - tchdbfbpinsert(hdb, noff, nsiz); - } - rec->psiz = psiz; - } - snum = rec->psiz; - snum = TCHTOIS(snum); - memcpy(pwp, &snum, sizeof(snum)); - rsiz = rec->rsiz; - rsiz -= hsiz; - memcpy(wp, rec->kbuf, rec->ksiz); - wp += rec->ksiz; - rsiz -= rec->ksiz; - memcpy(wp, rec->vbuf, rec->vsiz); - wp += rec->vsiz; - rsiz -= rec->vsiz; - memset(wp, 0, rsiz); - if(!tcseekwrite(hdb, rec->off, rbuf, rec->rsiz)){ - if(rbuf != stack) free(rbuf); - hdb->fsiz = ofsiz; - return false; - } - if(hdb->fsiz != ofsiz){ - uint64_t llnum = hdb->fsiz; - llnum = TCHTOILL(llnum); - memcpy(hdb->map + HDBFSIZOFF, &llnum, sizeof(llnum)); - } - if(rbuf != stack) free(rbuf); - if(entoff > 0){ - if(hdb->ba64){ - uint64_t llnum = rec->off >> hdb->apow; - llnum = TCHTOILL(llnum); - if(!tcseekwrite(hdb, entoff, &llnum, sizeof(uint64_t))) return false; - } else { - uint32_t lnum = rec->off >> hdb->apow; - lnum = TCHTOIL(lnum); - if(!tcseekwrite(hdb, entoff, &lnum, sizeof(uint32_t))) return false; - } - } else { - tchdbsetbucket(hdb, bidx, rec->off); - } - return true; -} - - -/* Read a record from the file. - `hdb' specifies the hash database object. - `rec' specifies the record object. - `rbuf' specifies the buffer for reading. - The return value is true if successful, else, it is false. */ -static bool tchdbreadrec(TCHDB *hdb, TCHREC *rec, char *rbuf){ - assert(hdb && rec && rbuf); - TCDODEBUG(hdb->cnt_readrec++); - off_t rsiz = hdb->fsiz - rec->off; - if(rsiz > hdb->runit){ - rsiz = hdb->runit; - } else if(rsiz < (sizeof(uint8_t) + sizeof(uint32_t))){ - tchdbsetecode(hdb, TCERHEAD, __FILE__, __LINE__, __func__); - return false; - } - if(!tcseekread(hdb, rec->off, rbuf, rsiz)) return false; - const char *rp = rbuf; - rec->magic = *(uint8_t *)(rp++); - if(rec->magic == HDBMAGICFB){ - uint32_t lnum; - memcpy(&lnum, rp, sizeof(lnum)); - rec->rsiz = TCITOHL(lnum); - return true; - } else if(rec->magic != HDBMAGICREC){ - tchdbsetecode(hdb, TCERHEAD, __FILE__, __LINE__, __func__); - return false; - } - rec->hash = *(uint8_t *)(rp++); - if(hdb->ba64){ - uint64_t llnum; - memcpy(&llnum, rp, sizeof(llnum)); - rec->left = TCITOHLL(llnum) << hdb->apow; - rp += sizeof(llnum); - memcpy(&llnum, rp, sizeof(llnum)); - rec->right = TCITOHLL(llnum) << hdb->apow; - rp += sizeof(llnum); - } else { - uint32_t lnum; - memcpy(&lnum, rp, sizeof(lnum)); - rec->left = (uint64_t)TCITOHL(lnum) << hdb->apow; - rp += sizeof(lnum); - memcpy(&lnum, rp, sizeof(lnum)); - rec->right = (uint64_t)TCITOHL(lnum) << hdb->apow; - rp += sizeof(lnum); - } - uint16_t snum; - memcpy(&snum, rp, sizeof(snum)); - rec->psiz = TCITOHS(snum); - rp += sizeof(snum); - uint32_t lnum; - int step; - TCREADVNUMBUF(rp, lnum, step); - rec->ksiz = lnum; - rp += step; - TCREADVNUMBUF(rp, lnum, step); - rec->vsiz = lnum; - rp += step; - int32_t hsiz = rp - rbuf; - rec->rsiz = hsiz + rec->ksiz + rec->vsiz + rec->psiz; - rec->kbuf = NULL; - rec->vbuf = NULL; - rec->boff = rec->off + hsiz; - rec->bbuf = NULL; - rsiz -= hsiz; - if(rsiz >= rec->ksiz){ - rec->kbuf = rp; - rsiz -= rec->ksiz; - rp += rec->ksiz; - if(rsiz >= rec->vsiz) rec->vbuf = rp; - } - return true; -} - - -/* Read the body of a record from the file. - `hdb' specifies the hash database object. - `rec' specifies the record object. - The return value is true if successful, else, it is false. */ -static bool tchdbreadrecbody(TCHDB *hdb, TCHREC *rec){ - assert(hdb && rec); - int32_t bsiz = rec->ksiz + rec->vsiz; - TCMALLOC(rec->bbuf, bsiz + 1); - if(!tcseekread(hdb, rec->boff, rec->bbuf, bsiz)) return false; - rec->kbuf = rec->bbuf; - rec->vbuf = rec->bbuf + rec->ksiz; - return true; -} - - -/* Compare keys of two records. - `abuf' specifies the pointer to the region of the former. - `asiz' specifies the size of the region. - `bbuf' specifies the pointer to the region of the latter. - `bsiz' specifies the size of the region. - The return value is 0 if two equals, positive if the formar is big, else, negative. */ -static int tcreckeycmp(const char *abuf, int asiz, const char *bbuf, int bsiz){ - assert(abuf && asiz >= 0 && bbuf && bsiz >= 0); - if(asiz > bsiz) return 1; - if(asiz < bsiz) return -1; - return memcmp(abuf, bbuf, asiz); -} - - -/* Flush the delayed record pool. - `hdb' specifies the hash database object. - The return value is true if successful, else, it is false. */ -static bool tchdbflushdrp(TCHDB *hdb){ - assert(hdb); - if(!HDBLOCKDRP(hdb)) return false; - if(!hdb->drpool){ - HDBUNLOCKDRP(hdb); - return true; - } - TCDODEBUG(hdb->cnt_flushdrp++); - if(!tcseekwrite(hdb, hdb->drpoff, TCXSTRPTR(hdb->drpool), TCXSTRSIZE(hdb->drpool))){ - HDBUNLOCKDRP(hdb); - return false; - } - const char *rp = TCXSTRPTR(hdb->drpdef); - int size = TCXSTRSIZE(hdb->drpdef); - while(size > 0){ - int ksiz, vsiz; - memcpy(&ksiz, rp, sizeof(int)); - rp += sizeof(int); - memcpy(&vsiz, rp, sizeof(int)); - rp += sizeof(int); - const char *kbuf = rp; - rp += ksiz; - const char *vbuf = rp; - rp += vsiz; - if(!tchdbputimpl(hdb, kbuf, ksiz, vbuf, vsiz, HDBPDOVER)){ - tcxstrdel(hdb->drpdef); - tcxstrdel(hdb->drpool); - hdb->drpool = NULL; - hdb->drpdef = NULL; - hdb->drpoff = 0; - HDBUNLOCKDRP(hdb); - return false; - } - size -= sizeof(int) * 2 + ksiz + vsiz; - } - tcxstrdel(hdb->drpdef); - tcxstrdel(hdb->drpool); - hdb->drpool = NULL; - hdb->drpdef = NULL; - hdb->drpoff = 0; - uint64_t llnum; - llnum = hdb->rnum; - llnum = TCHTOILL(llnum); - memcpy(hdb->map + HDBRNUMOFF, &llnum, sizeof(llnum)); - llnum = hdb->fsiz; - llnum = TCHTOILL(llnum); - memcpy(hdb->map + HDBFSIZOFF, &llnum, sizeof(llnum)); - HDBUNLOCKDRP(hdb); - return true; -} - - -/* Adjust the caches for leaves and nodes. - `hdb' specifies the hash tree database object. */ -static void tchdbcacheadjust(TCHDB *hdb){ - assert(hdb); - TCDODEBUG(hdb->cnt_adjrecc++); - tcmdbcutfront(hdb->recc, HDBCACHEOUT); -} - - -/* Open a database file and connect a hash database object. - `hdb' specifies the hash database object. - `path' specifies the path of the database file. - `omode' specifies the connection mode. - If successful, the return value is true, else, it is false. */ -static bool tchdbopenimpl(TCHDB *hdb, const char *path, int omode){ - assert(hdb && path); - int mode = O_RDONLY; - if(omode & HDBOWRITER){ - mode = O_RDWR; - if(omode & HDBOCREAT) mode |= O_CREAT; - } - int fd = open(path, mode, HDBFILEMODE); - if(fd < 0){ - int ecode = TCEOPEN; - switch(errno){ - case EACCES: ecode = TCENOPERM; break; - case ENOENT: ecode = TCENOFILE; break; - } - tchdbsetecode(hdb, ecode, __FILE__, __LINE__, __func__); - return false; - } - if(!(omode & HDBONOLCK)){ - if(!tclock(fd, omode & HDBOWRITER, omode & HDBOLCKNB)){ - tchdbsetecode(hdb, TCELOCK, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - } - if((omode & HDBOWRITER) && (omode & HDBOTRUNC)){ - if(ftruncate(fd, 0) == -1){ - tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - } - struct stat sbuf; - if(fstat(fd, &sbuf) == -1 || !S_ISREG(sbuf.st_mode)){ - tchdbsetecode(hdb, TCESTAT, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - char hbuf[HDBHEADSIZ]; - if((omode & HDBOWRITER) && sbuf.st_size < 1){ - hdb->rnum = 0; - uint32_t fbpmax = 1 << hdb->fpow; - uint32_t fbpsiz = HDBFBPBSIZ + fbpmax * HDBFBPESIZ; - int besiz = (hdb->opts & HDBTLARGE) ? sizeof(int64_t) : sizeof(int32_t); - hdb->align = 1 << hdb->apow; - hdb->fsiz = HDBHEADSIZ + besiz * hdb->bnum + fbpsiz; - uint64_t psiz = tchdbpadsize(hdb); - hdb->fsiz += psiz; - hdb->frec = hdb->fsiz; - tcdumpmeta(hdb, hbuf); - psiz += besiz * hdb->bnum + fbpsiz; - char pbuf[HDBIOBUFSIZ]; - memset(pbuf, 0, HDBIOBUFSIZ); - bool err = false; - if(!tcwrite(fd, hbuf, HDBHEADSIZ)) err = true; - while(psiz > 0){ - if(psiz > HDBIOBUFSIZ){ - if(!tcwrite(fd, pbuf, HDBIOBUFSIZ)) err = true; - psiz -= HDBIOBUFSIZ; - } else { - if(!tcwrite(fd, pbuf, psiz)) err = true; - psiz = 0; - } - } - if(err){ - tchdbsetecode(hdb, TCEWRITE, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - sbuf.st_size = hdb->fsiz; - } - if(lseek(fd, 0, SEEK_SET) == -1){ - tchdbsetecode(hdb, TCESEEK, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - if(!tcread(fd, hbuf, HDBHEADSIZ)){ - tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - int type = hdb->type; - tcloadmeta(hdb, hbuf); - uint32_t fbpmax = 1 << hdb->fpow; - uint32_t fbpsiz = HDBFBPBSIZ + fbpmax * HDBFBPESIZ; - if(!(omode & HDBONOLCK)){ - if(memcmp(hbuf, HDBMAGICDATA, strlen(HDBMAGICDATA)) || hdb->type != type || - hdb->frec < HDBHEADSIZ + fbpsiz || hdb->frec > hdb->fsiz || sbuf.st_size < hdb->fsiz){ - tchdbsetecode(hdb, TCEMETA, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - if(sbuf.st_size > hdb->fsiz) hdb->fsiz = sbuf.st_size; - } - if((hdb->opts & HDBTDEFLATE) && !_tc_deflate){ - tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - int besiz = (hdb->opts & HDBTLARGE) ? sizeof(int64_t) : sizeof(int32_t); - size_t msiz = HDBHEADSIZ + hdb->bnum * besiz; - void *map = mmap(0, msiz, PROT_READ | ((omode & HDBOWRITER) ? PROT_WRITE : 0), - MAP_SHARED, fd, 0); - if(map == MAP_FAILED){ - tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__); - close(fd); - return false; - } - hdb->fbpmax = fbpmax; - hdb->fbpsiz = fbpsiz; - if(omode & HDBOWRITER){ - TCMALLOC(hdb->fbpool, fbpmax * sizeof(HDBFB)); - } else { - hdb->fbpool = NULL; - } - hdb->fbpnum = 0; - hdb->fbpmis = 0; - hdb->async = false; - hdb->drpool = NULL; - hdb->drpdef = NULL; - hdb->drpoff = 0; - hdb->recc = (hdb->rcnum > 0) ? tcmdbnew2(hdb->rcnum * 2 + 1) : NULL; - hdb->path = tcstrdup(path); - hdb->omode = omode; - hdb->iter = 0; - hdb->map = map; - hdb->msiz = msiz; - if(hdb->opts & HDBTLARGE){ - hdb->ba32 = NULL; - hdb->ba64 = (uint64_t *)((char *)map + HDBHEADSIZ); - } else { - hdb->ba32 = (uint32_t *)((char *)map + HDBHEADSIZ); - hdb->ba64 = NULL; - } - hdb->align = 1 << hdb->apow; - hdb->runit = tclmin(tclmax(hdb->align, HDBMINRUNIT), HDBIOBUFSIZ); - hdb->zmode = (hdb->opts & HDBTDEFLATE) || (hdb->opts & HDBTTCBS); - hdb->ecode = TCESUCCESS; - hdb->fatal = false; - hdb->fd = fd; - if(hdb->omode & HDBOWRITER){ - bool err = false; - if(!(hdb->flags & HDBFOPEN) && !tchdbloadfbp(hdb)) err = true; - memset(hbuf, 0, 2); - if(!tcseekwrite(hdb, hdb->msiz, hbuf, 2)) err = true; - if(err){ - free(hdb->path); - free(hdb->fbpool); - munmap(hdb->map, hdb->msiz); - close(fd); - hdb->fd = -1; - return false; - } - tchdbsetflag(hdb, HDBFOPEN, true); - } - hdb->inode = (uint64_t)sbuf.st_ino; - hdb->mtime = sbuf.st_mtime; - return true; -} - - -/* Close a hash database object. - `hdb' specifies the hash database object. - If successful, the return value is true, else, it is false. */ -static bool tchdbcloseimpl(TCHDB *hdb){ - assert(hdb); - bool err = false; - if(hdb->recc){ - tcmdbdel(hdb->recc); - hdb->recc = NULL; - } - if(hdb->omode & HDBOWRITER){ - if(!tchdbflushdrp(hdb)) err = true; - if(!tchdbsavefbp(hdb)) err = true; - free(hdb->fbpool); - tchdbsetflag(hdb, HDBFOPEN, false); - } - free(hdb->path); - if((hdb->omode & HDBOWRITER) && !tchdbmemsync(hdb, false)) err = true; - if(munmap(hdb->map, hdb->msiz) == -1){ - tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__); - err = true; - } - if(close(hdb->fd) == -1){ - tchdbsetecode(hdb, TCECLOSE, __FILE__, __LINE__, __func__); - err = true; - } - hdb->path = NULL; - hdb->fd = -1; - return !err; -} - - -/* Store a record. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - `dmode' specifies behavior when the key overlaps. - If successful, the return value is true, else, it is false. */ -static bool tchdbputimpl(TCHDB *hdb, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - int dmode){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(hdb->recc) tcmdbout(hdb->recc, kbuf, ksiz); - uint8_t hash; - uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash); - off_t off = tchdbgetbucket(hdb, bidx); - off_t entoff = 0; - TCHREC rec; - char rbuf[HDBIOBUFSIZ]; - while(off > 0){ - rec.off = off; - if(!tchdbreadrec(hdb, &rec, rbuf)) return false; - if(hash > rec.hash){ - off = rec.left; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)); - } else if(hash < rec.hash){ - off = rec.right; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)) + - (hdb->ba64 ? sizeof(uint64_t) : sizeof(uint32_t)); - } else { - if(!rec.kbuf && !tchdbreadrecbody(hdb, &rec)) return false; - int kcmp = tcreckeycmp(kbuf, ksiz, rec.kbuf, rec.ksiz); - if(kcmp > 0){ - off = rec.left; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)); - } else if(kcmp < 0){ - off = rec.right; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)) + - (hdb->ba64 ? sizeof(uint64_t) : sizeof(uint32_t)); - } else { - switch(dmode){ - case HDBPDKEEP: - free(rec.bbuf); - tchdbsetecode(hdb, TCEKEEP, __FILE__, __LINE__, __func__); - return false; - case HDBPDCAT: - if(vsiz < 1){ - free(rec.bbuf); - return true; - } - if(!rec.vbuf && !tchdbreadrecbody(hdb, &rec)) return false; - int nvsiz = rec.vsiz + vsiz; - if(rec.bbuf){ - TCREALLOC(rec.bbuf, rec.bbuf, rec.ksiz + nvsiz); - memcpy(rec.bbuf + rec.ksiz + rec.vsiz, vbuf, vsiz); - rec.kbuf = rec.bbuf; - rec.vbuf = rec.kbuf + rec.ksiz; - rec.vsiz = nvsiz; - } else { - TCMALLOC(rec.bbuf, nvsiz); - memcpy(rec.bbuf, rec.vbuf, rec.vsiz); - memcpy(rec.bbuf + rec.vsiz, vbuf, vsiz); - rec.vbuf = rec.bbuf; - rec.vsiz = nvsiz; - } - bool rv = tchdbwriterec(hdb, &rec, bidx, entoff); - free(rec.bbuf); - return rv; - default: - break; - } - free(rec.bbuf); - rec.ksiz = ksiz; - rec.vsiz = vsiz; - rec.kbuf = kbuf; - rec.vbuf = vbuf; - return tchdbwriterec(hdb, &rec, bidx, entoff); - } - } - } - rec.rsiz = HDBMAXHSIZ + ksiz + vsiz; - if(!tchdbfbpsearch(hdb, &rec)) return false; - rec.hash = hash; - rec.left = 0; - rec.right = 0; - rec.ksiz = ksiz; - rec.vsiz = vsiz; - rec.psiz = 0; - rec.kbuf = kbuf; - rec.vbuf = vbuf; - if(!tchdbwriterec(hdb, &rec, bidx, entoff)) return false; - hdb->rnum++; - uint64_t llnum = hdb->rnum; - llnum = TCHTOILL(llnum); - memcpy(hdb->map + HDBRNUMOFF, &llnum, sizeof(llnum)); - return true; -} - - -/* Append a record to the delayed record pool. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - `hash' specifies the second hash value. */ -static void tchdbdrpappend(TCHDB *hdb, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - uint8_t hash){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - TCDODEBUG(hdb->cnt_appenddrp++); - char rbuf[HDBIOBUFSIZ]; - char *wp = rbuf; - *(uint8_t *)(wp++) = HDBMAGICREC; - *(uint8_t *)(wp++) = hash; - if(hdb->ba64){ - memset(wp, 0, sizeof(uint64_t) * 2); - wp += sizeof(uint64_t) * 2; - } else { - memset(wp, 0, sizeof(uint32_t) * 2); - wp += sizeof(uint32_t) * 2; - } - uint16_t snum; - char *pwp = wp; - wp += sizeof(snum); - int step; - TCSETVNUMBUF(step, wp, ksiz); - wp += step; - TCSETVNUMBUF(step, wp, vsiz); - wp += step; - int32_t hsiz = wp - rbuf; - int32_t rsiz = hsiz + ksiz + vsiz; - hdb->fsiz += rsiz; - uint16_t psiz = tchdbpadsize(hdb); - hdb->fsiz += psiz; - snum = TCHTOIS(psiz); - memcpy(pwp, &snum, sizeof(snum)); - TCXSTR *drpool = hdb->drpool; - TCXSTRCAT(drpool, rbuf, hsiz); - TCXSTRCAT(drpool, kbuf, ksiz); - TCXSTRCAT(drpool, vbuf, vsiz); - if(psiz > 0){ - char pbuf[psiz]; - memset(pbuf, 0, psiz); - TCXSTRCAT(drpool, pbuf, psiz); - } -} - - -/* Store a record in asynchronus fashion. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. */ -static bool tchdbputasyncimpl(TCHDB *hdb, const char *kbuf, int ksiz, const char *vbuf, int vsiz){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - if(hdb->recc) tcmdbout(hdb->recc, kbuf, ksiz); - if(!hdb->drpool){ - hdb->drpool = tcxstrnew3(HDBDRPUNIT + HDBDRPLAT); - hdb->drpdef = tcxstrnew3(HDBDRPUNIT); - hdb->drpoff = hdb->fsiz; - } - uint8_t hash; - uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash); - off_t off = tchdbgetbucket(hdb, bidx); - off_t entoff = 0; - TCHREC rec; - char rbuf[HDBIOBUFSIZ]; - while(off > 0){ - if(off >= hdb->drpoff - hdb->runit){ - TCDODEBUG(hdb->cnt_deferdrp++); - TCXSTR *drpdef = hdb->drpdef; - TCXSTRCAT(drpdef, &ksiz, sizeof(ksiz)); - TCXSTRCAT(drpdef, &vsiz, sizeof(vsiz)); - TCXSTRCAT(drpdef, kbuf, ksiz); - TCXSTRCAT(drpdef, vbuf, vsiz); - if(TCXSTRSIZE(hdb->drpdef) > HDBDRPUNIT && !tchdbflushdrp(hdb)) return false; - return true; - } - rec.off = off; - if(!tchdbreadrec(hdb, &rec, rbuf)) return false; - if(hash > rec.hash){ - off = rec.left; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)); - } else if(hash < rec.hash){ - off = rec.right; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)) + - (hdb->ba64 ? sizeof(uint64_t) : sizeof(uint32_t)); - } else { - TCDODEBUG(hdb->cnt_deferdrp++); - TCXSTR *drpdef = hdb->drpdef; - TCXSTRCAT(drpdef, &ksiz, sizeof(ksiz)); - TCXSTRCAT(drpdef, &vsiz, sizeof(vsiz)); - TCXSTRCAT(drpdef, kbuf, ksiz); - TCXSTRCAT(drpdef, vbuf, vsiz); - if(TCXSTRSIZE(hdb->drpdef) > HDBDRPUNIT && !tchdbflushdrp(hdb)) return false; - return true; - } - } - if(entoff > 0){ - if(hdb->ba64){ - uint64_t llnum = hdb->fsiz >> hdb->apow; - llnum = TCHTOILL(llnum); - if(!tcseekwrite(hdb, entoff, &llnum, sizeof(uint64_t))) return false; - } else { - uint32_t lnum = hdb->fsiz >> hdb->apow; - lnum = TCHTOIL(lnum); - if(!tcseekwrite(hdb, entoff, &lnum, sizeof(uint32_t))) return false; - } - } else { - tchdbsetbucket(hdb, bidx, hdb->fsiz); - } - tchdbdrpappend(hdb, kbuf, ksiz, vbuf, vsiz, hash); - hdb->rnum++; - if(TCXSTRSIZE(hdb->drpool) > HDBDRPUNIT && !tchdbflushdrp(hdb)) return false; - return true; -} - - -/* Remove a record of a hash database object. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. */ -static bool tchdboutimpl(TCHDB *hdb, const char *kbuf, int ksiz){ - assert(hdb && kbuf && ksiz >= 0); - if(hdb->recc) tcmdbout(hdb->recc, kbuf, ksiz); - uint8_t hash; - uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash); - off_t off = tchdbgetbucket(hdb, bidx); - off_t entoff = 0; - TCHREC rec; - char rbuf[HDBIOBUFSIZ]; - while(off > 0){ - rec.off = off; - if(!tchdbreadrec(hdb, &rec, rbuf)) return false; - if(hash > rec.hash){ - off = rec.left; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)); - } else if(hash < rec.hash){ - off = rec.right; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)) + - (hdb->ba64 ? sizeof(uint64_t) : sizeof(uint32_t)); - } else { - if(!rec.kbuf && !tchdbreadrecbody(hdb, &rec)) return false; - int kcmp = tcreckeycmp(kbuf, ksiz, rec.kbuf, rec.ksiz); - if(kcmp > 0){ - off = rec.left; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)); - } else if(kcmp < 0){ - off = rec.right; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - entoff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t)) + - (hdb->ba64 ? sizeof(uint64_t) : sizeof(uint32_t)); - } else { - free(rec.bbuf); - rec.bbuf = NULL; - if(!tchdbwritefb(hdb, rec.off, rec.rsiz)) return false; - tchdbfbpinsert(hdb, rec.off, rec.rsiz); - uint64_t child; - if(rec.left > 0 && rec.right < 1){ - child = rec.left; - } else if(rec.left < 1 && rec.right > 0){ - child = rec.right; - } else if(rec.left < 1 && rec.left < 1){ - child = 0; - } else { - child = rec.left; - uint64_t right = rec.right; - rec.right = child; - while(rec.right > 0){ - rec.off = rec.right; - if(!tchdbreadrec(hdb, &rec, rbuf)) return false; - } - if(hdb->ba64){ - off_t toff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint64_t)); - uint64_t llnum = right >> hdb->apow; - llnum = TCHTOILL(llnum); - if(!tcseekwrite(hdb, toff, &llnum, sizeof(uint64_t))) return false; - } else { - off_t toff = rec.off + (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t)); - uint32_t lnum = right >> hdb->apow; - lnum = TCHTOIL(lnum); - if(!tcseekwrite(hdb, toff, &lnum, sizeof(uint32_t))) return false; - } - } - if(entoff > 0){ - if(hdb->ba64){ - uint64_t llnum = child >> hdb->apow; - llnum = TCHTOILL(llnum); - if(!tcseekwrite(hdb, entoff, &llnum, sizeof(uint64_t))) return false; - } else { - uint32_t lnum = child >> hdb->apow; - lnum = TCHTOIL(lnum); - if(!tcseekwrite(hdb, entoff, &lnum, sizeof(uint32_t))) return false; - } - } else { - tchdbsetbucket(hdb, bidx, child); - } - hdb->rnum--; - uint64_t llnum = hdb->rnum; - llnum = TCHTOILL(llnum); - memcpy(hdb->map + HDBRNUMOFF, &llnum, sizeof(llnum)); - return true; - } - } - } - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; -} - - -/* Retrieve a record in a hash database object. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the corresponding - record. */ -static char *tchdbgetimpl(TCHDB *hdb, const char *kbuf, int ksiz, int *sp){ - assert(hdb && kbuf && ksiz >= 0 && sp); - if(hdb->recc){ - int tvsiz; - char *tvbuf = tcmdbget(hdb->recc, kbuf, ksiz, &tvsiz); - if(tvbuf){ - if(*tvbuf == '*'){ - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - free(tvbuf); - return NULL; - } - *sp = tvsiz - 1; - memmove(tvbuf, tvbuf + 1, tvsiz); - return tvbuf; - } - } - uint8_t hash; - uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash); - off_t off = tchdbgetbucket(hdb, bidx); - TCHREC rec; - char rbuf[HDBIOBUFSIZ]; - while(off > 0){ - rec.off = off; - if(!tchdbreadrec(hdb, &rec, rbuf)) return NULL; - if(hash > rec.hash){ - off = rec.left; - } else if(hash < rec.hash){ - off = rec.right; - } else { - if(!rec.kbuf && !tchdbreadrecbody(hdb, &rec)) return NULL; - int kcmp = tcreckeycmp(kbuf, ksiz, rec.kbuf, rec.ksiz); - if(kcmp > 0){ - off = rec.left; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - } else if(kcmp < 0){ - off = rec.right; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - } else { - if(!rec.vbuf && !tchdbreadrecbody(hdb, &rec)) return NULL; - if(hdb->zmode){ - int zsiz; - char *zbuf; - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_inflate(rec.vbuf, rec.vsiz, &zsiz, _TCZMRAW); - } else { - zbuf = tcbsdecode(rec.vbuf, rec.vsiz, &zsiz); - } - free(rec.bbuf); - if(!zbuf){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - return NULL; - } - if(hdb->recc){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput3(hdb->recc, kbuf, ksiz, "=", 1, zbuf, zsiz); - } - *sp = zsiz; - return zbuf; - } - if(rec.bbuf){ - memmove(rec.bbuf, rec.vbuf, rec.vsiz); - rec.bbuf[rec.vsiz] = '\0'; - *sp = rec.vsiz; - return rec.bbuf; - } - if(hdb->recc){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput3(hdb->recc, kbuf, ksiz, "=", 1, rec.vbuf, rec.vsiz); - } - *sp = rec.vsiz; - char *rv; - TCMEMDUP(rv, rec.vbuf, rec.vsiz); - return rv; - } - } - } - if(hdb->recc){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput(hdb->recc, kbuf, ksiz, "*", 1); - } - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - return NULL; -} - - -/* Retrieve a record in a hash database object and write the value into a buffer. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the buffer into which the value of the corresponding record is - written. - `max' specifies the size of the buffer. - If successful, the return value is the size of the written data, else, it is -1. */ -static int tchdbgetintobuf(TCHDB *hdb, const char *kbuf, int ksiz, char *vbuf, int max){ - assert(hdb && kbuf && ksiz >= 0 && vbuf && max >= 0); - if(hdb->recc){ - int tvsiz; - char *tvbuf = tcmdbget(hdb->recc, kbuf, ksiz, &tvsiz); - if(tvbuf){ - if(*tvbuf == '*'){ - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - free(tvbuf); - return -1; - } - tvsiz = tclmin(tvsiz - 1, max); - memcpy(vbuf, tvbuf + 1, tvsiz); - free(tvbuf); - return tvsiz; - } - } - uint8_t hash; - uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash); - off_t off = tchdbgetbucket(hdb, bidx); - TCHREC rec; - char rbuf[HDBIOBUFSIZ]; - while(off > 0){ - rec.off = off; - if(!tchdbreadrec(hdb, &rec, rbuf)) return -1; - if(hash > rec.hash){ - off = rec.left; - } else if(hash < rec.hash){ - off = rec.right; - } else { - if(!rec.kbuf && !tchdbreadrecbody(hdb, &rec)) return -1; - int kcmp = tcreckeycmp(kbuf, ksiz, rec.kbuf, rec.ksiz); - if(kcmp > 0){ - off = rec.left; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - } else if(kcmp < 0){ - off = rec.right; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - } else { - if(!rec.vbuf && !tchdbreadrecbody(hdb, &rec)) return -1; - if(hdb->zmode){ - int zsiz; - char *zbuf; - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_inflate(rec.vbuf, rec.vsiz, &zsiz, _TCZMRAW); - } else { - zbuf = tcbsdecode(rec.vbuf, rec.vsiz, &zsiz); - } - free(rec.bbuf); - if(!zbuf){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - return -1; - } - if(hdb->recc){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput3(hdb->recc, kbuf, ksiz, "=", 1, zbuf, zsiz); - } - zsiz = tclmin(zsiz, max); - memcpy(vbuf, zbuf, zsiz); - free(zbuf); - return zsiz; - } - if(hdb->recc){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput3(hdb->recc, kbuf, ksiz, "=", 1, rec.vbuf, rec.vsiz); - } - int vsiz = tclmin(rec.vsiz, max); - memcpy(vbuf, rec.vbuf, vsiz); - free(rec.bbuf); - return vsiz; - } - } - } - if(hdb->recc){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput(hdb->recc, kbuf, ksiz, "*", 1); - } - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - return -1; -} - - -/* Get the size of the value of a record in a hash database object. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. */ -static int tchdbvsizimpl(TCHDB *hdb, const char *kbuf, int ksiz){ - assert(hdb && kbuf && ksiz >= 0); - if(hdb->recc){ - int tvsiz; - char *tvbuf = tcmdbget(hdb->recc, kbuf, ksiz, &tvsiz); - if(tvbuf){ - if(*tvbuf == '*'){ - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - free(tvbuf); - return -1; - } - free(tvbuf); - return tvsiz - 1; - } - } - uint8_t hash; - uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash); - off_t off = tchdbgetbucket(hdb, bidx); - TCHREC rec; - char rbuf[HDBIOBUFSIZ]; - while(off > 0){ - rec.off = off; - if(!tchdbreadrec(hdb, &rec, rbuf)) return -1; - if(hash > rec.hash){ - off = rec.left; - } else if(hash < rec.hash){ - off = rec.right; - } else { - if(!rec.kbuf && !tchdbreadrecbody(hdb, &rec)) return -1; - int kcmp = tcreckeycmp(kbuf, ksiz, rec.kbuf, rec.ksiz); - if(kcmp > 0){ - off = rec.left; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - } else if(kcmp < 0){ - off = rec.right; - free(rec.bbuf); - rec.kbuf = NULL; - rec.bbuf = NULL; - } else { - if(hdb->zmode){ - if(!rec.vbuf && !tchdbreadrecbody(hdb, &rec)) return -1; - int zsiz; - char *zbuf; - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_inflate(rec.vbuf, rec.vsiz, &zsiz, _TCZMRAW); - } else { - zbuf = tcbsdecode(rec.vbuf, rec.vsiz, &zsiz); - } - free(rec.bbuf); - if(!zbuf){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - return -1; - } - if(hdb->recc){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput3(hdb->recc, kbuf, ksiz, "=", 1, zbuf, zsiz); - } - free(zbuf); - return zsiz; - } - if(hdb->recc && rec.vbuf){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput3(hdb->recc, kbuf, ksiz, "=", 1, rec.vbuf, rec.vsiz); - } - free(rec.bbuf); - return rec.vsiz; - } - } - } - if(hdb->recc){ - if(tcmdbrnum(hdb->recc) >= hdb->rcnum) tchdbcacheadjust(hdb); - tcmdbput(hdb->recc, kbuf, ksiz, "*", 1); - } - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - return -1; -} - - -/* Initialize the iterator of a hash database object. - `hdb' specifies the hash database object. - If successful, the return value is true, else, it is false. */ -static bool tchdbiterinitimpl(TCHDB *hdb){ - assert(hdb); - hdb->iter = hdb->frec; - return true; -} - - -/* Get the next key of the iterator of a hash database object. - `hdb' specifies the hash database object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the next key, else, it is - `NULL'. */ -static char *tchdbiternextimpl(TCHDB *hdb, int *sp){ - assert(hdb && sp); - TCHREC rec; - char rbuf[HDBIOBUFSIZ]; - while(hdb->iter < hdb->fsiz){ - rec.off = hdb->iter; - if(!tchdbreadrec(hdb, &rec, rbuf)) return NULL; - hdb->iter += rec.rsiz; - if(rec.magic == HDBMAGICREC){ - if(rec.kbuf){ - *sp = rec.ksiz; - char *rv; - TCMEMDUP(rv, rec.kbuf, rec.ksiz); - return rv; - } - if(!tchdbreadrecbody(hdb, &rec)) return NULL; - rec.bbuf[rec.ksiz] = '\0'; - *sp = rec.ksiz; - return rec.bbuf; - } - } - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - return NULL; -} - - -/* Get the next extensible objects of the iterator of a hash database object. */ -static bool tchdbiternextintoxstr(TCHDB *hdb, TCXSTR *kxstr, TCXSTR *vxstr){ - assert(hdb && kxstr && vxstr); - TCHREC rec; - char rbuf[HDBIOBUFSIZ]; - while(hdb->iter < hdb->fsiz){ - rec.off = hdb->iter; - if(!tchdbreadrec(hdb, &rec, rbuf)) return false; - hdb->iter += rec.rsiz; - if(rec.magic == HDBMAGICREC){ - if(!rec.vbuf && !tchdbreadrecbody(hdb, &rec)) return false; - tcxstrclear(kxstr); - TCXSTRCAT(kxstr, rec.kbuf, rec.ksiz); - tcxstrclear(vxstr); - if(hdb->zmode){ - int zsiz; - char *zbuf; - if(hdb->opts & HDBTDEFLATE){ - zbuf = _tc_inflate(rec.vbuf, rec.vsiz, &zsiz, _TCZMRAW); - } else { - zbuf = tcbsdecode(rec.vbuf, rec.vsiz, &zsiz); - } - if(!zbuf){ - tchdbsetecode(hdb, TCEMISC, __FILE__, __LINE__, __func__); - free(rec.bbuf); - return false; - } - TCXSTRCAT(vxstr, zbuf, zsiz); - free(zbuf); - } else { - TCXSTRCAT(vxstr, rec.vbuf, rec.vsiz); - } - free(rec.bbuf); - return true; - } - } - tchdbsetecode(hdb, TCENOREC, __FILE__, __LINE__, __func__); - return false; -} - - -/* Optimize the file of a hash database object. - `hdb' specifies the hash database object. - `bnum' specifies the number of elements of the bucket array. - `apow' specifies the size of record alignment by power of 2. - `fpow' specifies the maximum number of elements of the free block pool by power of 2. - `opts' specifies options by bitwise or. - If successful, the return value is true, else, it is false. */ -static bool tchdboptimizeimpl(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){ - assert(hdb); - if(bnum < 1){ - bnum = hdb->rnum * 2 + 1; - if(bnum < HDBDEFBNUM) bnum = HDBDEFBNUM; - } - if(apow < 0) apow = hdb->apow; - if(fpow < 0) fpow = hdb->fpow; - if(opts == UINT8_MAX) opts = hdb->opts; - char *tpath = tcsprintf("%s%ctmp%c%llu", hdb->path, MYEXTCHR, MYEXTCHR, hdb->inode); - TCHDB *thdb = tchdbnew(); - tchdbtune(thdb, bnum, apow, fpow, opts); - if(!tchdbopen(thdb, tpath, HDBOWRITER | HDBOCREAT | HDBOTRUNC)){ - tchdbsetecode(hdb, thdb->ecode, __FILE__, __LINE__, __func__); - tchdbdel(thdb); - free(tpath); - return false; - } - bool err = false; - if(!tchdbiterinitimpl(hdb)) err = true; - TCXSTR *key = tcxstrnew(); - TCXSTR *val = tcxstrnew(); - while(!err && tchdbiternextintoxstr(hdb, key, val)){ - if(!tchdbputkeep(thdb, TCXSTRPTR(key), TCXSTRSIZE(key), TCXSTRPTR(val), TCXSTRSIZE(val))){ - tchdbsetecode(hdb, thdb->ecode, __FILE__, __LINE__, __func__); - err = true; - } - } - tcxstrdel(val); - tcxstrdel(key); - if(!tchdbclose(thdb)){ - tchdbsetecode(hdb, thdb->ecode, __FILE__, __LINE__, __func__); - err = true; - } - tchdbdel(thdb); - if(unlink(hdb->path) == -1){ - tchdbsetecode(hdb, TCEUNLINK, __FILE__, __LINE__, __func__); - err = true; - } - if(rename(tpath, hdb->path) == -1){ - tchdbsetecode(hdb, TCERENAME, __FILE__, __LINE__, __func__); - err = true; - } - free(tpath); - if(err) return false; - tpath = tcstrdup(hdb->path); - int omode = (hdb->omode & ~HDBOCREAT) & ~HDBOTRUNC; - if(!tchdbcloseimpl(hdb)){ - free(tpath); - return false; - } - bool rv = tchdbopenimpl(hdb, tpath, omode); - free(tpath); - return rv; -} - - -/* Remove all records of a hash database object. - `hdb' specifies the hash database object. - If successful, the return value is true, else, it is false. */ -static bool tchdbvanishimpl(TCHDB *hdb){ - assert(hdb); - char *path = tcstrdup(hdb->path); - int omode = hdb->omode; - bool err = false; - if(!tchdbcloseimpl(hdb)) err = true; - if(!tchdbopenimpl(hdb, path, HDBOTRUNC | omode)) err = true; - free(path); - return !err; -} - - -/* Lock a method of the hash database object. - `hdb' specifies the hash database object. - `wr' specifies whether the lock is writer or not. - If successful, the return value is true, else, it is false. */ -static bool tchdblockmethod(TCHDB *hdb, bool wr){ - assert(hdb); - if(wr ? pthread_rwlock_wrlock(hdb->mmtx) != 0 : pthread_rwlock_rdlock(hdb->mmtx) != 0){ - tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Unlock a method of the hash database object. - `hdb' specifies the hash database object. - If successful, the return value is true, else, it is false. */ -static bool tchdbunlockmethod(TCHDB *hdb){ - assert(hdb); - if(pthread_rwlock_unlock(hdb->mmtx) != 0){ - tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Lock the delayed record pool of the hash database object. - `hdb' specifies the hash database object. - If successful, the return value is true, else, it is false. */ -static bool tchdblockdrp(TCHDB *hdb){ - assert(hdb); - if(pthread_mutex_lock(hdb->dmtx) != 0){ - tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - -/* Unlock the delayed record pool of the hash database object. - `hdb' specifies the hash database object. - If successful, the return value is true, else, it is false. */ -static bool tchdbunlockdrp(TCHDB *hdb){ - assert(hdb); - if(pthread_mutex_unlock(hdb->dmtx) != 0){ - tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__); - return false; - } - TCTESTYIELD(); - return true; -} - - - -/************************************************************************************************* - * debugging functions - *************************************************************************************************/ - - -/* Print meta data of the header into the debugging output. - `hdb' specifies the hash database object. */ -void tchdbprintmeta(TCHDB *hdb){ - assert(hdb); - if(hdb->dbgfd < 0) return; - char buf[HDBIOBUFSIZ]; - char *wp = buf; - wp += sprintf(wp, "META:"); - wp += sprintf(wp, " mmtx=%p", (void *)hdb->mmtx); - wp += sprintf(wp, " dmtx=%p", (void *)hdb->dmtx); - wp += sprintf(wp, " eckey=%p", (void *)hdb->eckey); - wp += sprintf(wp, " type=%02X", hdb->type); - wp += sprintf(wp, " flags=%02X", hdb->flags); - wp += sprintf(wp, " bnum=%llu", (unsigned long long)hdb->bnum); - wp += sprintf(wp, " apow=%u", hdb->apow); - wp += sprintf(wp, " fpow=%u", hdb->fpow); - wp += sprintf(wp, " opts=%u", hdb->opts); - wp += sprintf(wp, " path=%s", hdb->path ? hdb->path : "-"); - wp += sprintf(wp, " fd=%u", hdb->fd); - wp += sprintf(wp, " omode=%u", hdb->omode); - wp += sprintf(wp, " rnum=%llu", (unsigned long long)hdb->rnum); - wp += sprintf(wp, " fsiz=%llu", (unsigned long long)hdb->fsiz); - wp += sprintf(wp, " frec=%llu", (unsigned long long)hdb->frec); - wp += sprintf(wp, " iter=%llu", (unsigned long long)hdb->iter); - wp += sprintf(wp, " map=%p", (void *)hdb->map); - wp += sprintf(wp, " msiz=%llu", (unsigned long long)hdb->msiz); - wp += sprintf(wp, " ba32=%p", (void *)hdb->ba32); - wp += sprintf(wp, " ba64=%p", (void *)hdb->ba64); - wp += sprintf(wp, " align=%u", hdb->align); - wp += sprintf(wp, " runit=%u", hdb->runit); - wp += sprintf(wp, " zmode=%u", hdb->zmode); - wp += sprintf(wp, " fbpmax=%d", hdb->fbpmax); - wp += sprintf(wp, " fbpsiz=%d", hdb->fbpsiz); - wp += sprintf(wp, " fbpool=%p", (void *)hdb->fbpool); - wp += sprintf(wp, " fbpnum=%d", hdb->fbpnum); - wp += sprintf(wp, " fbpmis=%d", hdb->fbpmis); - wp += sprintf(wp, " drpool=%p", (void *)hdb->drpool); - wp += sprintf(wp, " drpdef=%p", (void *)hdb->drpdef); - wp += sprintf(wp, " drpoff=%llu", (unsigned long long)hdb->drpoff); - wp += sprintf(wp, " recc=%p", (void *)hdb->recc); - wp += sprintf(wp, " rcnum=%u", hdb->rcnum); - wp += sprintf(wp, " ecode=%d", hdb->ecode); - wp += sprintf(wp, " fatal=%u", hdb->fatal); - wp += sprintf(wp, " inode=%llu", (unsigned long long)(uint64_t)hdb->inode); - wp += sprintf(wp, " mtime=%llu", (unsigned long long)(uint64_t)hdb->mtime); - wp += sprintf(wp, " dbgfd=%d", hdb->dbgfd); - wp += sprintf(wp, " cnt_writerec=%lld", (long long)hdb->cnt_writerec); - wp += sprintf(wp, " cnt_reuserec=%lld", (long long)hdb->cnt_reuserec); - wp += sprintf(wp, " cnt_moverec=%lld", (long long)hdb->cnt_moverec); - wp += sprintf(wp, " cnt_readrec=%lld", (long long)hdb->cnt_readrec); - wp += sprintf(wp, " cnt_searchfbp=%lld", (long long)hdb->cnt_searchfbp); - wp += sprintf(wp, " cnt_insertfbp=%lld", (long long)hdb->cnt_insertfbp); - wp += sprintf(wp, " cnt_splicefbp=%lld", (long long)hdb->cnt_splicefbp); - wp += sprintf(wp, " cnt_dividefbp=%lld", (long long)hdb->cnt_dividefbp); - wp += sprintf(wp, " cnt_mergefbp=%lld", (long long)hdb->cnt_mergefbp); - wp += sprintf(wp, " cnt_reducefbp=%lld", (long long)hdb->cnt_reducefbp); - wp += sprintf(wp, " cnt_appenddrp=%lld", (long long)hdb->cnt_appenddrp); - wp += sprintf(wp, " cnt_deferdrp=%lld", (long long)hdb->cnt_deferdrp); - wp += sprintf(wp, " cnt_flushdrp=%lld", (long long)hdb->cnt_flushdrp); - wp += sprintf(wp, " cnt_adjrecc=%lld", (long long)hdb->cnt_adjrecc); - *(wp++) = '\n'; - tcwrite(hdb->dbgfd, buf, wp - buf); -} - - -/* Print a record information into the debugging output. - `hdb' specifies the hash database object. - `rec' specifies the record. */ -void tchdbprintrec(TCHDB *hdb, TCHREC *rec){ - assert(hdb && rec); - if(hdb->dbgfd < 0) return; - char buf[HDBIOBUFSIZ]; - char *wp = buf; - wp += sprintf(wp, "REC:"); - wp += sprintf(wp, " off=%llu", (unsigned long long)rec->off); - wp += sprintf(wp, " rsiz=%u", rec->rsiz); - wp += sprintf(wp, " magic=%02X", rec->magic); - wp += sprintf(wp, " hash=%02X", rec->hash); - wp += sprintf(wp, " left=%llu", (unsigned long long)rec->left); - wp += sprintf(wp, " right=%llu", (unsigned long long)rec->right); - wp += sprintf(wp, " ksiz=%u", rec->ksiz); - wp += sprintf(wp, " vsiz=%u", rec->vsiz); - wp += sprintf(wp, " psiz=%u", rec->psiz); - wp += sprintf(wp, " kbuf=%p", (void *)rec->kbuf); - wp += sprintf(wp, " vbuf=%p", (void *)rec->vbuf); - wp += sprintf(wp, " boff=%llu", (unsigned long long)rec->boff); - wp += sprintf(wp, " bbuf=%p", (void *)rec->bbuf); - *(wp++) = '\n'; - tcwrite(hdb->dbgfd, buf, wp - buf); -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tchdb.h b/bacula/src/lib/tokyocabinet/tchdb.h deleted file mode 100644 index 9a20762935..0000000000 --- a/bacula/src/lib/tokyocabinet/tchdb.h +++ /dev/null @@ -1,649 +0,0 @@ -/************************************************************************************************* - * The hash database API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#ifndef _TCHDB_H /* duplication check */ -#define _TCHDB_H - -#if defined(__cplusplus) -#define __TCHDB_CLINKAGEBEGIN extern "C" { -#define __TCHDB_CLINKAGEEND } -#else -#define __TCHDB_CLINKAGEBEGIN -#define __TCHDB_CLINKAGEEND -#endif -__TCHDB_CLINKAGEBEGIN - - -#include -#include -#include -#include -#include - - - -/************************************************************************************************* - * API - *************************************************************************************************/ - - -typedef struct { /* type of structure for a hash database */ - void *mmtx; /* mutex for method */ - void *dmtx; /* mutex for DRP */ - void *eckey; /* key for thread specific error code */ - uint8_t type; /* database type */ - uint8_t flags; /* additional flags */ - uint64_t bnum; /* number of the bucket array */ - uint8_t apow; /* power of record alignment */ - uint8_t fpow; /* power of free block pool number */ - uint8_t opts; /* options */ - char *path; /* path of the database file */ - int fd; /* file descriptor of the database file */ - uint32_t omode; /* connection mode */ - uint64_t rnum; /* number of the records */ - uint64_t fsiz; /* size of the database file */ - uint64_t frec; /* offset of the first record */ - uint64_t lrec; /* offset of the last record */ - uint64_t iter; /* offset of the iterator */ - char *map; /* pointer to the mapped memory */ - uint64_t msiz; /* size of the mapped memory */ - uint32_t *ba32; /* 32-bit bucket array */ - uint64_t *ba64; /* 64-bit bucket array */ - uint32_t align; /* record alignment */ - uint32_t runit; /* record reading unit */ - bool zmode; /* whether compression is used */ - int32_t fbpmax; /* maximum number of the free block pool */ - int32_t fbpsiz; /* size of the free block pool */ - void *fbpool; /* free block pool */ - int32_t fbpnum; /* number of the free block pool */ - int32_t fbpmis; /* number of missing retrieval of the free block pool */ - bool async; /* whether asynchronous storing is called */ - TCXSTR *drpool; /* delayed record pool */ - TCXSTR *drpdef; /* deferred records of the delayed record pool */ - uint64_t drpoff; /* offset of the delayed record pool */ - TCMDB *recc; /* cache for records */ - uint32_t rcnum; /* max number of cached records */ - int ecode; /* last happened error code */ - bool fatal; /* whether a fatal error occured */ - uint64_t inode; /* inode number */ - time_t mtime; /* modification time */ - int dbgfd; /* file descriptor for debugging */ - int64_t cnt_writerec; /* tesing counter for record write times */ - int64_t cnt_reuserec; /* tesing counter for record reuse times */ - int64_t cnt_moverec; /* tesing counter for record move times */ - int64_t cnt_readrec; /* tesing counter for record read times */ - int64_t cnt_searchfbp; /* tesing counter for FBP search times */ - int64_t cnt_insertfbp; /* tesing counter for FBP insert times */ - int64_t cnt_splicefbp; /* tesing counter for FBP splice times */ - int64_t cnt_dividefbp; /* tesing counter for FBP divide times */ - int64_t cnt_mergefbp; /* tesing counter for FBP merge times */ - int64_t cnt_reducefbp; /* tesing counter for FBP reduce times */ - int64_t cnt_appenddrp; /* tesing counter for DRP append times */ - int64_t cnt_deferdrp; /* tesing counter for DRP defer times */ - int64_t cnt_flushdrp; /* tesing counter for DRP flush times */ - int64_t cnt_adjrecc; /* tesing counter for record cache adjust times */ -} TCHDB; - -enum { /* enumeration for error codes */ - TCESUCCESS, /* success */ - TCETHREAD, /* threading error */ - TCEINVALID, /* invalid operation */ - TCENOFILE, /* file not found */ - TCENOPERM, /* no permission */ - TCEMETA, /* invalid meta data */ - TCERHEAD, /* invalid record header */ - TCEOPEN, /* open error */ - TCECLOSE, /* close error */ - TCETRUNC, /* trunc error */ - TCESYNC, /* sync error */ - TCESTAT, /* stat error */ - TCESEEK, /* seek error */ - TCEREAD, /* read error */ - TCEWRITE, /* write error */ - TCEMMAP, /* mmap error */ - TCELOCK, /* lock error */ - TCEUNLINK, /* unlink error */ - TCERENAME, /* rename error */ - TCEMKDIR, /* mkdir error */ - TCERMDIR, /* rmdir error */ - TCEKEEP, /* existing record */ - TCENOREC, /* no record found */ - TCEMISC = 9999 /* miscellaneous error */ -}; - -enum { /* enumeration for database type */ - HDBTHASH, /* hash table */ - HDBTBTREE /* B+ tree */ -}; - -enum { /* enumeration for additional flags */ - HDBFOPEN = 1 << 0, /* whether opened */ - HDBFFATAL = 1 << 1 /* whetehr with fatal error */ -}; - -enum { /* enumeration for tuning options */ - HDBTLARGE = 1 << 0, /* use 64-bit bucket array */ - HDBTDEFLATE = 1 << 1, /* compress each record with Deflate */ - HDBTTCBS = 1 << 2 /* compress each record with TCBS */ -}; - -enum { /* enumeration for open modes */ - HDBOREADER = 1 << 0, /* open as a reader */ - HDBOWRITER = 1 << 1, /* open as a writer */ - HDBOCREAT = 1 << 2, /* writer creating */ - HDBOTRUNC = 1 << 3, /* writer truncating */ - HDBONOLCK = 1 << 4, /* open without locking */ - HDBOLCKNB = 1 << 5 /* lock without blocking */ -}; - - -/* Get the message string corresponding to an error code. - `ecode' specifies the error code. - The return value is the message string of the error code. */ -const char *tchdberrmsg(int ecode); - - -/* Create a hash database object. - The return value is the new hash database object. */ -TCHDB *tchdbnew(void); - - -/* Delete a hash database object. - `hdb' specifies the hash database object. - If the database is not closed, it is closed implicitly. Note that the deleted object and its - derivatives can not be used anymore. */ -void tchdbdel(TCHDB *hdb); - - -/* Get the last happened error code of a hash database object. - `hdb' specifies the hash database object. - The return value is the last happened error code. - The following error code is defined: `TCESUCCESS' for success, `TCETHREAD' for threading - error, `TCEINVALID' for invalid operation, `TCENOFILE' for file not found, `TCENOPERM' for no - permission, `TCEMETA' for invalid meta data, `TCERHEAD' for invalid record header, `TCEOPEN' - for open error, `TCECLOSE' for close error, `TCETRUNC' for trunc error, `TCESYNC' for sync - error, `TCESTAT' for stat error, `TCESEEK' for seek error, `TCEREAD' for read error, - `TCEWRITE' for write error, `TCEMMAP' for mmap error, `TCELOCK' for lock error, `TCEUNLINK' - for unlink error, `TCERENAME' for rename error, `TCEMKDIR' for mkdir error, `TCERMDIR' for - rmdir error, `TCEKEEP' for existing record, `TCENOREC' for no record found, and `TCEMISC' for - miscellaneous error. */ -int tchdbecode(TCHDB *hdb); - - -/* Set mutual exclusion control of a hash database object for threading. - `hdb' specifies the hash database object which is not opened. - If successful, the return value is true, else, it is false. - Note that the mutual exclusion control is needed if the object is shared by plural threads and - this function should should be called before the database is opened. */ -bool tchdbsetmutex(TCHDB *hdb); - - -/* Set the tuning parameters of a hash database object. - `hdb' specifies the hash database object which is not opened. - `bnum' specifies the number of elements of the bucket array. If it is not more than 0, the - default value is specified. The default value is 16381. Suggested size of the bucket array - is about from 0.5 to 4 times of the number of all records to be stored. - `apow' specifies the size of record alignment by power of 2. If it is negative, the default - value is specified. The default value is 4 standing for 2^4=16. - `fpow' specifies the maximum number of elements of the free block pool by power of 2. If it - is negative, the default value is specified. The default value is 10 standing for 2^10=1024. - `opts' specifies options by bitwise or: `HDBTLARGE' specifies that the size of the database - can be larger than 2GB by using 64-bit bucket array, `HDBTDEFLATE' specifies that each record - is compressed with Deflate encoding, `HDBTTCBS' specifies that each record is compressed with - TCBS encoding. - If successful, the return value is true, else, it is false. - Note that the tuning parameters should be set before the database is opened. */ -bool tchdbtune(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts); - - -/* Set the caching parameters of a hash database object. - `hdb' specifies the hash database object which is not opened. - `rcnum' specifies the maximum number of records to be cached. If it is not more than 0, the - record cache is disabled. It is disabled by default. - If successful, the return value is true, else, it is false. - Note that the caching parameters should be set before the database is opened. */ -bool tchdbsetcache(TCHDB *hdb, int32_t rcnum); - - -/* Open a database file and connect a hash database object. - `hdb' specifies the hash database object which is not opened. - `path' specifies the path of the database file. - `omode' specifies the connection mode: `HDBOWRITER' as a writer, `HDBOREADER' as a reader. - If the mode is `HDBOWRITER', the following may be added by bitwise or: `HDBOCREAT', which - means it creates a new database if not exist, `HDBOTRUNC', which means it creates a new - database regardless if one exists. Both of `HDBOREADER' and `HDBOWRITER' can be added to by - bitwise or: `HDBONOLCK', which means it opens the database file without file locking, or - `HDBOLCKNB', which means locking is performed without blocking. - If successful, the return value is true, else, it is false. */ -bool tchdbopen(TCHDB *hdb, const char *path, int omode); - - -/* Close a hash database object. - `hdb' specifies the hash database object. - If successful, the return value is true, else, it is false. - Update of a database is assured to be written when the database is closed. If a writer opens - a database but does not close it appropriately, the database will be broken. */ -bool tchdbclose(TCHDB *hdb); - - -/* Store a record into a hash database object. - `hdb' specifies the hash database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, it is overwritten. */ -bool tchdbput(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a string record into a hash database object. - `hdb' specifies the hash database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, it is overwritten. */ -bool tchdbput2(TCHDB *hdb, const char *kstr, const char *vstr); - - -/* Store a new record into a hash database object. - `hdb' specifies the hash database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tchdbputkeep(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a new string record into a hash database object. - `hdb' specifies the hash database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tchdbputkeep2(TCHDB *hdb, const char *kstr, const char *vstr); - - -/* Concatenate a value at the end of the existing record in a hash database object. - `hdb' specifies the hash database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If there is no corresponding record, a new record is created. */ -bool tchdbputcat(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Concatenate a string value at the end of the existing record in a hash database object. - `hdb' specifies the hash database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If there is no corresponding record, a new record is created. */ -bool tchdbputcat2(TCHDB *hdb, const char *kstr, const char *vstr); - - -/* Store a record into a hash database object in asynchronous fashion. - `hdb' specifies the hash database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, it is overwritten. Records passed to - this function are accumulated into the inner buffer and wrote into the file at a blast. */ -bool tchdbputasync(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a string record into a hash database object in asynchronous fashion. - `hdb' specifies the hash database object connected as a writer. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, it is overwritten. Records passed to - this function are accumulated into the inner buffer and wrote into the file at a blast. */ -bool tchdbputasync2(TCHDB *hdb, const char *kstr, const char *vstr); - - -/* Remove a record of a hash database object. - `hdb' specifies the hash database object connected as a writer. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true, else, it is false. */ -bool tchdbout(TCHDB *hdb, const void *kbuf, int ksiz); - - -/* Remove a string record of a hash database object. - `hdb' specifies the hash database object connected as a writer. - `kstr' specifies the string of the key. - If successful, the return value is true, else, it is false. */ -bool tchdbout2(TCHDB *hdb, const char *kstr); - - -/* Retrieve a record in a hash database object. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the corresponding - record. `NULL' is returned if no record corresponds. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -void *tchdbget(TCHDB *hdb, const void *kbuf, int ksiz, int *sp); - - -/* Retrieve a string record in a hash database object. - `hdb' specifies the hash database object. - `kstr' specifies the string of the key. - If successful, the return value is the string of the value of the corresponding record. - `NULL' is returned if no record corresponds. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tchdbget2(TCHDB *hdb, const char *kstr); - - -/* Retrieve a record in a hash database object and write the value into a buffer. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the buffer into which the value of the corresponding record is - written. - `max' specifies the size of the buffer. - If successful, the return value is the size of the written data, else, it is -1. -1 is - returned if no record corresponds to the specified key. - Note that an additional zero code is not appended at the end of the region of the writing - buffer. */ -int tchdbget3(TCHDB *hdb, const void *kbuf, int ksiz, void *vbuf, int max); - - -/* Get the size of the value of a record in a hash database object. - `hdb' specifies the hash database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. */ -int tchdbvsiz(TCHDB *hdb, const void *kbuf, int ksiz); - - -/* Get the size of the value of a string record in a hash database object. - `hdb' specifies the hash database object. - `kstr' specifies the string of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. */ -int tchdbvsiz2(TCHDB *hdb, const char *kstr); - - -/* Initialize the iterator of a hash database object. - `hdb' specifies the hash database object. - If successful, the return value is true, else, it is false. - The iterator is used in order to access the key of every record stored in a database. */ -bool tchdbiterinit(TCHDB *hdb); - - -/* Get the next key of the iterator of a hash database object. - `hdb' specifies the hash database object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the next key, else, it is - `NULL'. `NULL' is returned when no record is to be get out of the iterator. - Because an additional zero code is appended at the end of the region of the return value, the - return value can be treated as a character string. Because the region of the return value is - allocated with the `malloc' call, it should be released with the `free' call when it is no - longer in use. It is possible to access every record by iteration of calling this function. - It is allowed to update or remove records whose keys are fetched while the iteration. - However, it is not assured if updating the database is occurred while the iteration. Besides, - the order of this traversal access method is arbitrary, so it is not assured that the order of - storing matches the one of the traversal access. */ -void *tchdbiternext(TCHDB *hdb, int *sp); - - -/* Get the next key string of the iterator of a hash database object. - `hdb' specifies the hash database object. - If successful, the return value is the string of the next key, else, it is `NULL'. `NULL' is - returned when no record is to be get out of the iterator. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. It is possible to access every - record by iteration of calling this function. However, it is not assured if updating the - database is occurred while the iteration. Besides, the order of this traversal access method - is arbitrary, so it is not assured that the order of storing matches the one of the traversal - access. */ -char *tchdbiternext2(TCHDB *hdb); - - -/* Get the next extensible objects of the iterator of a hash database object. - `hdb' specifies the hash database object. - `kxstr' specifies the object into which the next key is wrote down. - `vxstr' specifies the object into which the next value is wrote down. - If successful, the return value is true, else, it is false. False is returned when no record - is to be get out of the iterator. */ -bool tchdbiternext3(TCHDB *hdb, TCXSTR *kxstr, TCXSTR *vxstr); - - -/* Get forward matching keys in a hash database object. - `hdb' specifies the hash database object. - `pbuf' specifies the pointer to the region of the prefix. - `psiz' specifies the size of the region of the prefix. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the corresponding keys. This function does never fail - and return an empty list even if no key corresponds. - Because the object of the return value is created with the function `tclistnew', it should be - deleted with the function `tclistdel' when it is no longer in use. Note that this function - may be very slow because every key in the database is scanned. */ -TCLIST *tchdbfwmkeys(TCHDB *hdb, const void *pbuf, int psiz, int max); - - -/* Get forward matching string keys in a hash database object. - `hdb' specifies the hash database object. - `pstr' specifies the string of the prefix. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the corresponding keys. This function does never fail - and return an empty list even if no key corresponds. - Because the object of the return value is created with the function `tclistnew', it should be - deleted with the function `tclistdel' when it is no longer in use. Note that this function - may be very slow because every key in the database is scanned. */ -TCLIST *tchdbfwmkeys2(TCHDB *hdb, const char *pstr, int max); - - -/* Synchronize updated contents of a hash database object with the file and the device. - `hdb' specifies the hash database object connected as a writer. - If successful, the return value is true, else, it is false. - This function is useful when another process connects the same database file. */ -bool tchdbsync(TCHDB *hdb); - - -/* Optimize the file of a hash database object. - `hdb' specifies the hash database object connected as a writer. - `bnum' specifies the number of elements of the bucket array. If it is not more than 0, the - default value is specified. The default value is two times of the number of records. - `apow' specifies the size of record alignment by power of 2. If it is negative, the current - setting is not changed. - `fpow' specifies the maximum number of elements of the free block pool by power of 2. If it - is negative, the current setting is not changed. - `opts' specifies options by bitwise or: `HDBTLARGE' specifies that the size of the database - can be larger than 2GB by using 64-bit bucket array, `HDBTDEFLATE' specifies that each record - is compressed with Deflate encoding, `HDBTTCBS' specifies that each record is compressed with - TCBS encoding. If it is `UINT8_MAX', the current setting is not changed. - If successful, the return value is true, else, it is false. - This function is useful to reduce the size of the database file with data fragmentation by - successive updating. */ -bool tchdboptimize(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts); - - -/* Remove all records of a hash database object. - `hdb' specifies the hash database object connected as a writer. - If successful, the return value is true, else, it is false. */ -bool tchdbvanish(TCHDB *hdb); - - -/* Copy the database file of a hash database object. - `hdb' specifies the hash database object. - `path' specifies the path of the destination file. If it begins with `@', the trailing - substring is executed as a command line. - If successful, the return value is true, else, it is false. False is returned if the executed - command returns non-zero code. - The database file is assured to be kept synchronized and not modified while the copying or - executing operation is in progress. So, this function is useful to create a backup file of - the database file. */ -bool tchdbcopy(TCHDB *hdb, const char *path); - - -/* Get the file path of a hash database object. - `hdb' specifies the hash database object. - The return value is the path of the database file or `NULL' if the object does not connect to - any database file. */ -const char *tchdbpath(TCHDB *hdb); - - -/* Get the number of records of a hash database object. - `hdb' specifies the hash database object. - The return value is the number of records or 0 if the object does not connect to any database - file. */ -uint64_t tchdbrnum(TCHDB *hdb); - - -/* Get the size of the database file of a hash database object. - `hdb' specifies the hash database object. - The return value is the size of the database file or 0 if the object does not connect to any - database file. */ -uint64_t tchdbfsiz(TCHDB *hdb); - - - -/************************************************************************************************* - * features for experts - *************************************************************************************************/ - - -/* Set the error code of a hash database object. - `hdb' specifies the hash database object. - `ecode' specifies the error code. - `file' specifies the file name of the code. - `line' specifies the line number of the code. - `func' specifies the function name of the code. */ -void tchdbsetecode(TCHDB *hdb, int ecode, const char *filename, int line, const char *func); - - -/* Set the type of a hash database object. - `hdb' specifies the hash database object. - `type' specifies the database type. */ -void tchdbsettype(TCHDB *hdb, uint8_t type); - - -/* Set the file descriptor for debugging output. - `hdb' specifies the hash database object. - `fd' specifies the file descriptor for debugging output. */ -void tchdbsetdbgfd(TCHDB *hdb, int fd); - - -/* Get the file descriptor for debugging output. - `hdb' specifies the hash database object. - The return value is the file descriptor for debugging output. */ -int tchdbdbgfd(TCHDB *hdb); - - -/* Synchronize updating contents on memory. - `hdb' specifies the hash database object connected as a writer. - `phys' specifies whether to synchronize physically. - If successful, the return value is true, else, it is false. */ -bool tchdbmemsync(TCHDB *hdb, bool phys); - - -/* Get the number of elements of the bucket array of a hash database object. - `hdb' specifies the hash database object. - The return value is the number of elements of the bucket array or 0 if the object does not - connect to any database file. */ -uint64_t tchdbbnum(TCHDB *hdb); - - -/* Get the record alignment of a hash database object. - `hdb' specifies the hash database object. - The return value is the record alignment or 0 if the object does not connect to any database - file. */ -uint32_t tchdbalign(TCHDB *hdb); - - -/* Get the maximum number of the free block pool of a a hash database object. - `hdb' specifies the hash database object. - The return value is the maximum number of the free block pool or 0 if the object does not - connect to any database file. */ -uint32_t tchdbfbpmax(TCHDB *hdb); - - -/* Get the inode number of the database file of a hash database object. - `hdb' specifies the hash database object. - The return value is the inode number of the database file or 0 the object does not connect to - any database file. */ -uint64_t tchdbinode(TCHDB *hdb); - - -/* Get the modification time of the database file of a hash database object. - `hdb' specifies the hash database object. - The return value is the inode number of the database file or 0 the object does not connect to - any database file. */ -time_t tchdbmtime(TCHDB *hdb); - - -/* Get the connection mode of a hash database object. - `hdb' specifies the hash database object. - The return value is the connection mode. */ -int tchdbomode(TCHDB *hdb); - - -/* Get the database type of a hash database object. - `hdb' specifies the hash database object. - The return value is the database type. */ -uint8_t tchdbtype(TCHDB *hdb); - - -/* Get the additional flags of a hash database object. - `hdb' specifies the hash database object. - The return value is the additional flags. */ -uint8_t tchdbflags(TCHDB *hdb); - - -/* Get the options of a hash database object. - `hdb' specifies the hash database object. - The return value is the options. */ -uint8_t tchdbopts(TCHDB *hdb); - - -/* Get the pointer to the opaque field of a hash database object. - `hdb' specifies the hash database object. - The return value is the pointer to the opaque field whose size is 128 bytes. */ -char *tchdbopaque(TCHDB *hdb); - - -/* Get the number of used elements of the bucket array of a hash database object. - `hdb' specifies the hash database object. - The return value is the number of used elements of the bucket array or 0 if the object does not - connect to any database file. */ -uint64_t tchdbbnumused(TCHDB *hdb); - - - -__TCHDB_CLINKAGEEND -#endif /* duplication check */ - - -/* END OF FILE */ diff --git a/bacula/src/lib/tokyocabinet/tchmgr.c b/bacula/src/lib/tokyocabinet/tchmgr.c deleted file mode 100644 index 98febdaada..0000000000 --- a/bacula/src/lib/tokyocabinet/tchmgr.c +++ /dev/null @@ -1,803 +0,0 @@ -/************************************************************************************************* - * The command line utility of the hash database API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include -#include "myconf.h" - - -/* global variables */ -const char *g_progname; // program name -int g_dbgfd; // debugging output - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void printerr(TCHDB *hdb); -static int printdata(const char *ptr, int size, bool px); -static char *hextoobj(const char *str, int *sp); -static char *mygetline(FILE *ifp); -static int runcreate(int argc, char **argv); -static int runinform(int argc, char **argv); -static int runput(int argc, char **argv); -static int runout(int argc, char **argv); -static int runget(int argc, char **argv); -static int runlist(int argc, char **argv); -static int runoptimize(int argc, char **argv); -static int runimporttsv(int argc, char **argv); -static int runversion(int argc, char **argv); -static int proccreate(const char *path, int bnum, int apow, int fpow, int opts); -static int procinform(const char *path, int omode); -static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - int omode, int dmode); -static int procout(const char *path, const char *kbuf, int ksiz, int omode); -static int procget(const char *path, const char *kbuf, int ksiz, int omode, bool px, bool pz); -static int proclist(const char *path, int omode, int max, bool pv, bool px, const char *fmstr); -static int procoptimize(const char *path, int bnum, int apow, int fpow, int opts, int omode); -static int procimporttsv(const char *path, const char *file, int omode, bool sc); -static int procversion(void); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - g_dbgfd = -1; - const char *ebuf = getenv("TCDBGFD"); - if(ebuf) g_dbgfd = atoi(ebuf); - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "create")){ - rv = runcreate(argc, argv); - } else if(!strcmp(argv[1], "inform")){ - rv = runinform(argc, argv); - } else if(!strcmp(argv[1], "put")){ - rv = runput(argc, argv); - } else if(!strcmp(argv[1], "out")){ - rv = runout(argc, argv); - } else if(!strcmp(argv[1], "get")){ - rv = runget(argc, argv); - } else if(!strcmp(argv[1], "list")){ - rv = runlist(argc, argv); - } else if(!strcmp(argv[1], "optimize")){ - rv = runoptimize(argc, argv); - } else if(!strcmp(argv[1], "importtsv")){ - rv = runimporttsv(argc, argv); - } else if(!strcmp(argv[1], "version") || !strcmp(argv[1], "--version")){ - rv = runversion(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: the command line utility of the hash database API\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s create [-tl] [-td|-tb] path [bnum [apow [fpow]]]\n", g_progname); - fprintf(stderr, " %s inform [-nl|-nb] path\n", g_progname); - fprintf(stderr, " %s put [-nl|-nb] [-sx] [-dk|-dc] path key value\n", g_progname); - fprintf(stderr, " %s out [-nl|-nb] [-sx] path key\n", g_progname); - fprintf(stderr, " %s get [-nl|-nb] [-sx] [-px] [-pz] path key\n", g_progname); - fprintf(stderr, " %s list [-nl|-nb] [-m num] [-pv] [-px] [-fm str] path\n", g_progname); - fprintf(stderr, " %s optimize [-tl] [-td|-tb] [-tz] [-nl|-nb] path [bnum [apow [fpow]]]\n", - g_progname); - fprintf(stderr, " %s importtsv [-nl|-nb] [-sc] path [file]\n", g_progname); - fprintf(stderr, " %s version\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print error information */ -static void printerr(TCHDB *hdb){ - const char *path = tchdbpath(hdb); - int ecode = tchdbecode(hdb); - fprintf(stderr, "%s: %s: %d: %s\n", g_progname, path ? path : "-", ecode, tchdberrmsg(ecode)); -} - - -/* print record data */ -static int printdata(const char *ptr, int size, bool px){ - int len = 0; - while(size-- > 0){ - if(px){ - if(len > 0) putchar(' '); - len += printf("%02X", *(unsigned char *)ptr); - } else { - putchar(*ptr); - len++; - } - ptr++; - } - return len; -} - - -/* create a binary object from a hexadecimal string */ -static char *hextoobj(const char *str, int *sp){ - int len = strlen(str); - char *buf = tcmalloc(len + 1); - int j = 0; - for(int i = 0; i < len; i += 2){ - while(strchr(" \n\r\t\f\v", str[i])){ - i++; - } - char mbuf[3]; - if((mbuf[0] = str[i]) == '\0') break; - if((mbuf[1] = str[i+1]) == '\0') break; - mbuf[2] = '\0'; - buf[j++] = (char)strtol(mbuf, NULL, 16); - } - buf[j] = '\0'; - *sp = j; - return buf; -} - - -/* read a line from a file descriptor */ -static char *mygetline(FILE *ifp){ - char *buf; - int c, len, blen; - buf = NULL; - len = 0; - blen = 256; - while((c = fgetc(ifp)) != EOF){ - if(blen <= len) blen *= 2; - buf = tcrealloc(buf, blen + 1); - if(c == '\n' || c == '\r') c = '\0'; - buf[len++] = c; - if(c == '\0') break; - } - if(!buf) return NULL; - buf[len] = '\0'; - return buf; -} - - -/* parse arguments of create command */ -static int runcreate(int argc, char **argv){ - char *path = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - int opts = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-tl")){ - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= HDBTTCBS; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = proccreate(path, bnum, apow, fpow, opts); - return rv; -} - - -/* parse arguments of inform command */ -static int runinform(int argc, char **argv){ - char *path = NULL; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = procinform(path, omode); - return rv; -} - - -/* parse arguments of put command */ -static int runput(int argc, char **argv){ - char *path = NULL; - char *key = NULL; - char *value = NULL; - int omode = 0; - int dmode = 0; - bool sx = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-dk")){ - dmode = -1; - } else if(!strcmp(argv[i], "-dc")){ - dmode = 1; - } else if(!strcmp(argv[i], "-sx")){ - sx = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!key){ - key = argv[i]; - } else if(!value){ - value = argv[i]; - } else { - usage(); - } - } - if(!path || !key || !value) usage(); - int ksiz, vsiz; - char *kbuf, *vbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - vbuf = hextoobj(value, &vsiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - vsiz = strlen(value); - vbuf = tcmemdup(value, vsiz); - } - int rv = procput(path, kbuf, ksiz, vbuf, vsiz, omode, dmode); - free(vbuf); - free(kbuf); - return rv; -} - - -/* parse arguments of out command */ -static int runout(int argc, char **argv){ - char *path = NULL; - char *key = NULL; - int omode = 0; - bool sx = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-sx")){ - sx = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!key){ - key = argv[i]; - } else { - usage(); - } - } - if(!path || !key) usage(); - int ksiz; - char *kbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - } - int rv = procout(path, kbuf, ksiz, omode); - free(kbuf); - return rv; -} - - -/* parse arguments of get command */ -static int runget(int argc, char **argv){ - char *path = NULL; - char *key = NULL; - int omode = 0; - bool sx = false; - bool px = false; - bool pz = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-sx")){ - sx = true; - } else if(!strcmp(argv[i], "-px")){ - px = true; - } else if(!strcmp(argv[i], "-pz")){ - pz = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!key){ - key = argv[i]; - } else { - usage(); - } - } - if(!path || !key) usage(); - int ksiz; - char *kbuf; - if(sx){ - kbuf = hextoobj(key, &ksiz); - } else { - ksiz = strlen(key); - kbuf = tcmemdup(key, ksiz); - } - int rv = procget(path, kbuf, ksiz, omode, px, pz); - free(kbuf); - return rv; -} - - -/* parse arguments of list command */ -static int runlist(int argc, char **argv){ - char *path = NULL; - int omode = 0; - int max = -1; - bool pv = false; - bool px = false; - char *fmstr = NULL; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-m")){ - if(++i >= argc) usage(); - max = atoi(argv[i]); - } else if(!strcmp(argv[i], "-pv")){ - pv = true; - } else if(!strcmp(argv[i], "-px")){ - px = true; - } else if(!strcmp(argv[i], "-fm")){ - if(++i >= argc) usage(); - fmstr = argv[i]; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = proclist(path, omode, max, pv, px, fmstr); - return rv; -} - - -/* parse arguments of optimize command */ -static int runoptimize(int argc, char **argv){ - char *path = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - int opts = UINT8_MAX; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-tl")){ - if(opts == UINT8_MAX) opts = 0; - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - if(opts == UINT8_MAX) opts = 0; - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - if(opts == UINT8_MAX) opts = 0; - opts |= HDBTTCBS; - } else if(!strcmp(argv[i], "-tz")){ - if(opts == UINT8_MAX) opts = 0; - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procoptimize(path, bnum, apow, fpow, opts, omode); - return rv; -} - - -/* parse arguments of importtsv command */ -static int runimporttsv(int argc, char **argv){ - char *path = NULL; - char *file = NULL; - int omode = 0; - bool sc = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-sc")){ - sc = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!file){ - file = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = procimporttsv(path, file, omode, sc); - return rv; -} - - -/* parse arguments of version command */ -static int runversion(int argc, char **argv){ - int rv = procversion(); - return rv; -} - - -/* perform create command */ -static int proccreate(const char *path, int bnum, int apow, int fpow, int opts){ - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbtune(hdb, bnum, apow, fpow, opts)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | HDBOTRUNC)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - bool err = false; - if(!tchdbclose(hdb)){ - printerr(hdb); - err = true; - } - tchdbdel(hdb); - return err ? 1 : 0; -} - - -/* perform inform command */ -static int procinform(const char *path, int omode){ - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbopen(hdb, path, HDBOREADER | omode)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - bool err = false; - const char *npath = tchdbpath(hdb); - if(!npath) npath = "(unknown)"; - printf("path: %s\n", npath); - const char *type = "(unknown)"; - switch(tchdbtype(hdb)){ - case HDBTHASH: type = "hash"; break; - case HDBTBTREE: type = "btree"; break; - } - printf("database type: %s\n", type); - uint8_t flags = tchdbflags(hdb); - printf("additional flags:"); - if(flags & HDBFOPEN) printf(" open"); - if(flags & HDBFFATAL) printf(" fatal"); - printf("\n"); - printf("bucket number: %llu\n", (unsigned long long)tchdbbnum(hdb)); - if(hdb->cnt_writerec >= 0) - printf("used bucket number: %lld\n", (long long)tchdbbnumused(hdb)); - printf("alignment: %u\n", tchdbalign(hdb)); - printf("free block pool: %u\n", tchdbfbpmax(hdb)); - printf("inode number: %lld\n", (long long)tchdbinode(hdb)); - char date[48]; - tcdatestrwww(tchdbmtime(hdb), INT_MAX, date); - printf("modified time: %s\n", date); - uint8_t opts = tchdbopts(hdb); - printf("options:"); - if(opts & HDBTLARGE) printf(" large"); - if(opts & HDBTDEFLATE) printf(" deflate"); - if(opts & HDBTTCBS) printf(" tcbs"); - printf("\n"); - printf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - printf("file size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - if(!tchdbclose(hdb)){ - if(!err) printerr(hdb); - err = true; - } - tchdbdel(hdb); - return err ? 1 : 0; -} - - -/* perform put command */ -static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz, - int omode, int dmode){ - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbopen(hdb, path, HDBOWRITER | omode)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - bool err = false; - switch(dmode){ - case -1: - if(!tchdbputkeep(hdb, kbuf, ksiz, vbuf, vsiz)){ - printerr(hdb); - err = true; - } - break; - case 1: - if(!tchdbputcat(hdb, kbuf, ksiz, vbuf, vsiz)){ - printerr(hdb); - err = true; - } - break; - default: - if(!tchdbput(hdb, kbuf, ksiz, vbuf, vsiz)){ - printerr(hdb); - err = true; - } - break; - } - if(!tchdbclose(hdb)){ - if(!err) printerr(hdb); - err = true; - } - tchdbdel(hdb); - return err ? 1 : 0; -} - - -/* perform out command */ -static int procout(const char *path, const char *kbuf, int ksiz, int omode){ - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbopen(hdb, path, HDBOWRITER | omode)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - bool err = false; - if(!tchdbout(hdb, kbuf, ksiz)){ - printerr(hdb); - err = true; - } - if(!tchdbclose(hdb)){ - if(!err) printerr(hdb); - err = true; - } - tchdbdel(hdb); - return err ? 1 : 0; -} - - -/* perform get command */ -static int procget(const char *path, const char *kbuf, int ksiz, int omode, bool px, bool pz){ - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbopen(hdb, path, HDBOREADER | omode)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - bool err = false; - int vsiz; - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(vbuf){ - printdata(vbuf, vsiz, px); - if(!pz) putchar('\n'); - free(vbuf); - } else { - printerr(hdb); - err = true; - } - if(!tchdbclose(hdb)){ - if(!err) printerr(hdb); - err = true; - } - tchdbdel(hdb); - return err ? 1 : 0; -} - - -/* perform list command */ -static int proclist(const char *path, int omode, int max, bool pv, bool px, const char *fmstr){ - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbopen(hdb, path, HDBOREADER | omode)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - bool err = false; - if(fmstr){ - TCLIST *keys = tchdbfwmkeys2(hdb, fmstr, max); - for(int i = 0; i < tclistnum(keys); i++){ - int ksiz; - const char *kbuf = tclistval(keys, i, &ksiz); - printdata(kbuf, ksiz, px); - if(pv){ - int vsiz; - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(vbuf){ - putchar('\t'); - printdata(vbuf, vsiz, px); - free(vbuf); - } - } - putchar('\n'); - } - tclistdel(keys); - } else { - if(!tchdbiterinit(hdb)){ - printerr(hdb); - err = true; - } - TCXSTR *key = tcxstrnew(); - TCXSTR *val = tcxstrnew(); - int cnt = 0; - while(tchdbiternext3(hdb, key, val)){ - printdata(tcxstrptr(key), tcxstrsize(key), px); - if(pv){ - putchar('\t'); - printdata(tcxstrptr(val), tcxstrsize(val), px); - } - putchar('\n'); - if(max >= 0 && ++cnt >= max) break; - } - tcxstrdel(val); - tcxstrdel(key); - } - if(!tchdbclose(hdb)){ - if(!err) printerr(hdb); - err = true; - } - tchdbdel(hdb); - return err ? 1 : 0; -} - - -/* perform optimize command */ -static int procoptimize(const char *path, int bnum, int apow, int fpow, int opts, int omode){ - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbopen(hdb, path, HDBOWRITER | omode)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - bool err = false; - if(!tchdboptimize(hdb, bnum, apow, fpow, opts)){ - printerr(hdb); - err = true; - } - if(!tchdbclose(hdb)){ - if(!err) printerr(hdb); - err = true; - } - tchdbdel(hdb); - return err ? 1 : 0; -} - - -/* perform importtsv command */ -static int procimporttsv(const char *path, const char *file, int omode, bool sc){ - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - FILE *ifp = file ? fopen(file, "rb") : stdin; - if(!ifp){ - fprintf(stderr, "%s: could not open\n", file ? file : "(stdin)"); - tchdbdel(hdb); - return 1; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | omode)){ - printerr(hdb); - tchdbdel(hdb); - return 1; - } - bool err = false; - char *line; - int cnt = 0; - while(!err && (line = mygetline(ifp)) != NULL){ - char *pv = strchr(line, '\t'); - if(!pv) continue; - *pv = '\0'; - if(sc) tcstrtolower(line); - if(!tchdbput2(hdb, line, pv + 1) && tchdbecode(hdb) != TCEKEEP){ - printerr(hdb); - err = true; - } - free(line); - if(cnt > 0 && cnt % 100 == 0){ - putchar('.'); - fflush(stdout); - if(cnt % 5000 == 0) printf(" (%08d)\n", cnt); - } - cnt++; - } - printf(" (%08d)\n", cnt); - if(!tchdbclose(hdb)){ - if(!err) printerr(hdb); - err = true; - } - tchdbdel(hdb); - if(ifp != stdin) fclose(ifp); - return err ? 1 : 0; -} - - -/* perform version command */ -static int procversion(void){ - printf("Tokyo Cabinet version %s (%d:%s)\n", tcversion, _TC_LIBVER, _TC_FORMATVER); - printf("Copyright (C) 2006-2008 Mikio Hirabayashi\n"); - return 0; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tchmttest.c b/bacula/src/lib/tokyocabinet/tchmttest.c deleted file mode 100644 index 2e64ae91e3..0000000000 --- a/bacula/src/lib/tokyocabinet/tchmttest.c +++ /dev/null @@ -1,1266 +0,0 @@ -/************************************************************************************************* - * The test cases of the hash database API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include -#include "myconf.h" - -#define RECBUFSIZ 32 // buffer for records - -typedef struct { // type of structure for write thread - TCHDB *hdb; - int rnum; - bool as; - bool rnd; - int id; -} TARGWRITE; - -typedef struct { // type of structure for read thread - TCHDB *hdb; - int rnum; - bool wb; - bool rnd; - int id; -} TARGREAD; - -typedef struct { // type of structure for remove thread - TCHDB *hdb; - int rnum; - bool rnd; - int id; -} TARGREMOVE; - -typedef struct { // type of structure for wicked thread - TCHDB *hdb; - int rnum; - bool nc; - int id; - TCMAP *map; -} TARGWICKED; - -typedef struct { // type of structure for typical thread - TCHDB *hdb; - int rnum; - bool nc; - int rratio; - int id; -} TARGTYPICAL; - - -/* global variables */ -const char *g_progname; // program name -int g_dbgfd; // debugging output - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void iprintf(const char *format, ...); -static void eprint(TCHDB *hdb, const char *func); -static void mprint(TCHDB *hdb); -static int myrand(int range); -static int myrandnd(int range); -static int runwrite(int argc, char **argv); -static int runread(int argc, char **argv); -static int runremove(int argc, char **argv); -static int runwicked(int argc, char **argv); -static int runtypical(int argc, char **argv); -static int procwrite(const char *path, int tnum, int rnum, int bnum, int apow, int fpow, - int opts, int omode, bool as, bool rnd); -static int procread(const char *path, int tnum, int rcnum, int omode, bool wb, bool rnd); -static int procremove(const char *path, int tnum, int omode, bool rnd); -static int procwicked(const char *path, int tnum, int rnum, int opts, int omode, bool nc); -static int proctypical(const char *path, int tnum, int rnum, int bnum, int apow, int fpow, - int opts, int rcnum, int omode, bool nc, int rratio); -static void *threadwrite(void *targ); -static void *threadread(void *targ); -static void *threadremove(void *targ); -static void *threadwicked(void *targ); -static void *threadtypical(void *targ); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - g_dbgfd = -1; - const char *ebuf = getenv("TCDBGFD"); - if(ebuf) g_dbgfd = atoi(ebuf); - srand((unsigned int)(tctime() * 1000) % UINT_MAX); - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "write")){ - rv = runwrite(argc, argv); - } else if(!strcmp(argv[1], "read")){ - rv = runread(argc, argv); - } else if(!strcmp(argv[1], "remove")){ - rv = runremove(argc, argv); - } else if(!strcmp(argv[1], "wicked")){ - rv = runwicked(argc, argv); - } else if(!strcmp(argv[1], "typical")){ - rv = runtypical(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: test cases of the hash database API of Tokyo Cabinet\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s write [-tl] [-td|-tb] [-nl|-nb] [-as] [-rnd] path tnum rnum" - " [bnum [apow [fpow]]]\n", g_progname); - fprintf(stderr, " %s read [-rc num] [-nl|-nb] [-wb] [-rnd] path tnum\n", g_progname); - fprintf(stderr, " %s remove [-nl|-nb] [-wb] [-rnd] path tnum\n", g_progname); - fprintf(stderr, " %s wicked [-tl] [-td|-tb] [-nl|-nb] [-nc] path tnum rnum\n", - g_progname); - fprintf(stderr, " %s typical [-tl] [-td|-tb] [-rc num] [-nl|-nb] [-nc] [-rr num]" - " path tnum rnum [bnum [apow [fpow]]]\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print formatted information string and flush the buffer */ -static void iprintf(const char *format, ...){ - va_list ap; - va_start(ap, format); - vprintf(format, ap); - fflush(stdout); - va_end(ap); -} - - -/* print error message of hash database */ -static void eprint(TCHDB *hdb, const char *func){ - const char *path = tchdbpath(hdb); - int ecode = tchdbecode(hdb); - fprintf(stderr, "%s: %s: %s: error: %d: %s\n", - g_progname, path ? path : "-", func, ecode, tchdberrmsg(ecode)); -} - - -/* print members of hash database */ -static void mprint(TCHDB *hdb){ - if(hdb->cnt_writerec < 0) return; - iprintf("bucket number: %lld\n", (long long)tchdbbnum(hdb)); - iprintf("used bucket number: %lld\n", (long long)tchdbbnumused(hdb)); - iprintf("cnt_writerec: %lld\n", (long long)hdb->cnt_writerec); - iprintf("cnt_reuserec: %lld\n", (long long)hdb->cnt_reuserec); - iprintf("cnt_moverec: %lld\n", (long long)hdb->cnt_moverec); - iprintf("cnt_readrec: %lld\n", (long long)hdb->cnt_readrec); - iprintf("cnt_searchfbp: %lld\n", (long long)hdb->cnt_searchfbp); - iprintf("cnt_insertfbp: %lld\n", (long long)hdb->cnt_insertfbp); - iprintf("cnt_splicefbp: %lld\n", (long long)hdb->cnt_splicefbp); - iprintf("cnt_dividefbp: %lld\n", (long long)hdb->cnt_dividefbp); - iprintf("cnt_mergefbp: %lld\n", (long long)hdb->cnt_mergefbp); - iprintf("cnt_reducefbp: %lld\n", (long long)hdb->cnt_reducefbp); - iprintf("cnt_appenddrp: %lld\n", (long long)hdb->cnt_appenddrp); - iprintf("cnt_deferdrp: %lld\n", (long long)hdb->cnt_deferdrp); - iprintf("cnt_flushdrp: %lld\n", (long long)hdb->cnt_flushdrp); - iprintf("cnt_adjrecc: %lld\n", (long long)hdb->cnt_adjrecc); -} - - -/* get a random number */ -static int myrand(int range){ - return (int)((double)range * rand() / (RAND_MAX + 1.0)); -} - - -/* get a random number based on normal distribution */ -static int myrandnd(int range){ - int num = (int)tcdrandnd(range >> 1, range / 10); - return (num < 0 || num >= range) ? 0 : num; -} - - -/* parse arguments of write command */ -static int runwrite(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - char *rstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - int opts = 0; - int omode = 0; - bool as = false; - bool rnd = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-tl")){ - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= HDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-as")){ - as = true; - } else if(!strcmp(argv[i], "-rnd")){ - rnd = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr || !rstr) usage(); - int tnum = atoi(tstr); - int rnum = atoi(rstr); - if(tnum < 1 || rnum < 1) usage(); - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procwrite(path, tnum, rnum, bnum, apow, fpow, opts, omode, as, rnd); - return rv; -} - - -/* parse arguments of read command */ -static int runread(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - int rcnum = 0; - int omode = 0; - bool wb = false; - bool rnd = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-rc")){ - if(++i >= argc) usage(); - rcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-wb")){ - wb = true; - } else if(!strcmp(argv[i], "-rnd")){ - rnd = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr) usage(); - int tnum = atoi(tstr); - if(tnum < 1) usage(); - int rv = procread(path, tnum, rcnum, omode, wb, rnd); - return rv; -} - - -/* parse arguments of remove command */ -static int runremove(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - int omode = 0; - bool rnd = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-rnd")){ - rnd = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr) usage(); - int tnum = atoi(tstr); - if(tnum < 1) usage(); - int rv = procremove(path, tnum, omode, rnd); - return rv; -} - - -/* parse arguments of wicked command */ -static int runwicked(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - char *rstr = NULL; - int opts = 0; - int omode = 0; - bool nc = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-tl")){ - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= HDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-nc")){ - nc = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr || !rstr) usage(); - int tnum = atoi(tstr); - int rnum = atoi(rstr); - if(tnum < 1 || rnum < 1) usage(); - int rv = procwicked(path, tnum, rnum, opts, omode, nc); - return rv; -} - - -/* parse arguments of typical command */ -static int runtypical(int argc, char **argv){ - char *path = NULL; - char *tstr = NULL; - char *rstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - int opts = 0; - int rcnum = 0; - int omode = 0; - int rratio = -1; - bool nc = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-tl")){ - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= HDBTTCBS; - } else if(!strcmp(argv[i], "-rc")){ - if(++i >= argc) usage(); - rcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-nc")){ - nc = true; - } else if(!strcmp(argv[i], "-rr")){ - if(++i >= argc) usage(); - rratio = atoi(argv[i]); - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!tstr){ - tstr = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !tstr || !rstr) usage(); - int tnum = atoi(tstr); - int rnum = atoi(rstr); - if(tnum < 1 || rnum < 1) usage(); - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = proctypical(path, tnum, rnum, bnum, apow, fpow, opts, rcnum, omode, nc, rratio); - return rv; -} - - -/* perform write command */ -static int procwrite(const char *path, int tnum, int rnum, int bnum, int apow, int fpow, - int opts, int omode, bool as, bool rnd){ - iprintf("\n path=%s tnum=%d rnum=%d bnum=%d apow=%d fpow=%d" - " opts=%d omode=%d as=%d rnd=%d\n\n", - path, tnum, rnum, bnum, apow, fpow, opts, omode, as, rnd); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbtune(hdb, bnum, apow, fpow, opts)){ - eprint(hdb, "tchdbtune"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | HDBOTRUNC | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - TARGWRITE targs[tnum]; - pthread_t threads[tnum]; - if(tnum == 1){ - targs[0].hdb = hdb; - targs[0].rnum = rnum; - targs[0].as = as; - targs[0].rnd = rnd; - targs[0].id = 0; - if(threadwrite(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].hdb = hdb; - targs[i].rnum = rnum; - targs[i].as = as; - targs[i].rnd = rnd; - targs[i].id = i; - if(pthread_create(threads + i, NULL, threadwrite, targs + i) != 0){ - eprint(hdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(hdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform read command */ -static int procread(const char *path, int tnum, int rcnum, int omode, bool wb, bool rnd){ - iprintf("\n path=%s tnum=%d rcnum=%d omode=%d wb=%d rnd=%d\n\n", - path, tnum, rcnum, omode, wb, rnd); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbsetcache(hdb, rcnum)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOREADER | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - int rnum = tchdbrnum(hdb) / tnum; - TARGREAD targs[tnum]; - pthread_t threads[tnum]; - if(tnum == 1){ - targs[0].hdb = hdb; - targs[0].rnum = rnum; - targs[0].wb = wb; - targs[0].rnd = rnd; - targs[0].id = 0; - if(threadread(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].hdb = hdb; - targs[i].rnum = rnum; - targs[i].wb = wb; - targs[i].rnd = rnd; - targs[i].id = i; - if(pthread_create(threads + i, NULL, threadread, targs + i) != 0){ - eprint(hdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(hdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform remove command */ -static int procremove(const char *path, int tnum, int omode, bool rnd){ - iprintf("\n path=%s tnum=%d omode=%d rnd=%d\n\n", path, tnum, omode, rnd); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - int rnum = tchdbrnum(hdb) / tnum; - TARGREMOVE targs[tnum]; - pthread_t threads[tnum]; - if(tnum == 1){ - targs[0].hdb = hdb; - targs[0].rnum = rnum; - targs[0].rnd = rnd; - targs[0].id = 0; - if(threadremove(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].hdb = hdb; - targs[i].rnum = rnum; - targs[i].rnd = rnd; - targs[i].id = i; - if(pthread_create(threads + i, NULL, threadremove, targs + i) != 0){ - eprint(hdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(hdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform wicked command */ -static int procwicked(const char *path, int tnum, int rnum, int opts, int omode, bool nc){ - iprintf("\n path=%s tnum=%d rnum=%d opts=%d omode=%d nc=%d\n\n", - path, tnum, rnum, opts, omode, nc); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbtune(hdb, rnum / 50, 2, -1, opts)){ - eprint(hdb, "tchdbtune"); - err = true; - } - if(!tchdbsetcache(hdb, rnum / 2)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | HDBOTRUNC | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - if(!tchdbiterinit(hdb)){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - TARGWICKED targs[tnum]; - pthread_t threads[tnum]; - TCMAP *map = tcmapnew(); - if(tnum == 1){ - targs[0].hdb = hdb; - targs[0].rnum = rnum; - targs[0].nc = nc; - targs[0].id = 0; - targs[0].map = map; - if(threadwicked(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].hdb = hdb; - targs[i].rnum = rnum; - targs[i].nc = nc; - targs[i].id = i; - targs[i].map = map; - targs[i].map = map; - if(pthread_create(threads + i, NULL, threadwicked, targs + i) != 0){ - eprint(hdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(hdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - if(!nc){ - if(!tchdbsync(hdb)){ - eprint(hdb, "tchdbsync"); - err = true; - } - if(tchdbrnum(hdb) != tcmaprnum(map)){ - eprint(hdb, "(validation)"); - err = true; - } - int end = rnum * tnum; - for(int i = 1; i <= end && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", i - 1); - int vsiz; - const char *vbuf = tcmapget(map, kbuf, ksiz, &vsiz); - int rsiz; - char *rbuf = tchdbget(hdb, kbuf, ksiz, &rsiz); - if(vbuf){ - putchar('.'); - if(!rbuf){ - eprint(hdb, "tchdbget"); - err = true; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(hdb, "(validation)"); - err = true; - } - } else { - putchar('*'); - if(rbuf || tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "(validation)"); - err = true; - } - } - free(rbuf); - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - } - tcmapdel(map); - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform typical command */ -static int proctypical(const char *path, int tnum, int rnum, int bnum, int apow, int fpow, - int opts, int rcnum, int omode, bool nc, int rratio){ - iprintf("\n path=%s tnum=%d rnum=%d bnum=%d apow=%d fpow=%d" - " opts=%d rcnum=%d omode=%d nc=%d rratio=%d\n\n", - path, tnum, rnum, bnum, apow, fpow, opts, rcnum, omode, nc, rratio); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(!tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbtune(hdb, bnum, apow, fpow, opts)){ - eprint(hdb, "tchdbtune"); - err = true; - } - if(!tchdbsetcache(hdb, rcnum)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | HDBOTRUNC | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - TARGTYPICAL targs[tnum]; - pthread_t threads[tnum]; - if(tnum == 1){ - targs[0].hdb = hdb; - targs[0].rnum = rnum; - targs[0].nc = nc; - targs[0].rratio = rratio; - targs[0].id = 0; - if(threadtypical(targs) != NULL) err = true; - } else { - for(int i = 0; i < tnum; i++){ - targs[i].hdb = hdb; - targs[i].rnum = rnum; - targs[i].nc = nc; - targs[i].rratio= rratio; - targs[i].id = i; - if(pthread_create(threads + i, NULL, threadtypical, targs + i) != 0){ - eprint(hdb, "pthread_create"); - targs[i].id = -1; - err = true; - } - } - for(int i = 0; i < tnum; i++){ - if(targs[i].id == -1) continue; - void *rv; - if(pthread_join(threads[i], &rv) != 0){ - eprint(hdb, "pthread_join"); - err = true; - } else if(rv){ - err = true; - } - } - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* thread the write function */ -static void *threadwrite(void *targ){ - TCHDB *hdb = ((TARGWRITE *)targ)->hdb; - int rnum = ((TARGWRITE *)targ)->rnum; - bool as = ((TARGWRITE *)targ)->as; - bool rnd = ((TARGWRITE *)targ)->rnd; - int id = ((TARGWRITE *)targ)->id; - bool err = false; - int base = id * rnum; - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", base + (rnd ? myrand(i) : i)); - if(as){ - if(!tchdbputasync(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbput"); - err = true; - break; - } - } else { - if(!tchdbput(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbput"); - err = true; - break; - } - } - if(id == 0 && rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - return err ? "error" : NULL; -} - - -/* thread the read function */ -static void *threadread(void *targ){ - TCHDB *hdb = ((TARGREAD *)targ)->hdb; - int rnum = ((TARGREAD *)targ)->rnum; - bool wb = ((TARGREAD *)targ)->wb; - bool rnd = ((TARGREAD *)targ)->rnd; - int id = ((TARGREAD *)targ)->id; - bool err = false; - int base = id * rnum; - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", base + (rnd ? myrandnd(i) : i)); - int vsiz; - if(wb){ - char vbuf[RECBUFSIZ]; - int vsiz = tchdbget3(hdb, kbuf, ksiz, vbuf, RECBUFSIZ); - if(vsiz < 0 && (!rnd || tchdbecode(hdb) != TCENOREC)){ - eprint(hdb, "tchdbget3"); - err = true; - } - } else { - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(!vbuf && (!rnd || tchdbecode(hdb) != TCENOREC)){ - eprint(hdb, "tchdbget"); - err = true; - } - free(vbuf); - } - if(id == 0 && rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - return err ? "error" : NULL; -} - - -/* thread the remove function */ -static void *threadremove(void *targ){ - TCHDB *hdb = ((TARGREMOVE *)targ)->hdb; - int rnum = ((TARGREMOVE *)targ)->rnum; - bool rnd = ((TARGREMOVE *)targ)->rnd; - int id = ((TARGREMOVE *)targ)->id; - bool err = false; - int base = id * rnum; - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", base + (rnd ? myrand(i + 1) : i)); - if(!tchdbout(hdb, kbuf, ksiz) && (!rnd || tchdbecode(hdb) != TCENOREC)){ - eprint(hdb, "tchdbout"); - err = true; - break; - } - if(id == 0 && rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - return err ? "error" : NULL; -} - - -/* thread the wicked function */ -static void *threadwicked(void *targ){ - TCHDB *hdb = ((TARGWICKED *)targ)->hdb; - int rnum = ((TARGWICKED *)targ)->rnum; - bool nc = ((TARGWICKED *)targ)->nc; - int id = ((TARGWICKED *)targ)->id; - TCMAP *map = ((TARGWICKED *)targ)->map; - bool err = false; - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum * (id + 1))); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '*', vsiz); - vbuf[vsiz] = '\0'; - char *rbuf; - if(!nc) tcglobalmutexlock(); - switch(myrand(16)){ - case 0: - if(id == 0) putchar('0'); - if(!tchdbput(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbput"); - err = true; - } - if(!nc) tcmapput(map, kbuf, ksiz, vbuf, vsiz); - break; - case 1: - if(id == 0) putchar('1'); - if(!tchdbput2(hdb, kbuf, vbuf)){ - eprint(hdb, "tchdbput2"); - err = true; - } - if(!nc) tcmapput2(map, kbuf, vbuf); - break; - case 2: - if(id == 0) putchar('2'); - if(!tchdbputkeep(hdb, kbuf, ksiz, vbuf, vsiz) && tchdbecode(hdb) != TCEKEEP){ - eprint(hdb, "tchdbputkeep"); - err = true; - } - if(!nc) tcmapputkeep(map, kbuf, ksiz, vbuf, vsiz); - break; - case 3: - if(id == 0) putchar('3'); - if(!tchdbputkeep2(hdb, kbuf, vbuf) && tchdbecode(hdb) != TCEKEEP){ - eprint(hdb, "tchdbputkeep2"); - err = true; - } - if(!nc) tcmapputkeep2(map, kbuf, vbuf); - break; - case 4: - if(id == 0) putchar('4'); - if(!tchdbputcat(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputcat"); - err = true; - } - if(!nc) tcmapputcat(map, kbuf, ksiz, vbuf, vsiz); - break; - case 5: - if(id == 0) putchar('5'); - if(!tchdbputcat2(hdb, kbuf, vbuf)){ - eprint(hdb, "tchdbputcat2"); - err = true; - } - if(!nc) tcmapputcat2(map, kbuf, vbuf); - break; - case 6: - if(id == 0) putchar('6'); - if(i > rnum / 4 * 3){ - if(!tchdbputasync(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputasync"); - err = true; - } - } else { - if(!tchdbput(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbput"); - err = true; - } - } - if(!nc) tcmapput(map, kbuf, ksiz, vbuf, vsiz); - break; - case 7: - if(id == 0) putchar('7'); - if(i > rnum / 4 * 3){ - if(!tchdbputasync2(hdb, kbuf, vbuf)){ - eprint(hdb, "tchdbputasync2"); - err = true; - } - } else { - if(!tchdbput2(hdb, kbuf, vbuf)){ - eprint(hdb, "tchdbput2"); - err = true; - } - } - if(!nc) tcmapput2(map, kbuf, vbuf); - break; - case 8: - if(id == 0) putchar('8'); - if(myrand(10) == 0){ - if(!tchdbout(hdb, kbuf, ksiz) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbout"); - err = true; - } - if(!nc) tcmapout(map, kbuf, ksiz); - } - break; - case 9: - if(id == 0) putchar('9'); - if(myrand(10) == 0){ - if(!tchdbout2(hdb, kbuf) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbout2"); - err = true; - } - if(!nc) tcmapout2(map, kbuf); - } - break; - case 10: - if(id == 0) putchar('A'); - if(!(rbuf = tchdbget(hdb, kbuf, ksiz, &vsiz))){ - if(tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget"); - err = true; - } - rbuf = tcsprintf("[%d]", myrand(i + 1)); - vsiz = strlen(rbuf); - } - vsiz += myrand(vsiz); - if(myrand(3) == 0) vsiz += PATH_MAX; - rbuf = tcrealloc(rbuf, vsiz + 1); - for(int j = 0; j < vsiz; j++){ - rbuf[j] = myrand(0x100); - } - if(!tchdbput(hdb, kbuf, ksiz, rbuf, vsiz)){ - eprint(hdb, "tchdbput"); - err = true; - } - if(!nc) tcmapput(map, kbuf, ksiz, rbuf, vsiz); - free(rbuf); - break; - case 11: - if(id == 0) putchar('B'); - if(!(rbuf = tchdbget(hdb, kbuf, ksiz, &vsiz)) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget"); - err = true; - } - free(rbuf); - break; - case 12: - if(id == 0) putchar('C'); - if(!(rbuf = tchdbget2(hdb, kbuf)) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget"); - err = true; - } - free(rbuf); - break; - case 13: - if(id == 0) putchar('D'); - if(myrand(1) == 0) vsiz = 1; - if((vsiz = tchdbget3(hdb, kbuf, ksiz, vbuf, vsiz)) < 0 && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget3"); - err = true; - } - break; - case 14: - if(id == 0) putchar('E'); - if(myrand(rnum / 50) == 0){ - if(!tchdbiterinit(hdb)){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - } - TCXSTR *ikey = tcxstrnew(); - TCXSTR *ival = tcxstrnew(); - for(int j = myrand(rnum) / 1000 + 1; j >= 0; j--){ - if(j % 3 == 0){ - if(!tchdbiternext3(hdb, ikey, ival)){ - int ecode = tchdbecode(hdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(hdb, "tchdbiternext3"); - err = true; - } - } - } else { - int iksiz; - char *ikbuf = tchdbiternext(hdb, &iksiz); - if(ikbuf){ - free(ikbuf); - } else { - int ecode = tchdbecode(hdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(hdb, "tchdbiternext"); - err = true; - } - } - } - } - tcxstrdel(ival); - tcxstrdel(ikey); - break; - default: - if(id == 0) putchar('@'); - if(myrand(10000) == 0) srand((unsigned int)(tctime() * 1000) % UINT_MAX); - break; - } - if(!nc) tcglobalmutexunlock(); - if(id == 0){ - if(i % 50 == 0) iprintf(" (%08d)\n", i); - if(id == 0 && i == rnum / 4){ - if(!tchdboptimize(hdb, rnum / 50, -1, -1, -1)){ - eprint(hdb, "tchdboptimize"); - err = true; - } - if(!tchdbiterinit(hdb)){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - } - } - } - return err ? "error" : NULL; -} - - -/* thread the typical function */ -static void *threadtypical(void *targ){ - TCHDB *hdb = ((TARGTYPICAL *)targ)->hdb; - int rnum = ((TARGTYPICAL *)targ)->rnum; - bool nc = ((TARGTYPICAL *)targ)->nc; - int rratio = ((TARGTYPICAL *)targ)->rratio; - int id = ((TARGTYPICAL *)targ)->id; - bool err = false; - TCMAP *map = (!nc && id == 0) ? tcmapnew2(rnum + 1) : NULL; - int base = id * rnum; - int mrange = tclmax(50 + rratio, 100); - for(int i = 1; !err && i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", base + myrandnd(i)); - int rnd = myrand(mrange); - if(rnd < 10){ - if(!tchdbput(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbput"); - err = true; - } - if(map) tcmapput(map, buf, len, buf, len); - } else if(rnd < 15){ - if(!tchdbputkeep(hdb, buf, len, buf, len) && tchdbecode(hdb) != TCEKEEP){ - eprint(hdb, "tchdbputkeep"); - err = true; - } - if(map) tcmapputkeep(map, buf, len, buf, len); - } else if(rnd < 20){ - if(!tchdbputcat(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbputcat"); - err = true; - } - if(map) tcmapputcat(map, buf, len, buf, len); - } else if(rnd < 25){ - if(i > rnum / 10 * 9){ - if(!tchdbputasync(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbputasync"); - err = true; - } - } else { - if(!tchdbput(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbput"); - err = true; - } - } - if(map) tcmapput(map, buf, len, buf, len); - } else if(rnd < 30){ - if(!tchdbout(hdb, buf, len) && tchdbecode(hdb) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbout"); - err = true; - } - if(map) tcmapout(map, buf, len); - } else if(rnd < 31){ - if(myrand(10) == 0 && !tchdbiterinit(hdb) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - for(int j = 0; !err && j < 10; j++){ - int ksiz; - char *kbuf = tchdbiternext(hdb, &ksiz); - if(kbuf){ - free(kbuf); - } else if(tchdbecode(hdb) != TCEINVALID && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbiternext"); - err = true; - } - } - } else { - int vsiz; - char *vbuf = tchdbget(hdb, buf, len, &vsiz); - if(vbuf){ - if(map){ - int msiz; - const char *mbuf = tcmapget(map, buf, len, &msiz); - if(msiz != vsiz || memcmp(mbuf, vbuf, vsiz)){ - eprint(hdb, "(validation)"); - err = true; - } - } - free(vbuf); - } else { - if(tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget"); - err = true; - } - if(map && tcmapget(map, buf, len, &vsiz)){ - eprint(hdb, "(validation)"); - err = true; - } - } - } - if(id == 0 && rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(map){ - tcmapiterinit(map); - int ksiz; - const char *kbuf; - while(!err && (kbuf = tcmapiternext(map, &ksiz)) != NULL){ - int vsiz; - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(vbuf){ - int msiz; - const char *mbuf = tcmapget(map, kbuf, ksiz, &msiz); - if(!mbuf || msiz != vsiz || memcmp(mbuf, vbuf, vsiz)){ - eprint(hdb, "(validation)"); - err = true; - } - free(vbuf); - } else { - eprint(hdb, "(validation)"); - err = true; - } - } - tcmapdel(map); - } - return err ? "error" : NULL; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tchtest.c b/bacula/src/lib/tokyocabinet/tchtest.c deleted file mode 100644 index 9dfffc4dd2..0000000000 --- a/bacula/src/lib/tokyocabinet/tchtest.c +++ /dev/null @@ -1,1439 +0,0 @@ -/************************************************************************************************* - * The test cases of the hash database API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include -#include "myconf.h" - -#define RECBUFSIZ 32 // buffer for records - - -/* global variables */ -const char *g_progname; // program name -int g_dbgfd; // debugging output - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void iprintf(const char *format, ...); -static void eprint(TCHDB *hdb, const char *func); -static void mprint(TCHDB *hdb); -static int myrand(int range); -static int runwrite(int argc, char **argv); -static int runread(int argc, char **argv); -static int runremove(int argc, char **argv); -static int runrcat(int argc, char **argv); -static int runmisc(int argc, char **argv); -static int runwicked(int argc, char **argv); -static int procwrite(const char *path, int rnum, int bnum, int apow, int fpow, - bool mt, int opts, int rcnum, int omode, bool as); -static int procread(const char *path, bool mt, int rcnum, int omode, bool wb); -static int procremove(const char *path, bool mt, int rcnum, int omode); -static int procrcat(const char *path, int rnum, int bnum, int apow, int fpow, - bool mt, int opts, int rcnum, int omode, int pnum, bool rl); -static int procmisc(const char *path, int rnum, bool mt, int opts, int omode); -static int procwicked(const char *path, int rnum, bool mt, int opts, int omode); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - g_dbgfd = -1; - const char *ebuf = getenv("TCDBGFD"); - if(ebuf) g_dbgfd = atoi(ebuf); - srand((unsigned int)(tctime() * 1000) % UINT_MAX); - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "write")){ - rv = runwrite(argc, argv); - } else if(!strcmp(argv[1], "read")){ - rv = runread(argc, argv); - } else if(!strcmp(argv[1], "remove")){ - rv = runremove(argc, argv); - } else if(!strcmp(argv[1], "rcat")){ - rv = runrcat(argc, argv); - } else if(!strcmp(argv[1], "misc")){ - rv = runmisc(argc, argv); - } else if(!strcmp(argv[1], "wicked")){ - rv = runwicked(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: test cases of the hash database API of Tokyo Cabinet\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s write [-mt] [-tl] [-td|-tb] [-rc num] [-nl|-nb] [-as] path rnum" - " [bnum [apow [fpow]]]\n", g_progname); - fprintf(stderr, " %s read [-mt] [-rc num] [-nl|-nb] [-wb] path\n", g_progname); - fprintf(stderr, " %s remove [-mt] [-rc num] [-nl|-nb] path\n", g_progname); - fprintf(stderr, " %s rcat [-mt] [-rc num] [-tl] [-td|-tb] [-nl|-nb] [-pn num] [-rl]" - " path rnum [bnum [apow [fpow]]]\n", g_progname); - fprintf(stderr, " %s misc [-mt] [-tl] [-td|-tb] [-nl|-nb] path rnum\n", g_progname); - fprintf(stderr, " %s wicked [-mt] [-tl] [-td|-tb] [-nl|-nb] path rnum\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print formatted information string and flush the buffer */ -static void iprintf(const char *format, ...){ - va_list ap; - va_start(ap, format); - vprintf(format, ap); - fflush(stdout); - va_end(ap); -} - - -/* print error message of hash database */ -static void eprint(TCHDB *hdb, const char *func){ - const char *path = tchdbpath(hdb); - int ecode = tchdbecode(hdb); - fprintf(stderr, "%s: %s: %s: error: %d: %s\n", - g_progname, path ? path : "-", func, ecode, tchdberrmsg(ecode)); -} - - -/* print members of hash database */ -static void mprint(TCHDB *hdb){ - if(hdb->cnt_writerec < 0) return; - iprintf("bucket number: %lld\n", (long long)tchdbbnum(hdb)); - iprintf("used bucket number: %lld\n", (long long)tchdbbnumused(hdb)); - iprintf("cnt_writerec: %lld\n", (long long)hdb->cnt_writerec); - iprintf("cnt_reuserec: %lld\n", (long long)hdb->cnt_reuserec); - iprintf("cnt_moverec: %lld\n", (long long)hdb->cnt_moverec); - iprintf("cnt_readrec: %lld\n", (long long)hdb->cnt_readrec); - iprintf("cnt_searchfbp: %lld\n", (long long)hdb->cnt_searchfbp); - iprintf("cnt_insertfbp: %lld\n", (long long)hdb->cnt_insertfbp); - iprintf("cnt_splicefbp: %lld\n", (long long)hdb->cnt_splicefbp); - iprintf("cnt_dividefbp: %lld\n", (long long)hdb->cnt_dividefbp); - iprintf("cnt_mergefbp: %lld\n", (long long)hdb->cnt_mergefbp); - iprintf("cnt_reducefbp: %lld\n", (long long)hdb->cnt_reducefbp); - iprintf("cnt_appenddrp: %lld\n", (long long)hdb->cnt_appenddrp); - iprintf("cnt_deferdrp: %lld\n", (long long)hdb->cnt_deferdrp); - iprintf("cnt_flushdrp: %lld\n", (long long)hdb->cnt_flushdrp); - iprintf("cnt_adjrecc: %lld\n", (long long)hdb->cnt_adjrecc); -} - - -/* get a random number */ -static int myrand(int range){ - return (int)((double)range * rand() / (RAND_MAX + 1.0)); -} - - -/* parse arguments of write command */ -static int runwrite(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - bool mt = false; - int opts = 0; - int rcnum = 0; - int omode = 0; - bool as = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-tl")){ - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= HDBTTCBS; - } else if(!strcmp(argv[i], "-rc")){ - if(++i >= argc) usage(); - rcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-as")){ - as = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procwrite(path, rnum, bnum, apow, fpow, mt, opts, rcnum, omode, as); - return rv; -} - - -/* parse arguments of read command */ -static int runread(int argc, char **argv){ - char *path = NULL; - bool mt = false; - int rcnum = 0; - int omode = 0; - bool wb = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-rc")){ - if(++i >= argc) usage(); - rcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-wb")){ - wb = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = procread(path, mt, rcnum, omode, wb); - return rv; -} - - -/* parse arguments of remove command */ -static int runremove(int argc, char **argv){ - char *path = NULL; - bool mt = false; - int rcnum = 0; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-rc")){ - if(++i >= argc) usage(); - rcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - if(!path) usage(); - int rv = procremove(path, mt, rcnum, omode); - return rv; -} - - -/* parse arguments of rcat command */ -static int runrcat(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - char *bstr = NULL; - char *astr = NULL; - char *fstr = NULL; - bool mt = false; - int opts = 0; - int rcnum = 0; - int omode = 0; - int pnum = 0; - bool rl = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-tl")){ - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= HDBTTCBS; - } else if(!strcmp(argv[i], "-rc")){ - if(++i >= argc) usage(); - rcnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else if(!strcmp(argv[i], "-pn")){ - if(++i >= argc) usage(); - pnum = atoi(argv[i]); - } else if(!strcmp(argv[i], "-rl")){ - rl = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else if(!bstr){ - bstr = argv[i]; - } else if(!astr){ - astr = argv[i]; - } else if(!fstr){ - fstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int bnum = bstr ? atoi(bstr) : -1; - int apow = astr ? atoi(astr) : -1; - int fpow = fstr ? atoi(fstr) : -1; - int rv = procrcat(path, rnum, bnum, apow, fpow, mt, opts, rcnum, omode, pnum, rl); - return rv; -} - - -/* parse arguments of misc command */ -static int runmisc(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - bool mt = false; - int opts = 0; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-tl")){ - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= HDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int rv = procmisc(path, rnum, mt, opts, omode); - return rv; -} - - -/* parse arguments of wicked command */ -static int runwicked(int argc, char **argv){ - char *path = NULL; - char *rstr = NULL; - bool mt = false; - int opts = 0; - int omode = 0; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-mt")){ - mt = true; - } else if(!strcmp(argv[i], "-tl")){ - opts |= HDBTLARGE; - } else if(!strcmp(argv[i], "-td")){ - opts |= HDBTDEFLATE; - } else if(!strcmp(argv[i], "-tb")){ - opts |= HDBTTCBS; - } else if(!strcmp(argv[i], "-nl")){ - omode |= HDBONOLCK; - } else if(!strcmp(argv[i], "-nb")){ - omode |= HDBOLCKNB; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else if(!rstr){ - rstr = argv[i]; - } else { - usage(); - } - } - if(!path || !rstr) usage(); - int rnum = atoi(rstr); - if(rnum < 1) usage(); - int rv = procwicked(path, rnum, mt, opts, omode); - return rv; -} - - -/* perform write command */ -static int procwrite(const char *path, int rnum, int bnum, int apow, int fpow, - bool mt, int opts, int rcnum, int omode, bool as){ - iprintf("\n path=%s rnum=%d bnum=%d apow=%d fpow=%d mt=%d" - " opts=%d rcnum=%d omode=%d as=%d\n\n", - path, rnum, bnum, apow, fpow, mt, opts, rcnum, omode, as); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(mt && !tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbtune(hdb, bnum, apow, fpow, opts)){ - eprint(hdb, "tchdbtune"); - err = true; - } - if(!tchdbsetcache(hdb, rcnum)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | HDBOTRUNC | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", i); - if(as){ - if(!tchdbputasync(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbput"); - err = true; - break; - } - } else { - if(!tchdbput(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbput"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform read command */ -static int procread(const char *path, bool mt, int rcnum, int omode, bool wb){ - iprintf("\n path=%s mt=%d rcnum=%d omode=%d wb=%d\n", - path, mt, rcnum, omode, wb); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(mt && !tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbsetcache(hdb, rcnum)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOREADER | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - int rnum = tchdbrnum(hdb); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - int vsiz; - if(wb){ - char vbuf[RECBUFSIZ]; - int vsiz = tchdbget3(hdb, kbuf, ksiz, vbuf, RECBUFSIZ); - if(vsiz < 0){ - eprint(hdb, "tchdbget3"); - err = true; - break; - } - } else { - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(hdb, "tchdbget"); - err = true; - break; - } - free(vbuf); - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform remove command */ -static int procremove(const char *path, bool mt, int rcnum, int omode){ - iprintf("\n path=%s mt=%d rcnum=%d omode=%d\n", path, mt, rcnum, omode); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(mt && !tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbsetcache(hdb, rcnum)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - int rnum = tchdbrnum(hdb); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - if(!tchdbout(hdb, kbuf, ksiz)){ - eprint(hdb, "tchdbout"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform rcat command */ -static int procrcat(const char *path, int rnum, int bnum, int apow, int fpow, - bool mt, int opts, int rcnum, int omode, int pnum, bool rl){ - iprintf("\n" - " path=%s rnum=%d bnum=%d apow=%d fpow=%d mt=%d opts=%d rcnum=%d" - " omode=%d pnum=%d rl=%d\n\n", - path, rnum, bnum, apow, fpow, mt, opts, rcnum, omode, pnum, rl); - if(pnum < 1) pnum = rnum; - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(mt && !tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbtune(hdb, bnum, apow, fpow, opts)){ - eprint(hdb, "tchdbtune"); - err = true; - } - if(!tchdbsetcache(hdb, rcnum)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | HDBOTRUNC | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(pnum)); - if(rl){ - char vbuf[PATH_MAX]; - int vsiz = myrand(PATH_MAX); - for(int j = 0; j < vsiz; j++){ - vbuf[j] = myrand(0x100); - } - if(!tchdbputcat(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputcat"); - err = true; - break; - } - } else { - if(!tchdbputcat(hdb, kbuf, ksiz, kbuf, ksiz)){ - eprint(hdb, "tchdbputcat"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform misc command */ -static int procmisc(const char *path, int rnum, bool mt, int opts, int omode){ - iprintf("\n path=%s rnum=%d mt=%d opts=%d omode=%d\n\n", - path, rnum, mt, opts, omode); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(mt && !tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbtune(hdb, rnum / 50, 2, -1, opts)){ - eprint(hdb, "tchdbtune"); - err = true; - } - if(!tchdbsetcache(hdb, rnum / 10)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | HDBOTRUNC | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - iprintf("writing:\n"); - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", i); - if(i % 3 == 0){ - if(!tchdbputkeep(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbputkeep"); - err = true; - break; - } - } else { - if(!tchdbputasync(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbputasync"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("reading:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - int vsiz; - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(hdb, "tchdbget"); - err = true; - break; - } else if(vsiz != ksiz || memcmp(vbuf, kbuf, vsiz)){ - eprint(hdb, "(validation)"); - err = true; - free(vbuf); - break; - } - free(vbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(tchdbrnum(hdb) != rnum){ - eprint(hdb, "(validation)"); - err = true; - } - iprintf("random writing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '*', vsiz); - if(!tchdbput(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbput"); - err = true; - break; - } - int rsiz; - char *rbuf = tchdbget(hdb, kbuf, ksiz, &rsiz); - if(!rbuf){ - eprint(hdb, "tchdbget"); - err = true; - break; - } - if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(hdb, "(validation)"); - err = true; - free(rbuf); - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - free(rbuf); - } - iprintf("word writing:\n"); - const char *words[] = { - "a", "A", "bb", "BB", "ccc", "CCC", "dddd", "DDDD", "eeeee", "EEEEEE", - "mikio", "hirabayashi", "tokyo", "cabinet", "hyper", "estraier", "19780211", "birth day", - "one", "first", "two", "second", "three", "third", "four", "fourth", "five", "fifth", - "_[1]_", "uno", "_[2]_", "dos", "_[3]_", "tres", "_[4]_", "cuatro", "_[5]_", "cinco", - "[\xe5\xb9\xb3\xe6\x9e\x97\xe5\xb9\xb9\xe9\x9b\x84]", "[\xe9\xa6\xac\xe9\xb9\xbf]", NULL - }; - for(int i = 0; words[i] != NULL; i += 2){ - const char *kbuf = words[i]; - int ksiz = strlen(kbuf); - const char *vbuf = words[i+1]; - int vsiz = strlen(vbuf); - if(!tchdbputkeep(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputkeep"); - err = true; - break; - } - if(rnum > 250) putchar('.'); - } - if(rnum > 250) iprintf(" (%08d)\n", sizeof(words) / sizeof(*words)); - iprintf("random erasing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - if(!tchdbout(hdb, kbuf, ksiz) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbout"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("writing:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "[%d]", i); - char vbuf[RECBUFSIZ]; - int vsiz = i % RECBUFSIZ; - memset(vbuf, '*', vsiz); - if(!tchdbputkeep(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputkeep"); - err = true; - break; - } - if(vsiz < 1){ - char tbuf[PATH_MAX]; - for(int j = 0; j < PATH_MAX; j++){ - tbuf[j] = myrand(0x100); - } - if(!tchdbput(hdb, kbuf, ksiz, tbuf, PATH_MAX)){ - eprint(hdb, "tchdbput"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("erasing:\n"); - for(int i = 1; i <= rnum; i++){ - if(i % 2 == 1){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "[%d]", i); - if(!tchdbout(hdb, kbuf, ksiz)){ - eprint(hdb, "tchdbout"); - err = true; - break; - } - if(tchdbout(hdb, kbuf, ksiz) || tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbout"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("random writing and reopening:\n"); - for(int i = 1; i <= rnum; i++){ - if(myrand(10) == 0){ - int ksiz, vsiz; - char *kbuf, *vbuf; - ksiz = (myrand(5) == 0) ? myrand(UINT16_MAX) : myrand(RECBUFSIZ); - kbuf = tcmalloc(ksiz + 1); - memset(kbuf, '@', ksiz); - vsiz = (myrand(5) == 0) ? myrand(UINT16_MAX) : myrand(RECBUFSIZ); - vbuf = tcmalloc(vsiz + 1); - for(int j = 0; j < vsiz; j++){ - vbuf[j] = myrand(256); - } - switch(myrand(4)){ - case 0: - if(!tchdbput(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbput"); - err = true; - } - break; - case 1: - if(!tchdbputcat(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputcat"); - err = true; - } - break; - case 2: - if(!tchdbputasync(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputasync"); - err = true; - } - break; - case 3: - if(!tchdbout(hdb, kbuf, ksiz) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbout"); - err = true; - } - break; - } - free(vbuf); - free(kbuf); - } else { - char kbuf[RECBUFSIZ]; - int ksiz = myrand(RECBUFSIZ); - memset(kbuf, '@', ksiz); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '@', vsiz); - if(!tchdbput(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputcat"); - err = true; - break; - } - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - iprintf("checking:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "[%d]", i); - int vsiz; - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(i % 2 == 0){ - if(!vbuf){ - eprint(hdb, "tchdbget"); - err = true; - break; - } - if(vsiz != i % RECBUFSIZ && vsiz != PATH_MAX){ - eprint(hdb, "(validation)"); - err = true; - free(vbuf); - break; - } - } else { - if(vbuf || tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "(validation)"); - err = true; - free(vbuf); - break; - } - } - free(vbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("writing:\n"); - for(int i = 1; i <= rnum; i++){ - char buf[RECBUFSIZ]; - int len = sprintf(buf, "%08d", i); - if(!tchdbput(hdb, buf, len, buf, len)){ - eprint(hdb, "tchdbput"); - err = true; - break; - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("reading:\n"); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%08d", i); - int vsiz; - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(hdb, "tchdbget"); - err = true; - break; - } else if(vsiz != ksiz || memcmp(vbuf, kbuf, vsiz)){ - eprint(hdb, "(validation)"); - err = true; - free(vbuf); - break; - } - free(vbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("word checking:\n"); - for(int i = 0; words[i] != NULL; i += 2){ - const char *kbuf = words[i]; - int ksiz = strlen(kbuf); - const char *vbuf = words[i+1]; - int vsiz = strlen(vbuf); - int rsiz; - char *rbuf = tchdbget(hdb, kbuf, ksiz, &rsiz); - if(!rbuf){ - eprint(hdb, "tchdbget"); - err = true; - break; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(hdb, "(validation)"); - err = true; - free(rbuf); - break; - } - free(rbuf); - if(rnum > 250) putchar('.'); - } - if(rnum > 250) iprintf(" (%08d)\n", sizeof(words) / sizeof(*words)); - iprintf("iterator checking:\n"); - if(!tchdbiterinit(hdb)){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - char *kbuf; - int ksiz; - int inum = 0; - for(int i = 1; (kbuf = tchdbiternext(hdb, &ksiz)) != NULL; i++, inum++){ - int vsiz; - char *vbuf = tchdbget(hdb, kbuf, ksiz, &vsiz); - if(!vbuf){ - eprint(hdb, "tchdbget"); - err = true; - free(kbuf); - break; - } - free(vbuf); - free(kbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(rnum > 250) iprintf(" (%08d)\n", inum); - if(tchdbecode(hdb) != TCENOREC || inum != tchdbrnum(hdb)){ - eprint(hdb, "(validation)"); - err = true; - } - iprintf("iteration updating:\n"); - if(!tchdbiterinit(hdb)){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - inum = 0; - for(int i = 1; (kbuf = tchdbiternext(hdb, &ksiz)) != NULL; i++, inum++){ - if(myrand(2) == 0){ - if(!tchdbputcat(hdb, kbuf, ksiz, "0123456789", 10)){ - eprint(hdb, "tchdbputcat"); - err = true; - free(kbuf); - break; - } - } else { - if(!tchdbout(hdb, kbuf, ksiz)){ - eprint(hdb, "tchdbout"); - err = true; - free(kbuf); - break; - } - } - free(kbuf); - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - if(rnum > 250) iprintf(" (%08d)\n", inum); - if(tchdbecode(hdb) != TCENOREC || inum < tchdbrnum(hdb)){ - eprint(hdb, "(validation)"); - err = true; - } - if(!tchdbsync(hdb)){ - eprint(hdb, "tchdbsync"); - err = true; - } - if(!tchdbvanish(hdb)){ - eprint(hdb, "tchdbvanish"); - err = true; - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - -/* perform wicked command */ -static int procwicked(const char *path, int rnum, bool mt, int opts, int omode){ - iprintf("\n path=%s rnum=%d mt=%d opts=%d omode=%d\n\n", - path, rnum, mt, opts, omode); - bool err = false; - double stime = tctime(); - TCHDB *hdb = tchdbnew(); - if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd); - if(mt && !tchdbsetmutex(hdb)){ - eprint(hdb, "tchdbsetmutex"); - err = true; - } - if(!tchdbtune(hdb, rnum / 50, 2, -1, opts)){ - eprint(hdb, "tchdbtune"); - err = true; - } - if(!tchdbsetcache(hdb, rnum / 10)){ - eprint(hdb, "tchdbsetcache"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | HDBOTRUNC | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - if(!tchdbiterinit(hdb)){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - TCMAP *map = tcmapnew2(rnum / 5); - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(rnum)); - char vbuf[RECBUFSIZ]; - int vsiz = myrand(RECBUFSIZ); - memset(vbuf, '*', vsiz); - vbuf[vsiz] = '\0'; - char *rbuf; - switch(myrand(16)){ - case 0: - putchar('0'); - if(!tchdbput(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbput"); - err = true; - } - tcmapput(map, kbuf, ksiz, vbuf, vsiz); - break; - case 1: - putchar('1'); - if(!tchdbput2(hdb, kbuf, vbuf)){ - eprint(hdb, "tchdbput2"); - err = true; - } - tcmapput2(map, kbuf, vbuf); - break; - case 2: - putchar('2'); - if(!tchdbputkeep(hdb, kbuf, ksiz, vbuf, vsiz) && tchdbecode(hdb) != TCEKEEP){ - eprint(hdb, "tchdbputkeep"); - err = true; - } - tcmapputkeep(map, kbuf, ksiz, vbuf, vsiz); - break; - case 3: - putchar('3'); - if(!tchdbputkeep2(hdb, kbuf, vbuf) && tchdbecode(hdb) != TCEKEEP){ - eprint(hdb, "tchdbputkeep2"); - err = true; - } - tcmapputkeep2(map, kbuf, vbuf); - break; - case 4: - putchar('4'); - if(!tchdbputcat(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputcat"); - err = true; - } - tcmapputcat(map, kbuf, ksiz, vbuf, vsiz); - break; - case 5: - putchar('5'); - if(!tchdbputcat2(hdb, kbuf, vbuf)){ - eprint(hdb, "tchdbputcat2"); - err = true; - } - tcmapputcat2(map, kbuf, vbuf); - break; - case 6: - putchar('6'); - if(!tchdbputasync(hdb, kbuf, ksiz, vbuf, vsiz)){ - eprint(hdb, "tchdbputasync"); - err = true; - } - tcmapput(map, kbuf, ksiz, vbuf, vsiz); - break; - case 7: - putchar('7'); - if(!tchdbputasync2(hdb, kbuf, vbuf)){ - eprint(hdb, "tchdbputasync2"); - err = true; - } - tcmapput2(map, kbuf, vbuf); - break; - case 8: - putchar('8'); - if(myrand(10) == 0){ - if(!tchdbout(hdb, kbuf, ksiz) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbout"); - err = true; - } - tcmapout(map, kbuf, ksiz); - } - break; - case 9: - putchar('9'); - if(myrand(10) == 0){ - if(!tchdbout2(hdb, kbuf) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbout2"); - err = true; - } - tcmapout2(map, kbuf); - } - break; - case 10: - putchar('A'); - if(!(rbuf = tchdbget(hdb, kbuf, ksiz, &vsiz))){ - if(tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget"); - err = true; - } - rbuf = tcsprintf("[%d]", myrand(i + 1)); - vsiz = strlen(rbuf); - } - vsiz += myrand(vsiz); - if(myrand(3) == 0) vsiz += PATH_MAX; - rbuf = tcrealloc(rbuf, vsiz + 1); - for(int j = 0; j < vsiz; j++){ - rbuf[j] = myrand(0x100); - } - if(!tchdbput(hdb, kbuf, ksiz, rbuf, vsiz)){ - eprint(hdb, "tchdbput"); - err = true; - } - tcmapput(map, kbuf, ksiz, rbuf, vsiz); - free(rbuf); - break; - case 11: - putchar('B'); - if(!(rbuf = tchdbget(hdb, kbuf, ksiz, &vsiz)) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget"); - err = true; - } - free(rbuf); - break; - case 12: - putchar('C'); - if(!(rbuf = tchdbget2(hdb, kbuf)) && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget"); - err = true; - } - free(rbuf); - break; - case 13: - putchar('D'); - if(myrand(1) == 0) vsiz = 1; - if((vsiz = tchdbget3(hdb, kbuf, ksiz, vbuf, vsiz)) < 0 && tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tchdbget"); - err = true; - } - break; - case 14: - putchar('E'); - if(myrand(rnum / 50) == 0){ - if(!tchdbiterinit(hdb)){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - } - TCXSTR *ikey = tcxstrnew(); - TCXSTR *ival = tcxstrnew(); - for(int j = myrand(rnum) / 1000 + 1; j >= 0; j--){ - if(j % 3 == 0){ - if(tchdbiternext3(hdb, ikey, ival)){ - if(tcxstrsize(ival) != tchdbvsiz(hdb, tcxstrptr(ikey), tcxstrsize(ikey))){ - eprint(hdb, "(validation)"); - err = true; - } - } else { - int ecode = tchdbecode(hdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(hdb, "tchdbiternext3"); - err = true; - } - } - } else { - int iksiz; - char *ikbuf = tchdbiternext(hdb, &iksiz); - if(ikbuf){ - free(ikbuf); - } else { - int ecode = tchdbecode(hdb); - if(ecode != TCEINVALID && ecode != TCENOREC){ - eprint(hdb, "tchdbiternext"); - err = true; - } - } - } - } - tcxstrdel(ival); - tcxstrdel(ikey); - break; - default: - putchar('@'); - if(myrand(10000) == 0) srand((unsigned int)(tctime() * 1000) % UINT_MAX); - if(myrand(rnum / 16 + 1) == 0){ - int cnt = myrand(30); - for(int j = 0; j < rnum && !err; j++){ - ksiz = sprintf(kbuf, "%d", i + j); - if(tchdbout(hdb, kbuf, ksiz)){ - cnt--; - } else if(tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "tcbdbout"); - err = true; - } - tcmapout(map, kbuf, ksiz); - if(cnt < 0) break; - } - } - break; - } - if(i % 50 == 0) iprintf(" (%08d)\n", i); - if(i == rnum / 2){ - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - if(!tchdbopen(hdb, path, HDBOWRITER | omode)){ - eprint(hdb, "tchdbopen"); - err = true; - } - } else if(i == rnum / 4){ - char *npath = tcsprintf("%s-tmp", path); - if(!tchdbcopy(hdb, npath)){ - eprint(hdb, "tchdbcopy"); - err = true; - } - TCHDB *nhdb = tchdbnew(); - if(!tchdbopen(nhdb, npath, HDBOREADER | omode)){ - eprint(nhdb, "tchdbopen"); - err = true; - } - tchdbdel(nhdb); - unlink(npath); - free(npath); - if(!tchdboptimize(hdb, rnum / 50, -1, -1, -1)){ - eprint(hdb, "tchdboptimize"); - err = true; - } - if(!tchdbiterinit(hdb)){ - eprint(hdb, "tchdbiterinit"); - err = true; - } - } - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - if(!tchdbsync(hdb)){ - eprint(hdb, "tchdbsync"); - err = true; - } - if(tchdbrnum(hdb) != tcmaprnum(map)){ - eprint(hdb, "(validation)"); - err = true; - } - for(int i = 1; i <= rnum && !err; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", i - 1); - int vsiz; - const char *vbuf = tcmapget(map, kbuf, ksiz, &vsiz); - int rsiz; - char *rbuf = tchdbget(hdb, kbuf, ksiz, &rsiz); - if(vbuf){ - putchar('.'); - if(!rbuf){ - eprint(hdb, "tchdbget"); - err = true; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(hdb, "(validation)"); - err = true; - } - } else { - putchar('*'); - if(rbuf || tchdbecode(hdb) != TCENOREC){ - eprint(hdb, "(validation)"); - err = true; - } - } - free(rbuf); - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - tcmapiterinit(map); - int ksiz; - const char *kbuf; - for(int i = 1; (kbuf = tcmapiternext(map, &ksiz)) != NULL; i++){ - putchar('+'); - int vsiz; - const char *vbuf = tcmapiterval(kbuf, &vsiz); - int rsiz; - char *rbuf = tchdbget(hdb, kbuf, ksiz, &rsiz); - if(!rbuf){ - eprint(hdb, "tchdbget"); - err = true; - } else if(rsiz != vsiz || memcmp(rbuf, vbuf, rsiz)){ - eprint(hdb, "(validation)"); - err = true; - } - free(rbuf); - if(!tchdbout(hdb, kbuf, ksiz)){ - eprint(hdb, "tchdbout"); - err = true; - } - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - int mrnum = tcmaprnum(map); - if(mrnum % 50 > 0) iprintf(" (%08d)\n", mrnum); - if(tchdbrnum(hdb) != 0){ - eprint(hdb, "(validation)"); - err = true; - } - iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb)); - iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb)); - mprint(hdb); - tcmapdel(map); - if(!tchdbclose(hdb)){ - eprint(hdb, "tchdbclose"); - err = true; - } - tchdbdel(hdb); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("%s\n\n", err ? "error" : "ok"); - return err ? 1 : 0; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcucodec.c b/bacula/src/lib/tokyocabinet/tcucodec.c deleted file mode 100644 index 7a9d933ad6..0000000000 --- a/bacula/src/lib/tokyocabinet/tcucodec.c +++ /dev/null @@ -1,865 +0,0 @@ -/************************************************************************************************* - * Popular encoders and decoders of the utility API - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include -#include "myconf.h" - - -/* global variables */ -const char *g_progname; // program name - - -/* function prototypes */ -int main(int argc, char **argv); -static void usage(void); -static void eprintf(const char *format, ...); -static int runurl(int argc, char **argv); -static int runbase(int argc, char **argv); -static int runquote(int argc, char **argv); -static int runmime(int argc, char **argv); -static int runpack(int argc, char **argv); -static int runtcbs(int argc, char **argv); -static int runzlib(int argc, char **argv); -static int runxml(int argc, char **argv); -static int runucs(int argc, char **argv); -static int rundate(int argc, char **argv); -static int runconf(int argc, char **argv); -static int procurl(const char *ibuf, int isiz, bool dec, bool br, const char *base); -static int procbase(const char *ibuf, int isiz, bool dec); -static int procquote(const char *ibuf, int isiz, bool dec); -static int procmime(const char *ibuf, int isiz, bool dec, const char *ename, bool qb, bool on); -static int procpack(const char *ibuf, int isiz, bool dec, bool bwt); -static int proctcbs(const char *ibuf, int isiz, bool dec); -static int proczlib(const char *ibuf, int isiz, bool dec, bool gz); -static int procxml(const char *ibuf, int isiz, bool dec, bool br); -static int procucs(const char *ibuf, int isiz, bool dec); -static int procdate(const char *str, int jl, bool wf, bool rf); -static int procconf(int mode); - - -/* main routine */ -int main(int argc, char **argv){ - g_progname = argv[0]; - if(argc < 2) usage(); - int rv = 0; - if(!strcmp(argv[1], "url")){ - rv = runurl(argc, argv); - } else if(!strcmp(argv[1], "base")){ - rv = runbase(argc, argv); - } else if(!strcmp(argv[1], "quote")){ - rv = runquote(argc, argv); - } else if(!strcmp(argv[1], "mime")){ - rv = runmime(argc, argv); - } else if(!strcmp(argv[1], "pack")){ - rv = runpack(argc, argv); - } else if(!strcmp(argv[1], "tcbs")){ - rv = runtcbs(argc, argv); - } else if(!strcmp(argv[1], "zlib")){ - rv = runzlib(argc, argv); - } else if(!strcmp(argv[1], "xml")){ - rv = runxml(argc, argv); - } else if(!strcmp(argv[1], "ucs")){ - rv = runucs(argc, argv); - } else if(!strcmp(argv[1], "date")){ - rv = rundate(argc, argv); - } else if(!strcmp(argv[1], "conf")){ - rv = runconf(argc, argv); - } else { - usage(); - } - return rv; -} - - -/* print the usage and exit */ -static void usage(void){ - fprintf(stderr, "%s: popular encoders and decoders of Tokyo Cabinet\n", g_progname); - fprintf(stderr, "\n"); - fprintf(stderr, "usage:\n"); - fprintf(stderr, " %s url [-d] [-br] [-rs base] [file]\n", g_progname); - fprintf(stderr, " %s base [-d] [file]\n", g_progname); - fprintf(stderr, " %s quote [-d] [file]\n", g_progname); - fprintf(stderr, " %s mime [-d] [-en name] [-q] [file]\n", g_progname); - fprintf(stderr, " %s pack [-d] [-bwt] [file]\n", g_progname); - fprintf(stderr, " %s tcbs [-d] [file]\n", g_progname); - fprintf(stderr, " %s zlib [-d] [-gz] [file]\n", g_progname); - fprintf(stderr, " %s xml [-d] [-br] [file]\n", g_progname); - fprintf(stderr, " %s ucs [-d] [file]\n", g_progname); - fprintf(stderr, " %s date [-ds str] [-jl num] [-wf] [-rf]\n", g_progname); - fprintf(stderr, " %s conf [-v|-i|-l|-p]\n", g_progname); - fprintf(stderr, "\n"); - exit(1); -} - - -/* print formatted error string */ -static void eprintf(const char *format, ...){ - va_list ap; - va_start(ap, format); - fprintf(stderr, "%s: ", g_progname); - vfprintf(stderr, format, ap); - fprintf(stderr, "\n"); - va_end(ap); -} - - -/* parse arguments of url command */ -static int runurl(int argc, char **argv){ - char *path = NULL; - bool dec = false; - bool br = false; - char *base = NULL; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else if(!strcmp(argv[i], "-br")){ - br = true; - } else if(!strcmp(argv[i], "-rs")){ - if(++i >= argc) usage(); - base = argv[i]; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - int rv = procurl(ibuf, isiz, dec, br, base); - if(path && path[0] == '@' && !br) printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of base command */ -static int runbase(int argc, char **argv){ - char *path = NULL; - bool dec = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - int rv = procbase(ibuf, isiz, dec); - if(path && path[0] == '@') printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of quote command */ -static int runquote(int argc, char **argv){ - char *path = NULL; - bool dec = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - int rv = procquote(ibuf, isiz, dec); - if(path && path[0] == '@') printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of mime command */ -static int runmime(int argc, char **argv){ - char *path = NULL; - bool dec = false; - char *ename = NULL; - bool qb = false; - bool on = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else if(!strcmp(argv[i], "-en")){ - if(++i >= argc) usage(); - ename = argv[i]; - } else if(!strcmp(argv[i], "-q")){ - qb = true; - } else if(!strcmp(argv[i], "-on")){ - on = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - if(!ename) ename = "UTF-8"; - int rv = procmime(ibuf, isiz, dec, ename, qb, on); - if(path && path[0] == '@') printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of pack command */ -static int runpack(int argc, char **argv){ - char *path = NULL; - bool dec = false; - bool bwt = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else if(!strcmp(argv[i], "-bwt")){ - bwt = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - int rv = procpack(ibuf, isiz, dec, bwt); - if(path && path[0] == '@') printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of tcbs command */ -static int runtcbs(int argc, char **argv){ - char *path = NULL; - bool dec = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - int rv = proctcbs(ibuf, isiz, dec); - if(path && path[0] == '@') printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of zlib command */ -static int runzlib(int argc, char **argv){ - char *path = NULL; - bool dec = false; - bool gz = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else if(!strcmp(argv[i], "-gz")){ - gz = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - int rv = proczlib(ibuf, isiz, dec, gz); - if(path && path[0] == '@') printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of xml command */ -static int runxml(int argc, char **argv){ - char *path = NULL; - bool dec = false; - bool br = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else if(!strcmp(argv[i], "-br")){ - br = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - int rv = procxml(ibuf, isiz, dec, br); - if(path && path[0] == '@') printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of ucs command */ -static int runucs(int argc, char **argv){ - char *path = NULL; - bool dec = false; - for(int i = 2; i < argc; i++){ - if(!path && argv[i][0] == '-'){ - if(!strcmp(argv[i], "-d")){ - dec = true; - } else { - usage(); - } - } else if(!path){ - path = argv[i]; - } else { - usage(); - } - } - char *ibuf; - int isiz; - if(path && path[0] == '@'){ - isiz = strlen(path) - 1; - ibuf = tcmemdup(path + 1, isiz); - } else { - ibuf = tcreadfile(path, -1, &isiz); - } - if(!ibuf){ - eprintf("%s: cannot open", path ? path : "(stdin)"); - return 1; - } - int rv = procucs(ibuf, isiz, dec); - if(path && path[0] == '@') printf("\n"); - free(ibuf); - return rv; -} - - -/* parse arguments of date command */ -static int rundate(int argc, char **argv){ - char *str = NULL; - int jl = INT_MAX; - bool wf = false; - bool rf = false; - for(int i = 2; i < argc; i++){ - if(argv[i][0] == '-'){ - if(!strcmp(argv[i], "-ds")){ - if(++i >= argc) usage(); - str = argv[i]; - } else if(!strcmp(argv[i], "-jl")){ - if(++i >= argc) usage(); - jl = atoi(argv[i]); - } else if(!strcmp(argv[i], "-wf")){ - wf = true; - } else if(!strcmp(argv[i], "-rf")){ - rf = true; - } else { - usage(); - } - } else { - usage(); - } - } - int rv = procdate(str, jl, wf, rf); - return rv; -} - - -/* parse arguments of conf command */ -static int runconf(int argc, char **argv){ - int mode = 0; - for(int i = 2; i < argc; i++){ - if(argv[i][0] == '-'){ - if(!strcmp(argv[i], "-v")){ - mode = 'v'; - } else if(!strcmp(argv[i], "-i")){ - mode = 'i'; - } else if(!strcmp(argv[i], "-l")){ - mode = 'l'; - } else if(!strcmp(argv[i], "-p")){ - mode = 'p'; - } else { - usage(); - } - } else { - usage(); - } - } - int rv = procconf(mode); - return rv; -} - - -/* perform url command */ -static int procurl(const char *ibuf, int isiz, bool dec, bool br, const char *base){ - if(base){ - char *obuf = tcurlresolve(base, ibuf); - printf("%s", obuf); - free(obuf); - } else if(br){ - TCMAP *elems = tcurlbreak(ibuf); - const char *elem; - if((elem = tcmapget2(elems, "self")) != NULL) printf("self: %s\n", elem); - if((elem = tcmapget2(elems, "scheme")) != NULL) printf("scheme: %s\n", elem); - if((elem = tcmapget2(elems, "host")) != NULL) printf("host: %s\n", elem); - if((elem = tcmapget2(elems, "port")) != NULL) printf("port: %s\n", elem); - if((elem = tcmapget2(elems, "authority")) != NULL) printf("authority: %s\n", elem); - if((elem = tcmapget2(elems, "path")) != NULL) printf("path: %s\n", elem); - if((elem = tcmapget2(elems, "file")) != NULL) printf("file: %s\n", elem); - if((elem = tcmapget2(elems, "query")) != NULL) printf("query: %s\n", elem); - if((elem = tcmapget2(elems, "fragment")) != NULL) printf("fragment: %s\n", elem); - tcmapdel(elems); - } else if(dec){ - int osiz; - char *obuf = tcurldecode(ibuf, &osiz); - fwrite(obuf, osiz, 1, stdout); - free(obuf); - } else { - char *obuf = tcurlencode(ibuf, isiz); - fwrite(obuf, strlen(obuf), 1, stdout); - free(obuf); - } - return 0; -} - - -/* perform base command */ -static int procbase(const char *ibuf, int isiz, bool dec){ - if(dec){ - int osiz; - char *obuf = tcbasedecode(ibuf, &osiz); - fwrite(obuf, osiz, 1, stdout); - free(obuf); - } else { - char *obuf = tcbaseencode(ibuf, isiz); - fwrite(obuf, strlen(obuf), 1, stdout); - free(obuf); - } - return 0; -} - - -/* perform quote command */ -static int procquote(const char *ibuf, int isiz, bool dec){ - if(dec){ - int osiz; - char *obuf = tcquotedecode(ibuf, &osiz); - fwrite(obuf, osiz, 1, stdout); - free(obuf); - } else { - char *obuf = tcquoteencode(ibuf, isiz); - fwrite(obuf, strlen(obuf), 1, stdout); - free(obuf); - } - return 0; -} - - -/* perform mime command */ -static int procmime(const char *ibuf, int isiz, bool dec, const char *ename, bool qb, bool on){ - if(dec){ - char ebuf[32]; - char *obuf = tcmimedecode(ibuf, ebuf); - if(on){ - fwrite(ebuf, strlen(ebuf), 1, stdout); - } else { - fwrite(obuf, strlen(obuf), 1, stdout); - } - free(obuf); - } else { - char *obuf = tcmimeencode(ibuf, ename, !qb); - fwrite(obuf, strlen(obuf), 1, stdout); - free(obuf); - } - return 0; -} - - -/* perform pack command */ -static int procpack(const char *ibuf, int isiz, bool dec, bool bwt){ - if(dec){ - int osiz; - char *obuf = tcpackdecode(ibuf, isiz, &osiz); - if(bwt && osiz > 0){ - int idx, step; - TCREADVNUMBUF(obuf, idx, step); - char *tbuf = tcbwtdecode(obuf + step, osiz - step, idx); - fwrite(tbuf, osiz - step, 1, stdout); - free(tbuf); - } else { - fwrite(obuf, osiz, 1, stdout); - } - free(obuf); - } else { - char *tbuf = NULL; - if(bwt){ - int idx; - tbuf = tcbwtencode(ibuf, isiz, &idx); - char vnumbuf[sizeof(int)+1]; - int step; - TCSETVNUMBUF(step, vnumbuf, idx); - tbuf = tcrealloc(tbuf, isiz + step + 1); - memmove(tbuf + step, tbuf, isiz); - memcpy(tbuf, vnumbuf, step); - isiz += step; - ibuf = tbuf; - } - int osiz; - char *obuf = tcpackencode(ibuf, isiz, &osiz); - fwrite(obuf, osiz, 1, stdout); - free(obuf); - free(tbuf); - } - return 0; -} - - -/* perform tcbs command */ -static int proctcbs(const char *ibuf, int isiz, bool dec){ - if(dec){ - int osiz; - char *obuf = tcbsdecode(ibuf, isiz, &osiz); - fwrite(obuf, osiz, 1, stdout); - free(obuf); - } else { - int osiz; - char *obuf = tcbsencode(ibuf, isiz, &osiz); - fwrite(obuf, osiz, 1, stdout); - free(obuf); - } - return 0; -} - - -/* perform zlib command */ -static int proczlib(const char *ibuf, int isiz, bool dec, bool gz){ - if(dec){ - int osiz; - char *obuf = gz ? tcgzipdecode(ibuf, isiz, &osiz) : tcinflate(ibuf, isiz, &osiz); - if(obuf){ - fwrite(obuf, osiz, 1, stdout); - free(obuf); - } else { - eprintf("inflate failure"); - } - } else { - int osiz; - char *obuf = gz ? tcgzipencode(ibuf, isiz, &osiz) : tcdeflate(ibuf, isiz, &osiz); - if(obuf){ - fwrite(obuf, osiz, 1, stdout); - free(obuf); - } else { - eprintf("deflate failure"); - } - } - return 0; -} - - -/* perform xml command */ -static int procxml(const char *ibuf, int isiz, bool dec, bool br){ - if(br){ - TCLIST *elems = tcxmlbreak(ibuf); - for(int i = 0; i < tclistnum(elems); i++){ - int esiz; - const char *elem = tclistval(elems, i, &esiz); - char *estr = tcmemdup(elem, esiz); - tcstrsubchr(estr, "\t\n\r", " "); - tcstrtrim(estr); - if(*estr != '\0'){ - if(*elem == '<'){ - if(tcstrfwm(estr, ""); - for(int j = 0; j < tclistnum(list); j++){ - const char *elem = tclistval2(list, j); - TCMAP *attrs = tcxmlattrs(elem); - tcmapdel(attrs); - } - tclistdel(list); - } - if(i % 10 == 1){ - for(int16_t j = 1; j <= 0x2000; j *= 2){ - for(int16_t num = j - 1; num <= j + 1; num++){ - int16_t nnum = TCHTOIS(num); - if(num != TCITOHS(nnum)) err = true; - } - } - for(int32_t j = 1; j <= 0x20000000; j *= 2){ - for(int32_t num = j - 1; num <= j + 1; num++){ - int32_t nnum = TCHTOIL(num); - if(num != TCITOHL(nnum)) err = true; - char buf[TCNUMBUFSIZ]; - int step, nstep; - TCSETVNUMBUF(step, buf, num); - TCREADVNUMBUF(buf, nnum, nstep); - if(num != nnum || step != nstep) err = true; - } - } - for(int64_t j = 1; j <= 0x2000000000000000; j *= 2){ - for(int64_t num = j - 1; num <= j + 1; num++){ - int64_t nnum = TCHTOILL(num); - if(num != TCITOHLL(nnum)) err = true; - char buf[TCNUMBUFSIZ]; - int step, nstep; - TCSETVNUMBUF64(step, buf, num); - TCREADVNUMBUF64(buf, nnum, nstep); - if(num != nnum || step != nstep) err = true; - } - } - char *bitmap = TCBITMAPNEW(100); - for(int j = 0; j < 100; j++){ - if(j % 3 == 0) TCBITMAPON(bitmap, j); - if(j % 5 == 0) TCBITMAPOFF(bitmap, j); - } - for(int j = 0; j < 100; j++){ - if(j % 5 == 0){ - if(TCBITMAPCHECK(bitmap, j)) err = true; - } else if(j % 3 == 0){ - if(!TCBITMAPCHECK(bitmap, j)) err = true; - } - } - TCBITMAPDEL(bitmap); - buf = tcmalloc(i / 8 + 2); - TCBITSTRM strm; - TCBITSTRMINITW(strm, buf); - for(int j = 0; j < i; j++){ - int sign = j % 3 == 0 || j % 7 == 0; - TCBITSTRMCAT(strm, sign); - } - TCBITSTRMSETEND(strm); - int bnum = TCBITSTRMNUM(strm); - if(bnum != i) err = true; - TCBITSTRMINITR(strm, buf, bsiz); - for(int j = 0; j < i; j++){ - int sign; - TCBITSTRMREAD(strm, sign); - if(sign != (j % 3 == 0 || j % 7 == 0)) err = true; - } - free(buf); - } - if(rnum > 250 && i % (rnum / 250) == 0){ - putchar('.'); - fflush(stdout); - if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i); - } - } - iprintf("time: %.3f\n", tctime() - stime); - if(err){ - iprintf("error\n\n"); - return 1; - } - iprintf("ok\n\n"); - return 0; -} - - -/* perform wicked command */ -static int procwicked(int rnum){ - iprintf("\n rnum=%d\n\n", rnum); - double stime = tctime(); - TCMPOOL *mpool = tcmpoolglobal(); - TCXSTR *xstr = myrand(2) > 0 ? tcxstrnew() : tcxstrnew2("hello world"); - tcmpoolputxstr(mpool, xstr); - TCLIST *list = myrand(2) > 0 ? tclistnew() : tclistnew2(myrand(rnum) + rnum / 2); - tcmpoolputlist(mpool, list); - TCMAP *map = myrand(2) > 0 ? tcmapnew() : tcmapnew2(myrand(rnum) + rnum / 2); - tcmpoolputmap(mpool, map); - TCMDB *mdb = myrand(2) > 0 ? tcmdbnew() : tcmdbnew2(myrand(rnum) + rnum / 2); - tcmpoolput(mpool, mdb, (void (*)(void*))tcmdbdel); - for(int i = 1; i <= rnum; i++){ - char kbuf[RECBUFSIZ]; - int ksiz = sprintf(kbuf, "%d", myrand(i)); - char vbuf[RECBUFSIZ]; - int vsiz = sprintf(vbuf, "%d", myrand(i)); - char *tmp; - switch(myrand(69)){ - case 0: - putchar('0'); - tcxstrcat(xstr, kbuf, ksiz); - break; - case 1: - putchar('1'); - tcxstrcat2(xstr, kbuf); - break; - case 2: - putchar('2'); - if(myrand(rnum / 100 + 1) == 0) tcxstrclear(xstr); - break; - case 3: - putchar('3'); - tcxstrprintf(xstr, "[%s:%d]", kbuf, i); - break; - case 4: - putchar('4'); - tclistpush(list, kbuf, ksiz); - break; - case 5: - putchar('5'); - tclistpush2(list, kbuf); - break; - case 6: - putchar('6'); - tmp = tcmemdup(kbuf, ksiz); - tclistpushmalloc(list, tmp, strlen(tmp)); - break; - case 7: - putchar('7'); - if(myrand(10) == 0) free(tclistpop(list, &ksiz)); - break; - case 8: - putchar('8'); - if(myrand(10) == 0) free(tclistpop2(list)); - break; - case 9: - putchar('9'); - tclistunshift(list, kbuf, ksiz); - break; - case 10: - putchar('A'); - tclistunshift2(list, kbuf); - break; - case 11: - putchar('B'); - if(myrand(10) == 0) free(tclistshift(list, &ksiz)); - break; - case 12: - putchar('C'); - if(myrand(10) == 0) free(tclistshift2(list)); - break; - case 13: - putchar('D'); - tclistinsert(list, i / 10, kbuf, ksiz); - break; - case 14: - putchar('E'); - tclistinsert2(list, i / 10, kbuf); - break; - case 15: - putchar('F'); - if(myrand(10) == 0) free(tclistremove(list, i / 10, &ksiz)); - break; - case 16: - putchar('G'); - if(myrand(10) == 0) free(tclistremove2(list, i / 10)); - break; - case 17: - putchar('H'); - tclistover(list, i / 10, kbuf, ksiz); - break; - case 18: - putchar('I'); - tclistover2(list, i / 10, kbuf); - break; - case 19: - putchar('J'); - if(myrand(rnum / 1000 + 1) == 0) tclistsort(list); - break; - case 20: - putchar('K'); - if(myrand(rnum / 1000 + 1) == 0) tclistsortci(list); - break; - case 21: - putchar('L'); - if(myrand(rnum / 1000 + 1) == 0) tclistlsearch(list, kbuf, ksiz); - break; - case 22: - putchar('M'); - if(myrand(rnum / 1000 + 1) == 0) tclistbsearch(list, kbuf, ksiz); - break; - case 23: - putchar('N'); - if(myrand(rnum / 100 + 1) == 0) tclistclear(list); - break; - case 24: - putchar('O'); - if(myrand(rnum / 100 + 1) == 0){ - int dsiz; - char *dbuf = tclistdump(list, &dsiz); - tclistdel(tclistload(dbuf, dsiz)); - free(dbuf); - } - break; - case 25: - putchar('P'); - if(myrand(100) == 0){ - if(myrand(2) == 0){ - for(int j = 0; j < tclistnum(list); j++){ - int rsiz; - tclistval(list, j, &rsiz); - } - } else { - for(int j = 0; j < tclistnum(list); j++){ - tclistval2(list, j); - } - } - } - break; - case 26: - putchar('Q'); - tcmapput(map, kbuf, ksiz, vbuf, vsiz); - break; - case 27: - putchar('R'); - tcmapput2(map, kbuf, vbuf); - break; - case 28: - putchar('S'); - tcmapput3(map, kbuf, ksiz, vbuf, vsiz, vbuf, vsiz); - break; - case 29: - putchar('T'); - tcmapputkeep(map, kbuf, ksiz, vbuf, vsiz); - break; - case 30: - putchar('U'); - tcmapputkeep2(map, kbuf, vbuf); - break; - case 31: - putchar('V'); - tcmapputcat(map, kbuf, ksiz, vbuf, vsiz); - break; - case 32: - putchar('W'); - tcmapputcat2(map, kbuf, vbuf); - break; - case 33: - putchar('X'); - if(myrand(10) == 0) tcmapout(map, kbuf, ksiz); - break; - case 34: - putchar('Y'); - if(myrand(10) == 0) tcmapout2(map, kbuf); - break; - case 35: - putchar('Z'); - tcmapget3(map, kbuf, ksiz, &vsiz); - break; - case 36: - putchar('a'); - tcmapmove(map, kbuf, ksiz, true); - break; - case 37: - putchar('b'); - tcmapmove(map, kbuf, ksiz, false); - break; - case 38: - putchar('c'); - tcmapmove2(map, kbuf, true); - break; - case 39: - putchar('d'); - if(myrand(100) == 0) tcmapiterinit(map); - break; - case 40: - putchar('e'); - tcmapiternext(map, &vsiz); - break; - case 41: - putchar('f'); - tcmapiternext2(map); - break; - case 42: - putchar('g'); - if(myrand(100) == 0){ - if(myrand(2) == 0){ - tclistdel(tcmapkeys(map)); - } else { - tclistdel(tcmapvals(map)); - } - } - break; - case 43: - putchar('h'); - if(myrand(rnum / 100 + 1) == 0) tcmapclear(map); - break; - case 44: - putchar('i'); - if(myrand(20) == 0) tcmapcutfront(map, myrand(10)); - break; - case 45: - putchar('j'); - if(myrand(rnum / 100 + 1) == 0){ - int dsiz; - char *dbuf = tcmapdump(map, &dsiz); - free(tcmaploadone(dbuf, dsiz, kbuf, ksiz, &vsiz)); - tcmapdel(tcmapload(dbuf, dsiz)); - free(dbuf); - } - break; - case 46: - putchar('k'); - tcmdbput(mdb, kbuf, ksiz, vbuf, vsiz); - break; - case 47: - putchar('l'); - tcmdbput2(mdb, kbuf, vbuf); - break; - case 48: - putchar('m'); - tcmdbputkeep(mdb, kbuf, ksiz, vbuf, vsiz); - break; - case 49: - putchar('n'); - tcmdbputkeep2(mdb, kbuf, vbuf); - break; - case 50: - putchar('o'); - tcmdbputcat(mdb, kbuf, ksiz, vbuf, vsiz); - break; - case 51: - putchar('p'); - tcmdbputcat2(mdb, kbuf, vbuf); - break; - case 52: - putchar('q'); - if(myrand(10) == 0) tcmdbout(mdb, kbuf, ksiz); - break; - case 53: - putchar('r'); - if(myrand(10) == 0) tcmdbout2(mdb, kbuf); - break; - case 54: - putchar('s'); - free(tcmdbget(mdb, kbuf, ksiz, &vsiz)); - break; - case 55: - putchar('t'); - free(tcmdbget3(mdb, kbuf, ksiz, &vsiz)); - break; - case 56: - putchar('u'); - if(myrand(100) == 0) tcmdbiterinit(mdb); - break; - case 57: - putchar('v'); - free(tcmdbiternext(mdb, &vsiz)); - break; - case 58: - putchar('w'); - tmp = tcmdbiternext2(mdb); - free(tmp); - break; - case 59: - putchar('x'); - if(myrand(rnum / 100 + 1) == 0) tcmdbvanish(mdb); - break; - case 60: - putchar('y'); - if(myrand(200) == 0) tcmdbcutfront(mdb, myrand(100)); - break; - case 61: - putchar('+'); - if(myrand(100) == 0) tcmpoolmalloc(mpool, 1); - break; - case 62: - putchar('+'); - if(myrand(100) == 0) tcmpoolxstrnew(mpool); - break; - case 63: - putchar('+'); - if(myrand(100) == 0) tcmpoollistnew(mpool); - break; - case 64: - putchar('+'); - if(myrand(100) == 0) tcmpoolmapnew(mpool); - break; - default: - putchar('@'); - if(myrand(10000) == 0) srand((unsigned int)(tctime() * 1000) % UINT_MAX); - break; - } - if(i % 50 == 0) iprintf(" (%08d)\n", i); - } - if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum); - iprintf("time: %.3f\n", tctime() - stime); - iprintf("ok\n\n"); - return 0; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcutil.c b/bacula/src/lib/tokyocabinet/tcutil.c deleted file mode 100644 index 19cba35557..0000000000 --- a/bacula/src/lib/tokyocabinet/tcutil.c +++ /dev/null @@ -1,5014 +0,0 @@ -/************************************************************************************************* - * The utility API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#include "tcutil.h" -#include "myconf.h" - - -/************************************************************************************************* - * basic utilities - *************************************************************************************************/ - - -/* String containing the version information. */ -const char *tcversion = _TC_VERSION; - - -/* Call back function for handling a fatal error. */ -void (*tcfatalfunc)(const char *message) = NULL; - - -/* Allocate a region on memory. */ -void *tcmalloc(size_t size){ - assert(size > 0 && size < INT_MAX); - char *p = malloc(size); - if(!p) tcmyfatal("out of memory"); - return p; -} - - -/* Allocate a nullified region on memory. */ -void *tccalloc(size_t nmemb, size_t size){ - assert(nmemb > 0 && size < INT_MAX && size > 0 && size < INT_MAX); - char *p = calloc(nmemb, size); - if(!p) tcmyfatal("out of memory"); - return p; -} - - -/* Re-allocate a region on memory. */ -void *tcrealloc(void *ptr, size_t size){ - assert(size >= 0 && size < INT_MAX); - char *p = realloc(ptr, size); - if(!p) tcmyfatal("out of memory"); - return p; -} - - -/* Duplicate a region on memory. */ -void *tcmemdup(const void *ptr, size_t size){ - assert(ptr && size >= 0); - char *p; - TCMALLOC(p, size + 1); - memcpy(p, ptr, size); - p[size] = '\0'; - return p; -} - - -/* Duplicate a string on memory. */ -char *tcstrdup(const void *str){ - assert(str); - int size = strlen(str); - char *p; - TCMALLOC(p, size + 1); - memcpy(p, str, size); - p[size] = '\0'; - return p; -} - - -/* Free a region on memory. */ -void tcfree(void *ptr){ - free(ptr); -} - - - -/************************************************************************************************* - * extensible string - *************************************************************************************************/ - - -#define TCXSTRUNIT 12 // allocation unit size of an extensible string - - -/* private function prototypes */ -static void tcvxstrprintf(TCXSTR *xstr, const char *format, va_list ap); - - -/* Create an extensible string object. */ -TCXSTR *tcxstrnew(void){ - TCXSTR *xstr; - TCMALLOC(xstr, sizeof(*xstr)); - TCMALLOC(xstr->ptr, TCXSTRUNIT); - xstr->size = 0; - xstr->asize = TCXSTRUNIT; - xstr->ptr[0] = '\0'; - return xstr; -} - - -/* Create an extensible string object from a character string. */ -TCXSTR *tcxstrnew2(const char *str){ - assert(str); - TCXSTR *xstr; - TCMALLOC(xstr, sizeof(*xstr)); - int size = strlen(str); - int asize = tclmax(size + 1, TCXSTRUNIT); - TCMALLOC(xstr->ptr, asize); - xstr->size = size; - xstr->asize = asize; - memcpy(xstr->ptr, str, size + 1); - return xstr; -} - - -/* Create an extensible string object with the initial allocation size. */ -TCXSTR *tcxstrnew3(int asiz){ - assert(asiz >= 0); - asiz = tclmax(asiz, TCXSTRUNIT); - TCXSTR *xstr; - TCMALLOC(xstr, sizeof(*xstr)); - TCMALLOC(xstr->ptr, asiz); - xstr->size = 0; - xstr->asize = asiz; - xstr->ptr[0] = '\0'; - return xstr; -} - - -/* Copy an extensible string object. */ -TCXSTR *tcxstrdup(const TCXSTR *xstr){ - assert(xstr); - TCXSTR *nxstr; - TCMALLOC(nxstr, sizeof(*nxstr)); - int asize = tclmax(xstr->size + 1, TCXSTRUNIT); - TCMALLOC(nxstr->ptr, asize); - nxstr->size = xstr->size; - nxstr->asize = asize; - memcpy(nxstr->ptr, xstr->ptr, xstr->size + 1); - return nxstr; -} - - -/* Delete an extensible string object. */ -void tcxstrdel(TCXSTR *xstr){ - assert(xstr); - free(xstr->ptr); - free(xstr); -} - - -/* Concatenate a region to the end of an extensible string object. */ -void tcxstrcat(TCXSTR *xstr, const void *ptr, int size){ - assert(xstr && ptr && size >= 0); - int nsize = xstr->size + size + 1; - if(xstr->asize < nsize){ - while(xstr->asize < nsize){ - xstr->asize *= 2; - if(xstr->asize < nsize) xstr->asize = nsize; - } - TCREALLOC(xstr->ptr, xstr->ptr, xstr->asize); - } - memcpy(xstr->ptr + xstr->size, ptr, size); - xstr->size += size; - xstr->ptr[xstr->size] = '\0'; -} - - -/* Concatenate a character string to the end of an extensible string object. */ -void tcxstrcat2(TCXSTR *xstr, const char *str){ - assert(xstr && str); - int size = strlen(str); - int nsize = xstr->size + size + 1; - if(xstr->asize < nsize){ - while(xstr->asize < nsize){ - xstr->asize *= 2; - if(xstr->asize < nsize) xstr->asize = nsize; - } - TCREALLOC(xstr->ptr, xstr->ptr, xstr->asize); - } - memcpy(xstr->ptr + xstr->size, str, size + 1); - xstr->size += size; -} - - -/* Get the pointer of the region of an extensible string object. */ -const void *tcxstrptr(const TCXSTR *xstr){ - assert(xstr); - return xstr->ptr; -} - - -/* Get the size of the region of an extensible string object. */ -int tcxstrsize(const TCXSTR *xstr){ - assert(xstr); - return xstr->size; -} - - -/* Clear an extensible string object. */ -void tcxstrclear(TCXSTR *xstr){ - assert(xstr); - xstr->size = 0; - xstr->ptr[0] = '\0'; -} - - -/* Convert an extensible string object into a usual allocated region. */ -void *tcxstrtomalloc(TCXSTR *xstr){ - assert(xstr); - char *ptr; - ptr = xstr->ptr; - free(xstr); - return ptr; -} - - -/* Create an extensible string object from an allocated region. */ -TCXSTR *tcxstrfrommalloc(void *ptr, int size){ - TCXSTR *xstr; - TCMALLOC(xstr, sizeof(*xstr)); - TCREALLOC(xstr->ptr, ptr, size + 1); - xstr->ptr[size] = '\0'; - xstr->size = size; - xstr->asize = size; - return xstr; -} - - -/* Perform formatted output into an extensible string object. */ -void tcxstrprintf(TCXSTR *xstr, const char *format, ...){ - assert(xstr && format); - va_list ap; - va_start(ap, format); - tcvxstrprintf(xstr, format, ap); - va_end(ap); -} - - -/* Allocate a formatted string on memory. */ -char *tcsprintf(const char *format, ...){ - assert(format); - TCXSTR *xstr = tcxstrnew(); - va_list ap; - va_start(ap, format); - tcvxstrprintf(xstr, format, ap); - va_end(ap); - return tcxstrtomalloc(xstr); -} - - -/* Perform formatted output into an extensible string object. */ -static void tcvxstrprintf(TCXSTR *xstr, const char *format, va_list ap){ - assert(xstr && format); - while(*format != '\0'){ - if(*format == '%'){ - char cbuf[TCNUMBUFSIZ]; - cbuf[0] = '%'; - int cblen = 1; - int lnum = 0; - format++; - while(strchr("0123456789 .+-hlLz", *format) && *format != '\0' && - cblen < TCNUMBUFSIZ - 1){ - if(*format == 'l' || *format == 'L') lnum++; - cbuf[cblen++] = *(format++); - } - cbuf[cblen++] = *format; - cbuf[cblen] = '\0'; - int tlen; - char *tmp, tbuf[TCNUMBUFSIZ*2]; - switch(*format){ - case 's': - tmp = va_arg(ap, char *); - if(!tmp) tmp = "(null)"; - tcxstrcat2(xstr, tmp); - break; - case 'd': - if(lnum >= 2){ - tlen = sprintf(tbuf, cbuf, va_arg(ap, long long)); - } else if(lnum >= 1){ - tlen = sprintf(tbuf, cbuf, va_arg(ap, long)); - } else { - tlen = sprintf(tbuf, cbuf, va_arg(ap, int)); - } - TCXSTRCAT(xstr, tbuf, tlen); - break; - case 'o': case 'u': case 'x': case 'X': case 'c': - if(lnum >= 2){ - tlen = sprintf(tbuf, cbuf, va_arg(ap, unsigned long long)); - } else if(lnum >= 1){ - tlen = sprintf(tbuf, cbuf, va_arg(ap, unsigned long)); - } else { - tlen = sprintf(tbuf, cbuf, va_arg(ap, unsigned int)); - } - TCXSTRCAT(xstr, tbuf, tlen); - break; - case 'e': case 'E': case 'f': case 'g': case 'G': - if(lnum >= 1){ - tlen = sprintf(tbuf, cbuf, va_arg(ap, long double)); - } else { - tlen = sprintf(tbuf, cbuf, va_arg(ap, double)); - } - TCXSTRCAT(xstr, tbuf, tlen); - break; - case '@': - tmp = va_arg(ap, char *); - if(!tmp) tmp = "(null)"; - while(*tmp){ - switch(*tmp){ - case '&': TCXSTRCAT(xstr, "&", 5); break; - case '<': TCXSTRCAT(xstr, "<", 4); break; - case '>': TCXSTRCAT(xstr, ">", 4); break; - case '"': TCXSTRCAT(xstr, """, 6); break; - default: - if(!((*tmp >= 0 && *tmp <= 0x8) || (*tmp >= 0x0e && *tmp <= 0x1f))) - TCXSTRCAT(xstr, tmp, 1); - break; - } - tmp++; - } - break; - case '?': - tmp = va_arg(ap, char *); - if(!tmp) tmp = "(null)"; - while(*tmp){ - unsigned char c = *(unsigned char *)tmp; - if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') || (c != '\0' && strchr("_-.", c))){ - TCXSTRCAT(xstr, tmp, 1); - } else { - tlen = sprintf(tbuf, "%%%02X", c); - TCXSTRCAT(xstr, tbuf, tlen); - } - tmp++; - } - break; - case '%': - TCXSTRCAT(xstr, "%", 1); - break; - } - } else { - TCXSTRCAT(xstr, format, 1); - } - format++; - } -} - - - -/************************************************************************************************* - * array list - *************************************************************************************************/ - - -#define TCLISTUNIT 64 // allocation unit number of a list handle - - -/* private function prototypes */ -static int tclistelemcmp(const void *a, const void *b); -static int tclistelemcmpci(const void *a, const void *b); - - -/* Create a list object. */ -TCLIST *tclistnew(void){ - TCLIST *list; - TCMALLOC(list, sizeof(*list)); - list->anum = TCLISTUNIT; - TCMALLOC(list->array, sizeof(list->array[0]) * list->anum); - list->start = 0; - list->num = 0; - return list; -} - - -/* Create a list object. */ -TCLIST *tclistnew2(int anum){ - TCLIST *list; - TCMALLOC(list, sizeof(*list)); - if(anum < 1) anum = 1; - list->anum = anum; - TCMALLOC(list->array, sizeof(list->array[0]) * list->anum); - list->start = 0; - list->num = 0; - return list; -} - - -/* Copy a list object. */ -TCLIST *tclistdup(const TCLIST *list){ - assert(list); - int num = list->num; - if(num < 1) tclistnew(); - const TCLISTDATUM *array = list->array + list->start; - TCLIST *nlist; - TCMALLOC(nlist, sizeof(*nlist)); - TCLISTDATUM *narray; - TCMALLOC(narray, sizeof(list->array[0]) * tclmax(num, 1)); - for(int i = 0; i < num; i++){ - int size = array[i].size; - TCMALLOC(narray[i].ptr, tclmax(size + 1, TCXSTRUNIT)); - memcpy(narray[i].ptr, array[i].ptr, size + 1); - narray[i].size = array[i].size; - } - nlist->anum = num; - nlist->array = narray; - nlist->start = 0; - nlist->num = num; - return nlist; -} - - -/* Delete a list object. */ -void tclistdel(TCLIST *list){ - assert(list); - TCLISTDATUM *array = list->array; - int end = list->start + list->num; - for(int i = list->start; i < end; i++){ - free(array[i].ptr); - } - free(list->array); - free(list); -} - - -/* Get the number of elements of a list object. */ -int tclistnum(const TCLIST *list){ - assert(list); - return list->num; -} - - -/* Get the pointer to the region of an element of a list object. */ -const void *tclistval(const TCLIST *list, int index, int *sp){ - assert(list && index >= 0 && sp); - if(index >= list->num) return NULL; - index += list->start; - *sp = list->array[index].size; - return list->array[index].ptr; -} - - -/* Get the string of an element of a list object. */ -const char *tclistval2(const TCLIST *list, int index){ - assert(list && index >= 0); - if(index >= list->num) return NULL; - index += list->start; - return list->array[index].ptr; -} - - -/* Add an element at the end of a list object. */ -void tclistpush(TCLIST *list, const void *ptr, int size){ - assert(list && ptr && size >= 0); - int index = list->start + list->num; - if(index >= list->anum){ - list->anum += list->num + 1; - TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); - } - TCLISTDATUM *array = list->array; - TCMALLOC(array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); - memcpy(array[index].ptr, ptr, size); - array[index].ptr[size] = '\0'; - array[index].size = size; - list->num++; -} - - -/* Add a string element at the end of a list object. */ -void tclistpush2(TCLIST *list, const char *str){ - assert(list && str); - int index = list->start + list->num; - if(index >= list->anum){ - list->anum += list->num + 1; - TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); - } - int size = strlen(str); - TCLISTDATUM *array = list->array; - TCMALLOC(array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); - memcpy(array[index].ptr, str, size + 1); - array[index].size = size; - list->num++; -} - - -/* Add an allocated element at the end of a list object. */ -void tclistpushmalloc(TCLIST *list, void *ptr, int size){ - assert(list && ptr && size >= 0); - int index = list->start + list->num; - if(index >= list->anum){ - list->anum += list->num + 1; - TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); - } - TCLISTDATUM *array = list->array; - TCREALLOC(array[index].ptr, ptr, size + 1); - array[index].ptr[size] = '\0'; - array[index].size = size; - list->num++; -} - - -/* Remove an element of the end of a list object. */ -void *tclistpop(TCLIST *list, int *sp){ - assert(list && sp); - if(list->num < 1) return NULL; - int index = list->start + list->num - 1; - list->num--; - *sp = list->array[index].size; - return list->array[index].ptr; -} - - -/* Remove a string element of the end of a list object. */ -char *tclistpop2(TCLIST *list){ - assert(list); - if(list->num < 1) return NULL; - int index = list->start + list->num - 1; - list->num--; - return list->array[index].ptr; -} - - -/* Add an element at the top of a list object. */ -void tclistunshift(TCLIST *list, const void *ptr, int size){ - assert(list && ptr && size >= 0); - if(list->start < 1){ - if(list->start + list->num >= list->anum){ - list->anum += list->num + 1; - TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); - } - list->start = list->anum - list->num; - memmove(list->array + list->start, list->array, list->num * sizeof(list->array[0])); - } - int index = list->start - 1; - TCMALLOC(list->array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); - memcpy(list->array[index].ptr, ptr, size); - list->array[index].ptr[size] = '\0'; - list->array[index].size = size; - list->start--; - list->num++; -} - - -/* Add a string element at the top of a list object. */ -void tclistunshift2(TCLIST *list, const char *str){ - assert(list && str); - if(list->start < 1){ - if(list->start + list->num >= list->anum){ - list->anum += list->num + 1; - TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); - } - list->start = list->anum - list->num; - memmove(list->array + list->start, list->array, list->num * sizeof(list->array[0])); - } - int index = list->start - 1; - int size = strlen(str); - TCMALLOC(list->array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); - memcpy(list->array[index].ptr, str, size + 1); - list->array[index].size = size; - list->start--; - list->num++; -} - - -/* Remove an element of the top of a list object. */ -void *tclistshift(TCLIST *list, int *sp){ - assert(list && sp); - if(list->num < 1) return NULL; - int index = list->start; - list->start++; - list->num--; - *sp = list->array[index].size; - void *rv = list->array[index].ptr; - if((list->start & 0xff) == 0 && list->start > (list->num >> 1)){ - memmove(list->array, list->array + list->start, list->num * sizeof(list->array[0])); - list->start = 0; - } - return rv; -} - - -/* Remove a string element of the top of a list object. */ -char *tclistshift2(TCLIST *list){ - assert(list); - if(list->num < 1) return NULL; - int index = list->start; - list->start++; - list->num--; - void *rv = list->array[index].ptr; - if((list->start & 0xff) == 0 && list->start > (list->num >> 1)){ - memmove(list->array, list->array + list->start, list->num * sizeof(list->array[0])); - list->start = 0; - } - return rv; -} - - -/* Add an element at the specified location of a list object. */ -void tclistinsert(TCLIST *list, int index, const void *ptr, int size){ - assert(list && index >= 0 && ptr && size >= 0); - if(index > list->num) return; - index += list->start; - if(list->start + list->num >= list->anum){ - list->anum += list->num + 1; - TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); - } - memmove(list->array + index + 1, list->array + index, - sizeof(list->array[0]) * (list->start + list->num - index)); - TCMALLOC(list->array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); - memcpy(list->array[index].ptr, ptr, size); - list->array[index].ptr[size] = '\0'; - list->array[index].size = size; - list->num++; -} - - -/* Add a string element at the specified location of a list object. */ -void tclistinsert2(TCLIST *list, int index, const char *str){ - assert(list && index >= 0 && str); - if(index > list->num) return; - index += list->start; - if(list->start + list->num >= list->anum){ - list->anum += list->num + 1; - TCREALLOC(list->array, list->array, list->anum * sizeof(list->array[0])); - } - memmove(list->array + index + 1, list->array + index, - sizeof(list->array[0]) * (list->start + list->num - index)); - int size = strlen(str); - TCMALLOC(list->array[index].ptr, tclmax(size + 1, TCXSTRUNIT)); - memcpy(list->array[index].ptr, str, size); - list->array[index].ptr[size] = '\0'; - list->array[index].size = size; - list->num++; -} - - -/* Remove an element at the specified location of a list object. */ -void *tclistremove(TCLIST *list, int index, int *sp){ - assert(list && index >= 0 && sp); - if(index >= list->num) return NULL; - index += list->start; - char *ptr = list->array[index].ptr; - *sp = list->array[index].size; - list->num--; - memmove(list->array + index, list->array + index + 1, - sizeof(list->array[0]) * (list->start + list->num - index)); - return ptr; -} - - -/* Remove a string element at the specified location of a list object. */ -char *tclistremove2(TCLIST *list, int index){ - assert(list && index >= 0); - if(index >= list->num) return NULL; - index += list->start; - char *ptr = list->array[index].ptr; - list->num--; - memmove(list->array + index, list->array + index + 1, - sizeof(list->array[0]) * (list->start + list->num - index)); - return ptr; -} - - -/* Overwrite an element at the specified location of a list object. */ -void tclistover(TCLIST *list, int index, const void *ptr, int size){ - assert(list && index >= 0 && ptr && size >= 0); - if(index >= list->num) return; - index += list->start; - if(size > list->array[index].size) - TCREALLOC(list->array[index].ptr, list->array[index].ptr, size + 1); - memcpy(list->array[index].ptr, ptr, size); - list->array[index].size = size; - list->array[index].ptr[size] = '\0'; -} - - -/* Overwrite a string element at the specified location of a list object. */ -void tclistover2(TCLIST *list, int index, const char *str){ - assert(list && index >= 0 && str); - if(index >= list->num) return; - index += list->start; - int size = strlen(str); - if(size > list->array[index].size) - TCREALLOC(list->array[index].ptr, list->array[index].ptr, size + 1); - memcpy(list->array[index].ptr, str, size + 1); - list->array[index].size = size; -} - - -/* Sort elements of a list object in lexical order. */ -void tclistsort(TCLIST *list){ - assert(list); - qsort(list->array + list->start, list->num, sizeof(list->array[0]), tclistelemcmp); -} - - -/* Sort elements of a list object in case-insensitive lexical order. */ -void tclistsortci(TCLIST *list){ - assert(list); - qsort(list->array + list->start, list->num, sizeof(list->array[0]), tclistelemcmpci); -} - - -/* Sort elements of a list object by an arbitrary comparison function. */ -void tclistsortex(TCLIST *list, int (*cmp)(const TCLISTDATUM *, const TCLISTDATUM *)){ - assert(list && cmp); - qsort(list->array + list->start, list->num, sizeof(list->array[0]), - (int (*)(const void *, const void *))cmp); -} - - -/* Search a list object for an element using liner search. */ -int tclistlsearch(const TCLIST *list, const void *ptr, int size){ - assert(list && ptr && size >= 0); - int end = list->start + list->num; - for(int i = list->start; i < end; i++){ - if(list->array[i].size == size && !memcmp(list->array[i].ptr, ptr, size)) - return i - list->start; - } - return -1; -} - - -/* Search a list object for an element using binary search. */ -int tclistbsearch(const TCLIST *list, const void *ptr, int size){ - assert(list && ptr && size >= 0); - TCLISTDATUM key; - key.ptr = (char *)ptr; - key.size = size; - TCLISTDATUM *res = bsearch(&key, list->array + list->start, - list->num, sizeof(list->array[0]), tclistelemcmp); - return res ? res - list->array - list->start : -1; -} - - -/* Clear a list object. */ -void tclistclear(TCLIST *list){ - assert(list); - TCLISTDATUM *array = list->array; - int end = list->start + list->num; - for(int i = list->start; i < end; i++){ - free(array[i].ptr); - } - list->start = 0; - list->num = 0; -} - - -/* Serialize a list object into a byte array. */ -void *tclistdump(const TCLIST *list, int *sp){ - assert(list && sp); - const TCLISTDATUM *array = list->array; - int end = list->start + list->num; - int tsiz = 0; - for(int i = list->start; i < end; i++){ - tsiz += array[i].size + sizeof(int); - } - char *buf; - TCMALLOC(buf, tsiz + 1); - char *wp = buf; - for(int i = list->start; i < end; i++){ - int step; - TCSETVNUMBUF(step, wp, array[i].size); - wp += step; - memcpy(wp, array[i].ptr, array[i].size); - wp += array[i].size; - } - *sp = wp - buf; - return buf; -} - - -/* Create a list object from a serialized byte array. */ -TCLIST *tclistload(const void *ptr, int size){ - assert(ptr && size >= 0); - TCLIST *list; - TCMALLOC(list, sizeof(*list)); - int anum = size / sizeof(int) + 1; - TCLISTDATUM *array; - TCMALLOC(array, sizeof(array[0]) * anum); - int num = 0; - const char *rp = ptr; - const char *ep = (char *)ptr + size; - while(rp < ep){ - int step, vsiz; - TCREADVNUMBUF(rp, vsiz, step); - rp += step; - if(num >= anum){ - anum *= 2; - TCREALLOC(array, array, anum * sizeof(array[0])); - } - TCMALLOC(array[num].ptr, tclmax(vsiz + 1, TCXSTRUNIT)); - memcpy(array[num].ptr, rp, vsiz); - array[num].ptr[vsiz] = '\0'; - array[num].size = vsiz; - num++; - rp += vsiz; - } - list->anum = anum; - list->array = array; - list->start = 0; - list->num = num; - return list; -} - - -/* Compare two list elements in lexical order. - `a' specifies the pointer to one element. - `b' specifies the pointer to the other element. - The return value is positive if the former is big, negative if the latter is big, 0 if both - are equivalent. */ -static int tclistelemcmp(const void *a, const void *b){ - assert(a && b); - unsigned char *ao = (unsigned char *)((TCLISTDATUM *)a)->ptr; - unsigned char *bo = (unsigned char *)((TCLISTDATUM *)b)->ptr; - int size = (((TCLISTDATUM *)a)->size < ((TCLISTDATUM *)b)->size) ? - ((TCLISTDATUM *)a)->size : ((TCLISTDATUM *)b)->size; - for(int i = 0; i < size; i++){ - if(ao[i] > bo[i]) return 1; - if(ao[i] < bo[i]) return -1; - } - return ((TCLISTDATUM *)a)->size - ((TCLISTDATUM *)b)->size; -} - - -/* Compare two list elements in case-insensitive lexical order.. - `a' specifies the pointer to one element. - `b' specifies the pointer to the other element. - The return value is positive if the former is big, negative if the latter is big, 0 if both - are equivalent. */ -static int tclistelemcmpci(const void *a, const void *b){ - assert(a && b); - TCLISTDATUM *ap = (TCLISTDATUM *)a; - TCLISTDATUM *bp = (TCLISTDATUM *)b; - unsigned char *ao = (unsigned char *)ap->ptr; - unsigned char *bo = (unsigned char *)bp->ptr; - int size = (ap->size < bp->size) ? ap->size : bp->size; - for(int i = 0; i < size; i++){ - int ac = ao[i]; - bool ab = false; - if(ac >= 'A' && ac <= 'Z'){ - ac += 'a' - 'A'; - ab = true; - } - int bc = bo[i]; - bool bb = false; - if(bc >= 'A' && bc <= 'Z'){ - bc += 'a' - 'A'; - bb = true; - } - if(ac > bc) return 1; - if(ac < bc) return -1; - if(!ab && bb) return 1; - if(ab && !bb) return -1; - } - return ap->size - bp->size; -} - - - -/************************************************************************************************* - * hash map - *************************************************************************************************/ - - -#define TCMAPBNUM 4093 // allocation unit number of a map -#define TCMAPCSUNIT 52 // small allocation unit size of map concatenation -#define TCMAPCBUNIT 252 // big allocation unit size of map concatenation - -/* get the first hash value */ -#define TCMAPHASH1(TC_res, TC_kbuf, TC_ksiz) \ - do { \ - const unsigned char *_TC_p = (const unsigned char *)(TC_kbuf); \ - int _TC_ksiz = TC_ksiz; \ - for((TC_res) = 19780211; _TC_ksiz--;){ \ - (TC_res) = ((TC_res) << 5) + ((TC_res) << 2) + (TC_res) + *(_TC_p)++; \ - } \ - } while(false) - -/* get the second hash value */ -#define TCMAPHASH2(TC_res, TC_kbuf, TC_ksiz) \ - do { \ - const unsigned char *_TC_p = (const unsigned char *)(TC_kbuf) + TC_ksiz - 1; \ - int _TC_ksiz = TC_ksiz; \ - for((TC_res) = 0x13579bdf; _TC_ksiz--;){ \ - (TC_res) = ((TC_res) << 5) - (TC_res) + *(_TC_p)--; \ - } \ - } while(false) - -/* get the size of padding bytes for pointer alignment */ -#define TCALIGNPAD(TC_hsiz) \ - (((TC_hsiz | ~-(int)sizeof(void *)) + 1) - TC_hsiz) - -/* compare two keys */ -#define TCKEYCMP(TC_abuf, TC_asiz, TC_bbuf, TC_bsiz) \ - ((TC_asiz > TC_bsiz) ? 1 : (TC_asiz < TC_bsiz) ? -1 : memcmp(TC_abuf, TC_bbuf, TC_asiz)) - - -/* Create a map object. */ -TCMAP *tcmapnew(void){ - return tcmapnew2(TCMAPBNUM); -} - - -/* Create a map object with specifying the number of the buckets. */ -TCMAP *tcmapnew2(uint32_t bnum){ - if(bnum < 1) bnum = 1; - TCMAP *map; - TCMALLOC(map, sizeof(*map)); - TCMAPREC **buckets; - TCCALLOC(buckets, bnum, sizeof(map->buckets[0])); - map->buckets = buckets; - map->first = NULL; - map->last = NULL; - map->cur = NULL; - map->bnum = bnum; - map->rnum = 0; - map->msiz = 0; - return map; -} - - -/* Copy a map object. */ -TCMAP *tcmapdup(const TCMAP *map){ - assert(map); - TCMAP *nmap = tcmapnew2(tclmax(tclmax(map->bnum, map->rnum), TCMAPBNUM)); - TCMAPREC *cur = map->cur; - const char *kbuf; - int ksiz; - ((TCMAP *)map)->cur = map->first; - while((kbuf = tcmapiternext((TCMAP *)map, &ksiz)) != NULL){ - int vsiz; - const char *vbuf = tcmapiterval(kbuf, &vsiz); - tcmapputkeep(nmap, kbuf, ksiz, vbuf, vsiz); - } - ((TCMAP *)map)->cur = cur; - return nmap; -} - - -/* Close a map object. */ -void tcmapdel(TCMAP *map){ - assert(map); - TCMAPREC *rec = map->first; - while(rec){ - TCMAPREC *next = rec->next; - free(rec); - rec = next; - } - free(map->buckets); - free(map); -} - - -/* Store a record into a map object. */ -void tcmapput(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(map && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - int bidx = hash % map->bnum; - TCMAPREC *rec = map->buckets[bidx]; - TCMAPREC **entp = map->buckets + bidx; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - entp = &(rec->left); - rec = rec->left; - } else if(hash < rec->hash){ - entp = &(rec->right); - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - entp = &(rec->left); - rec = rec->left; - } else if(kcmp > 0){ - entp = &(rec->right); - rec = rec->right; - } else { - map->msiz += vsiz - rec->vsiz; - int psiz = TCALIGNPAD(ksiz); - if(vsiz > rec->vsiz){ - TCMAPREC *old = rec; - TCREALLOC(rec, rec, sizeof(*rec) + ksiz + psiz + vsiz + 1); - if(rec != old){ - if(map->first == old) map->first = rec; - if(map->last == old) map->last = rec; - if(map->cur == old) map->cur = rec; - if(*entp == old) *entp = rec; - if(rec->prev) rec->prev->next = rec; - if(rec->next) rec->next->prev = rec; - dbuf = (char *)rec + sizeof(*rec); - } - } - memcpy(dbuf + ksiz + psiz, vbuf, vsiz); - dbuf[ksiz+psiz+vsiz] = '\0'; - rec->vsiz = vsiz; - return; - } - } - } - int psiz = TCALIGNPAD(ksiz); - map->msiz += ksiz + vsiz; - TCMALLOC(rec, sizeof(*rec) + ksiz + psiz + vsiz + 1); - char *dbuf = (char *)rec + sizeof(*rec); - memcpy(dbuf, kbuf, ksiz); - dbuf[ksiz] = '\0'; - rec->ksiz = ksiz; - memcpy(dbuf + ksiz + psiz, vbuf, vsiz); - dbuf[ksiz+psiz+vsiz] = '\0'; - rec->vsiz = vsiz; - rec->hash = hash; - rec->left = NULL; - rec->right = NULL; - rec->prev = map->last; - rec->next = NULL; - *entp = rec; - if(!map->first) map->first = rec; - if(map->last) map->last->next = rec; - map->last = rec; - map->rnum++; -} - - -/* Store a string record into a map object. */ -void tcmapput2(TCMAP *map, const char *kstr, const char *vstr){ - assert(map && kstr && vstr); - tcmapput(map, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Store a record of the value of two regions into a map object. */ -void tcmapput3(TCMAP *map, const char *kbuf, int ksiz, - const void *fvbuf, int fvsiz, const char *lvbuf, int lvsiz){ - assert(map && kbuf && ksiz >= 0 && fvbuf && fvsiz >= 0 && lvbuf && lvsiz >= 0); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - int bidx = hash % map->bnum; - TCMAPREC *rec = map->buckets[bidx]; - TCMAPREC **entp = map->buckets + bidx; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - entp = &(rec->left); - rec = rec->left; - } else if(hash < rec->hash){ - entp = &(rec->right); - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - entp = &(rec->left); - rec = rec->left; - } else if(kcmp > 0){ - entp = &(rec->right); - rec = rec->right; - } else { - int vsiz = fvsiz + lvsiz; - map->msiz += vsiz - rec->vsiz; - int psiz = TCALIGNPAD(ksiz); - ksiz += psiz; - if(vsiz > rec->vsiz){ - TCMAPREC *old = rec; - TCREALLOC(rec, rec, sizeof(*rec) + ksiz + vsiz + 1); - if(rec != old){ - if(map->first == old) map->first = rec; - if(map->last == old) map->last = rec; - if(map->cur == old) map->cur = rec; - if(*entp == old) *entp = rec; - if(rec->prev) rec->prev->next = rec; - if(rec->next) rec->next->prev = rec; - dbuf = (char *)rec + sizeof(*rec); - } - } - memcpy(dbuf + ksiz, fvbuf, fvsiz); - memcpy(dbuf + ksiz + fvsiz, lvbuf, lvsiz); - dbuf[ksiz+vsiz] = '\0'; - rec->vsiz = vsiz; - return; - } - } - } - int vsiz = fvsiz + lvsiz; - int psiz = TCALIGNPAD(ksiz); - map->msiz += ksiz + vsiz; - TCMALLOC(rec, sizeof(*rec) + ksiz + psiz + vsiz + 1); - char *dbuf = (char *)rec + sizeof(*rec); - memcpy(dbuf, kbuf, ksiz); - dbuf[ksiz] = '\0'; - rec->ksiz = ksiz; - ksiz += psiz; - memcpy(dbuf + ksiz, fvbuf, fvsiz); - memcpy(dbuf + ksiz + fvsiz, lvbuf, lvsiz); - dbuf[ksiz+vsiz] = '\0'; - rec->vsiz = vsiz; - rec->hash = hash; - rec->left = NULL; - rec->right = NULL; - rec->prev = map->last; - rec->next = NULL; - *entp = rec; - if(!map->first) map->first = rec; - if(map->last) map->last->next = rec; - map->last = rec; - map->rnum++; -} - - -/* Store a new record into a map object. */ -bool tcmapputkeep(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(map && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - int bidx = hash % map->bnum; - TCMAPREC *rec = map->buckets[bidx]; - TCMAPREC **entp = map->buckets + bidx; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - entp = &(rec->left); - rec = rec->left; - } else if(hash < rec->hash){ - entp = &(rec->right); - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - entp = &(rec->left); - rec = rec->left; - } else if(kcmp > 0){ - entp = &(rec->right); - rec = rec->right; - } else { - return false; - } - } - } - int psiz = TCALIGNPAD(ksiz); - map->msiz += ksiz + vsiz; - TCMALLOC(rec, sizeof(*rec) + ksiz + psiz + vsiz + 1); - char *dbuf = (char *)rec + sizeof(*rec); - memcpy(dbuf, kbuf, ksiz); - dbuf[ksiz] = '\0'; - rec->ksiz = ksiz; - memcpy(dbuf + ksiz + psiz, vbuf, vsiz); - dbuf[ksiz+psiz+vsiz] = '\0'; - rec->vsiz = vsiz; - rec->hash = hash; - rec->left = NULL; - rec->right = NULL; - rec->prev = map->last; - rec->next = NULL; - *entp = rec; - if(!map->first) map->first = rec; - if(map->last) map->last->next = rec; - map->last = rec; - map->rnum++; - return true; -} - - -/* Store a new string record into a map object. - `map' specifies the map object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tcmapputkeep2(TCMAP *map, const char *kstr, const char *vstr){ - assert(map && kstr && vstr); - return tcmapputkeep(map, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Concatenate a value at the end of the value of the existing record in a map object. */ -void tcmapputcat(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(map && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - int bidx = hash % map->bnum; - TCMAPREC *rec = map->buckets[bidx]; - TCMAPREC **entp = map->buckets + bidx; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - entp = &(rec->left); - rec = rec->left; - } else if(hash < rec->hash){ - entp = &(rec->right); - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - entp = &(rec->left); - rec = rec->left; - } else if(kcmp > 0){ - entp = &(rec->right); - rec = rec->right; - } else { - map->msiz += vsiz; - int psiz = TCALIGNPAD(ksiz); - int asiz = sizeof(*rec) + ksiz + psiz + rec->vsiz + vsiz + 1; - int unit = (asiz <= TCMAPCSUNIT) ? TCMAPCSUNIT : TCMAPCBUNIT; - asiz = (asiz - 1) + unit - (asiz - 1) % unit; - TCMAPREC *old = rec; - TCREALLOC(rec, rec, asiz); - if(rec != old){ - if(map->first == old) map->first = rec; - if(map->last == old) map->last = rec; - if(map->cur == old) map->cur = rec; - if(*entp == old) *entp = rec; - if(rec->prev) rec->prev->next = rec; - if(rec->next) rec->next->prev = rec; - dbuf = (char *)rec + sizeof(*rec); - } - memcpy(dbuf + ksiz + psiz + rec->vsiz, vbuf, vsiz); - dbuf[ksiz+psiz+rec->vsiz+vsiz] = '\0'; - rec->vsiz += vsiz; - return; - } - } - } - int psiz = TCALIGNPAD(ksiz); - int asiz = sizeof(*rec) + ksiz + psiz + vsiz + 1; - int unit = (asiz <= TCMAPCSUNIT) ? TCMAPCSUNIT : TCMAPCBUNIT; - asiz = (asiz - 1) + unit - (asiz - 1) % unit; - map->msiz += ksiz + vsiz; - TCMALLOC(rec, asiz); - char *dbuf = (char *)rec + sizeof(*rec); - memcpy(dbuf, kbuf, ksiz); - dbuf[ksiz] = '\0'; - rec->ksiz = ksiz; - memcpy(dbuf + ksiz + psiz, vbuf, vsiz); - dbuf[ksiz+psiz+vsiz] = '\0'; - rec->vsiz = vsiz; - rec->hash = hash; - rec->left = NULL; - rec->right = NULL; - rec->prev = map->last; - rec->next = NULL; - *entp = rec; - if(!map->first) map->first = rec; - if(map->last) map->last->next = rec; - map->last = rec; - map->rnum++; -} - - -/* Concatenate a string value at the end of the value of the existing record in a map object. */ -void tcmapputcat2(TCMAP *map, const char *kstr, const char *vstr){ - assert(map && kstr && vstr); - tcmapputcat(map, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Remove a record of a map object. */ -bool tcmapout(TCMAP *map, const void *kbuf, int ksiz){ - assert(map && kbuf && ksiz >= 0); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - int bidx = hash % map->bnum; - TCMAPREC *rec = map->buckets[bidx]; - TCMAPREC **entp = map->buckets + bidx; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - entp = &(rec->left); - rec = rec->left; - } else if(hash < rec->hash){ - entp = &(rec->right); - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - entp = &(rec->left); - rec = rec->left; - } else if(kcmp > 0){ - entp = &(rec->right); - rec = rec->right; - } else { - map->rnum--; - map->msiz -= rec->ksiz + rec->vsiz; - if(rec->prev) rec->prev->next = rec->next; - if(rec->next) rec->next->prev = rec->prev; - if(rec == map->first) map->first = rec->next; - if(rec == map->last) map->last = rec->prev; - if(rec == map->cur) map->cur = rec->next; - if(rec->left && !rec->right){ - *entp = rec->left; - } else if(!rec->left && rec->right){ - *entp = rec->right; - } else if(!rec->left && !rec->left){ - *entp = NULL; - } else { - *entp = rec->left; - TCMAPREC *tmp = *entp; - while(tmp->right){ - tmp = tmp->right; - } - tmp->right = rec->right; - } - free(rec); - return true; - } - } - } - return false; -} - - -/* Remove a string record of a map object. */ -bool tcmapout2(TCMAP *map, const char *kstr){ - assert(map && kstr); - return tcmapout(map, kstr, strlen(kstr)); -} - - -/* Retrieve a record in a map object. */ -const void *tcmapget(const TCMAP *map, const void *kbuf, int ksiz, int *sp){ - assert(map && kbuf && ksiz >= 0 && sp); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - TCMAPREC *rec = map->buckets[hash%map->bnum]; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - rec = rec->left; - } else if(hash < rec->hash){ - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - rec = rec->left; - } else if(kcmp > 0){ - rec = rec->right; - } else { - *sp = rec->vsiz; - return dbuf + rec->ksiz + TCALIGNPAD(rec->ksiz); - } - } - } - return NULL; -} - - -/* Retrieve a string record in a map object. */ -const char *tcmapget2(const TCMAP *map, const char *kstr){ - assert(map && kstr); - int ksiz = strlen(kstr); - unsigned int hash; - TCMAPHASH1(hash, kstr, ksiz); - TCMAPREC *rec = map->buckets[hash%map->bnum]; - TCMAPHASH2(hash, kstr, ksiz); - while(rec){ - if(hash > rec->hash){ - rec = rec->left; - } else if(hash < rec->hash){ - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kstr, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - rec = rec->left; - } else if(kcmp > 0){ - rec = rec->right; - } else { - return dbuf + rec->ksiz + TCALIGNPAD(rec->ksiz); - } - } - } - return NULL; -} - - -/* Retrieve a semivolatile record in a map object. */ -const void *tcmapget3(TCMAP *map, const void *kbuf, int ksiz, int *sp){ - assert(map && kbuf && ksiz >= 0 && sp); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - TCMAPREC *rec = map->buckets[hash%map->bnum]; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - rec = rec->left; - } else if(hash < rec->hash){ - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - rec = rec->left; - } else if(kcmp > 0){ - rec = rec->right; - } else { - if(map->last != rec){ - if(map->first == rec) map->first = rec->next; - if(rec->prev) rec->prev->next = rec->next; - if(rec->next) rec->next->prev = rec->prev; - rec->prev = map->last; - rec->next = NULL; - map->last->next = rec; - map->last = rec; - } - *sp = rec->vsiz; - return dbuf + rec->ksiz + TCALIGNPAD(rec->ksiz); - } - } - } - return NULL; -} - - -/* Move a record to the edge of a map object. */ -bool tcmapmove(TCMAP *map, const void *kbuf, int ksiz, bool head){ - assert(map && kbuf && ksiz >= 0); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - TCMAPREC *rec = map->buckets[hash%map->bnum]; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - rec = rec->left; - } else if(hash < rec->hash){ - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - rec = rec->left; - } else if(kcmp > 0){ - rec = rec->right; - } else { - if(head){ - if(map->first == rec) return true; - if(map->last == rec) map->last = rec->prev; - if(rec->prev) rec->prev->next = rec->next; - if(rec->next) rec->next->prev = rec->prev; - rec->prev = NULL; - rec->next = map->first; - map->first->prev = rec; - map->first = rec; - } else { - if(map->last == rec) return true; - if(map->first == rec) map->first = rec->next; - if(rec->prev) rec->prev->next = rec->next; - if(rec->next) rec->next->prev = rec->prev; - rec->prev = map->last; - rec->next = NULL; - map->last->next = rec; - map->last = rec; - } - return true; - } - } - } - return false; -} - - -/* Move a string record to the edge of a map object. */ -bool tcmapmove2(TCMAP *map, const char *kstr, bool head){ - assert(map && kstr); - return tcmapmove(map, kstr, strlen(kstr), head); -} - - -/* Initialize the iterator of a map object. */ -void tcmapiterinit(TCMAP *map){ - assert(map); - map->cur = map->first; -} - - -/* Get the next key of the iterator of a map object. */ -const void *tcmapiternext(TCMAP *map, int *sp){ - assert(map && sp); - TCMAPREC *rec; - if(!map->cur) return NULL; - rec = map->cur; - map->cur = rec->next; - *sp = rec->ksiz; - return (char *)rec + sizeof(*rec); -} - - -/* Get the next key string of the iterator of a map object. */ -const char *tcmapiternext2(TCMAP *map){ - assert(map); - TCMAPREC *rec; - if(!map->cur) return NULL; - rec = map->cur; - map->cur = rec->next; - return (char *)rec + sizeof(*rec); -} - - -/* Get the value bound to the key fetched from the iterator of a map object. */ -const void *tcmapiterval(const void *kbuf, int *sp){ - assert(kbuf && sp); - TCMAPREC *rec = (TCMAPREC *)((char *)kbuf - sizeof(*rec)); - *sp = rec->vsiz; - return (char *)kbuf + rec->ksiz + TCALIGNPAD(rec->ksiz); -} - - -/* Get the value string bound to the key fetched from the iterator of a map object. */ -const char *tcmapiterval2(const char *kstr){ - assert(kstr); - TCMAPREC *rec = (TCMAPREC *)(kstr - sizeof(*rec)); - return kstr + rec->ksiz + TCALIGNPAD(rec->ksiz); -} - - -/* Get the number of records stored in a map object. */ -uint64_t tcmaprnum(const TCMAP *map){ - assert(map); - return map->rnum; -} - - -/* Get the total size of memory used in a map object. */ -uint64_t tcmapmsiz(const TCMAP *map){ - assert(map); - return map->msiz + map->rnum * (sizeof(*map->first) + sizeof(void *)) + - map->bnum * sizeof(void *); -} - - -/* Create a list object containing all keys in a map object. */ -TCLIST *tcmapkeys(const TCMAP *map){ - assert(map); - TCLIST *list = tclistnew2(map->rnum); - TCMAPREC *cur = map->cur; - const char *kbuf; - int ksiz; - ((TCMAP *)map)->cur = map->first; - while((kbuf = tcmapiternext((TCMAP *)map, &ksiz)) != NULL){ - TCLISTPUSH(list, kbuf, ksiz); - } - ((TCMAP *)map)->cur = cur; - return list; -} - - -/* Create a list object containing all values in a map object. */ -TCLIST *tcmapvals(const TCMAP *map){ - assert(map); - TCLIST *list = tclistnew2(map->rnum); - TCMAPREC *cur = map->cur; - const char *kbuf; - int ksiz; - ((TCMAP *)map)->cur = map->first; - while((kbuf = tcmapiternext((TCMAP *)map, &ksiz)) != NULL){ - int vsiz; - const char *vbuf = tcmapiterval(kbuf, &vsiz); - TCLISTPUSH(list, vbuf, vsiz); - } - ((TCMAP *)map)->cur = cur; - return list; -} - - -/* Add an integer to a record in a map object. */ -void tcmapaddint(TCMAP *map, const char *kbuf, int ksiz, int num){ - assert(map && kbuf && ksiz >= 0); - unsigned int hash; - TCMAPHASH1(hash, kbuf, ksiz); - int bidx = hash % map->bnum; - TCMAPREC *rec = map->buckets[bidx]; - TCMAPREC **entp = map->buckets + bidx; - TCMAPHASH2(hash, kbuf, ksiz); - while(rec){ - if(hash > rec->hash){ - entp = &(rec->left); - rec = rec->left; - } else if(hash < rec->hash){ - entp = &(rec->right); - rec = rec->right; - } else { - char *dbuf = (char *)rec + sizeof(*rec); - int kcmp = TCKEYCMP(kbuf, ksiz, dbuf, rec->ksiz); - if(kcmp < 0){ - entp = &(rec->left); - rec = rec->left; - } else if(kcmp > 0){ - entp = &(rec->right); - rec = rec->right; - } else { - int psiz = TCALIGNPAD(ksiz); - *(int *)(dbuf + ksiz + psiz) += num; - return; - } - } - } - int psiz = TCALIGNPAD(ksiz); - TCMALLOC(rec, sizeof(*rec) + ksiz + psiz + sizeof(num) + 1); - char *dbuf = (char *)rec + sizeof(*rec); - memcpy(dbuf, kbuf, ksiz); - dbuf[ksiz] = '\0'; - rec->ksiz = ksiz; - memcpy(dbuf + ksiz + psiz, &num, sizeof(num)); - dbuf[ksiz+psiz+sizeof(num)] = '\0'; - rec->vsiz = sizeof(num); - rec->hash = hash; - rec->left = NULL; - rec->right = NULL; - rec->prev = map->last; - rec->next = NULL; - *entp = rec; - if(!map->first) map->first = rec; - if(map->last) map->last->next = rec; - map->last = rec; - map->rnum++; -} - - -/* Clear a map object. */ -void tcmapclear(TCMAP *map){ - assert(map); - TCMAPREC *rec = map->first; - while(rec){ - TCMAPREC *next = rec->next; - free(rec); - rec = next; - } - TCMAPREC **buckets = map->buckets; - int bnum = map->bnum; - for(int i = 0; i < bnum; i++){ - buckets[i] = NULL; - } - map->first = NULL; - map->last = NULL; - map->cur = NULL; - map->rnum = 0; - map->msiz = 0; -} - - -/* Remove front records of a map object. */ -void tcmapcutfront(TCMAP *map, int num){ - assert(map && num >= 0); - tcmapiterinit(map); - while(num-- > 0){ - int ksiz; - const char *kbuf = tcmapiternext(map, &ksiz); - if(!kbuf) break; - tcmapout(map, kbuf, ksiz); - } -} - - -/* Serialize a map object into a byte array. */ -void *tcmapdump(const TCMAP *map, int *sp){ - assert(map && sp); - TCMAPREC *cur = map->cur; - int tsiz = 0; - const char *kbuf, *vbuf; - int ksiz, vsiz; - ((TCMAP *)map)->cur = map->first; - while((kbuf = tcmapiternext((TCMAP *)map, &ksiz)) != NULL){ - vbuf = tcmapiterval(kbuf, &vsiz); - tsiz += ksiz + vsiz + sizeof(int) * 2; - } - char *buf; - TCMALLOC(buf, tsiz + 1); - char *wp = buf; - ((TCMAP *)map)->cur = map->first; - while((kbuf = tcmapiternext((TCMAP *)map, &ksiz)) != NULL){ - vbuf = tcmapiterval(kbuf, &vsiz); - int step; - TCSETVNUMBUF(step, wp, ksiz); - wp += step; - memcpy(wp, kbuf, ksiz); - wp += ksiz; - TCSETVNUMBUF(step, wp, vsiz); - wp += step; - memcpy(wp, vbuf, vsiz); - wp += vsiz; - } - ((TCMAP *)map)->cur = cur; - *sp = wp - buf; - return buf; -} - - -/* Create a map object from a serialized byte array. */ -TCMAP *tcmapload(const void *ptr, int size){ - assert(ptr && size >= 0); - TCMAP *map = tcmapnew(); - const char *rp = ptr; - const char *ep = (char *)ptr + size; - while(rp < ep){ - int step, ksiz, vsiz; - TCREADVNUMBUF(rp, ksiz, step); - rp += step; - const char *kbuf = rp; - rp += ksiz; - TCREADVNUMBUF(rp, vsiz, step); - rp += step; - tcmapputkeep(map, kbuf, ksiz, rp, vsiz); - rp += vsiz; - } - return map; -} - - -/* Extract a map record from a serialized byte array. */ -void *tcmaploadone(const void *ptr, int size, const void *kbuf, int ksiz, int *sp){ - assert(ptr && size >= 0 && kbuf && ksiz >= 0 && sp); - const char *rp = ptr; - const char *ep = (char *)ptr + size; - while(rp < ep){ - int step, rsiz; - TCREADVNUMBUF(rp, rsiz, step); - rp += step; - if(rsiz == ksiz && !memcmp(kbuf, rp, rsiz)){ - rp += rsiz; - TCREADVNUMBUF(rp, rsiz, step); - rp += step; - *sp = rsiz; - char *rv; - TCMEMDUP(rv, rp, rsiz); - return rv; - } - rp += rsiz; - TCREADVNUMBUF(rp, rsiz, step); - rp += step; - rp += rsiz; - } - return NULL; -} - - - -/************************************************************************************************* - * on-memory database - *************************************************************************************************/ - - -#define TCMDBMNUM 8 // number of internal maps -#define TCMDBBNUM 65536 // allocation unit number of a map - -/* get the first hash value */ -#define TCMDBHASH(TC_res, TC_kbuf, TC_ksiz) \ - do { \ - const unsigned char *_TC_p = (const unsigned char *)(TC_kbuf) + TC_ksiz - 1; \ - int _TC_ksiz = TC_ksiz; \ - for((TC_res) = 0x20071123; _TC_ksiz--;){ \ - (TC_res) = ((TC_res) << 5) + (TC_res) + *(_TC_p)--; \ - } \ - (TC_res) &= TCMDBMNUM - 1; \ - } while(false) - - -/* Create an on-memory database object. */ -TCMDB *tcmdbnew(void){ - return tcmdbnew2(TCMDBBNUM); -} - - -/* Create an on-memory database with specifying the number of the buckets. */ -TCMDB *tcmdbnew2(uint32_t bnum){ - TCMDB *mdb; - if(bnum < 1) bnum = TCMDBBNUM; - bnum = bnum / TCMDBMNUM + 17; - TCMALLOC(mdb, sizeof(*mdb)); - TCMALLOC(mdb->mmtxs, sizeof(pthread_rwlock_t) * TCMDBMNUM); - TCMALLOC(mdb->imtx, sizeof(pthread_mutex_t)); - TCMALLOC(mdb->maps, sizeof(TCMAP *) * TCMDBMNUM); - if(pthread_mutex_init(mdb->imtx, NULL) != 0) tcmyfatal("mutex error"); - for(int i = 0; i < TCMDBMNUM; i++){ - if(pthread_rwlock_init((pthread_rwlock_t *)mdb->mmtxs + i, NULL) != 0) - tcmyfatal("rwlock error"); - mdb->maps[i] = tcmapnew2(bnum); - } - mdb->iter = -1; - return mdb; -} - - -/* Delete an on-memory database object. */ -void tcmdbdel(TCMDB *mdb){ - assert(mdb); - for(int i = TCMDBMNUM - 1; i >= 0; i--){ - tcmapdel(mdb->maps[i]); - pthread_rwlock_destroy((pthread_rwlock_t *)mdb->mmtxs + i); - } - pthread_mutex_destroy(mdb->imtx); - free(mdb->maps); - free(mdb->imtx); - free(mdb->mmtxs); - free(mdb); -} - - -/* Store a record into an on-memory database. */ -void tcmdbput(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(mdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - unsigned int mi; - TCMDBHASH(mi, kbuf, ksiz); - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return; - tcmapput(mdb->maps[mi], kbuf, ksiz, vbuf, vsiz); - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); -} - - -/* Store a string record into an on-memory database. */ -void tcmdbput2(TCMDB *mdb, const char *kstr, const char *vstr){ - assert(mdb && kstr && vstr); - tcmdbput(mdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Store a record of the value of two regions into an on-memory database object. */ -void tcmdbput3(TCMDB *mdb, const char *kbuf, int ksiz, - const void *fvbuf, int fvsiz, const char *lvbuf, int lvsiz){ - assert(mdb && kbuf && ksiz >= 0 && fvbuf && fvsiz >= 0 && lvbuf && lvsiz >= 0); - unsigned int mi; - TCMDBHASH(mi, kbuf, ksiz); - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return; - tcmapput3(mdb->maps[mi], kbuf, ksiz, fvbuf, fvsiz, lvbuf, lvsiz); - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); -} - - -/* Store a new record into an on-memory database. */ -bool tcmdbputkeep(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(mdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - unsigned int mi; - TCMDBHASH(mi, kbuf, ksiz); - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return false; - bool rv = tcmapputkeep(mdb->maps[mi], kbuf, ksiz, vbuf, vsiz); - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); - return rv; -} - - -/* Store a new string record into an on-memory database. */ -bool tcmdbputkeep2(TCMDB *mdb, const char *kstr, const char *vstr){ - assert(mdb && kstr && vstr); - return tcmdbputkeep(mdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Concatenate a value at the end of the value of the existing record in an on-memory database. */ -void tcmdbputcat(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz){ - assert(mdb && kbuf && ksiz >= 0 && vbuf && vsiz >= 0); - unsigned int mi; - TCMDBHASH(mi, kbuf, ksiz); - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return; - tcmapputcat(mdb->maps[mi], kbuf, ksiz, vbuf, vsiz); - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); -} - - -/* Concatenate a string at the end of the value of the existing record in an on-memory database. */ -void tcmdbputcat2(TCMDB *mdb, const char *kstr, const char *vstr){ - assert(mdb && kstr && vstr); - tcmdbputcat(mdb, kstr, strlen(kstr), vstr, strlen(vstr)); -} - - -/* Remove a record of an on-memory database. */ -bool tcmdbout(TCMDB *mdb, const void *kbuf, int ksiz){ - assert(mdb && kbuf && ksiz >= 0); - unsigned int mi; - TCMDBHASH(mi, kbuf, ksiz); - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return false; - bool rv = tcmapout(mdb->maps[mi], kbuf, ksiz); - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); - return rv; -} - - -/* Remove a string record of an on-memory database. */ -bool tcmdbout2(TCMDB *mdb, const char *kstr){ - assert(mdb && kstr); - return tcmdbout(mdb, kstr, strlen(kstr)); -} - - -/* Retrieve a record in an on-memory database. */ -void *tcmdbget(TCMDB *mdb, const void *kbuf, int ksiz, int *sp){ - assert(mdb && kbuf && ksiz >= 0 && sp); - unsigned int mi; - TCMDBHASH(mi, kbuf, ksiz); - if(pthread_rwlock_rdlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return NULL; - int vsiz; - const char *vbuf = tcmapget(mdb->maps[mi], kbuf, ksiz, &vsiz); - char *rv; - if(vbuf){ - TCMEMDUP(rv, vbuf, vsiz); - *sp = vsiz; - } else { - rv = NULL; - } - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); - return rv; -} - - -/* Retrieve a string record in an on-memory database. */ -char *tcmdbget2(TCMDB *mdb, const char *kstr){ - assert(mdb && kstr); - int vsiz; - return tcmdbget(mdb, kstr, strlen(kstr), &vsiz); -} - - -/* Retrieve a record and move it astern in an on-memory database. */ -void *tcmdbget3(TCMDB *mdb, const void *kbuf, int ksiz, int *sp){ - assert(mdb && kbuf && ksiz >= 0 && sp); - unsigned int mi; - TCMDBHASH(mi, kbuf, ksiz); - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return NULL; - int vsiz; - const char *vbuf = tcmapget3(mdb->maps[mi], kbuf, ksiz, &vsiz); - char *rv; - if(vbuf){ - TCMEMDUP(rv, vbuf, vsiz); - *sp = vsiz; - } else { - rv = NULL; - } - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); - return rv; -} - - -/* Get the size of the value of a record in an on-memory database object. */ -int tcmdbvsiz(TCMDB *mdb, const void *kbuf, int ksiz){ - assert(mdb && kbuf && ksiz >= 0); - unsigned int mi; - TCMDBHASH(mi, kbuf, ksiz); - if(pthread_rwlock_rdlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0) return -1; - int vsiz; - const char *vbuf = tcmapget(mdb->maps[mi], kbuf, ksiz, &vsiz); - if(!vbuf) vsiz = -1; - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); - return vsiz; -} - - -/* Get the size of the value of a string record in an on-memory database object. */ -int tcmdbvsiz2(TCMDB *mdb, const char *kstr){ - assert(mdb && kstr); - return tcmdbvsiz(mdb, kstr, strlen(kstr)); -} - - -/* Initialize the iterator of an on-memory database. */ -void tcmdbiterinit(TCMDB *mdb){ - assert(mdb); - if(pthread_mutex_lock(mdb->imtx) != 0) return; - for(int i = 0; i < TCMDBMNUM; i++){ - tcmapiterinit(mdb->maps[i]); - } - mdb->iter = 0; - pthread_mutex_unlock(mdb->imtx); -} - - -/* Get the next key of the iterator of an on-memory database. */ -void *tcmdbiternext(TCMDB *mdb, int *sp){ - assert(mdb && sp); - if(pthread_mutex_lock(mdb->imtx) != 0) return NULL; - if(mdb->iter < 0 || mdb->iter >= TCMDBMNUM){ - pthread_mutex_unlock(mdb->imtx); - return NULL; - } - int mi = mdb->iter; - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0){ - pthread_mutex_unlock(mdb->imtx); - return NULL; - } - int ksiz; - const char *kbuf; - while(!(kbuf = tcmapiternext(mdb->maps[mi], &ksiz)) && mi < TCMDBMNUM - 1){ - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); - mi = ++mdb->iter; - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + mi) != 0){ - pthread_mutex_unlock(mdb->imtx); - return NULL; - } - } - char *rv; - if(kbuf){ - TCMEMDUP(rv, kbuf, ksiz); - *sp = ksiz; - } else { - rv = NULL; - } - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + mi); - pthread_mutex_unlock(mdb->imtx); - return rv; -} - - -/* Get the next key string of the iterator of an on-memory database. */ -char *tcmdbiternext2(TCMDB *mdb){ - assert(mdb); - int ksiz; - return tcmdbiternext(mdb, &ksiz); -} - - -/* Get forward matching keys in an on-memory database object. */ -TCLIST *tcmdbfwmkeys(TCMDB *mdb, const void *pbuf, int psiz, int max){ - assert(mdb && pbuf && psiz >= 0); - TCLIST* keys = tclistnew(); - if(pthread_mutex_lock(mdb->imtx) != 0) return keys; - if(max < 0) max = INT_MAX; - for(int i = 0; i < TCMDBMNUM && TCLISTNUM(keys) < max; i++){ - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + i) == 0){ - TCMAP *map = mdb->maps[i]; - TCMAPREC *cur = map->cur; - tcmapiterinit(map); - int ksiz; - const char *kbuf; - while(TCLISTNUM(keys) < max && (kbuf = tcmapiternext(map, &ksiz)) != NULL){ - if(ksiz >= psiz && !memcmp(kbuf, pbuf, psiz)) tclistpush(keys, kbuf, ksiz); - } - map->cur = cur; - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + i); - } - } - pthread_mutex_unlock(mdb->imtx); - return keys; -} - - -/* Get forward matching string keys in an on-memory database object. */ -TCLIST *tcmdbfwmkeys2(TCMDB *mdb, const char *pstr, int max){ - assert(mdb && pstr); - return tcmdbfwmkeys(mdb, pstr, strlen(pstr), max); -} - - -/* Get the number of records stored in an on-memory database. */ -uint64_t tcmdbrnum(TCMDB *mdb){ - assert(mdb); - uint64_t rnum = 0; - for(int i = 0; i < TCMDBMNUM; i++){ - rnum += tcmaprnum(mdb->maps[i]); - } - return rnum; -} - - -/* Get the total size of memory used in an on-memory database object. */ -uint64_t tcmdbmsiz(TCMDB *mdb){ - assert(mdb); - uint64_t msiz = 0; - for(int i = 0; i < TCMDBMNUM; i++){ - msiz += tcmapmsiz(mdb->maps[i]); - } - return msiz; -} - - -/* Clear an on-memory database object. */ -void tcmdbvanish(TCMDB *mdb){ - assert(mdb); - for(int i = 0; i < TCMDBMNUM; i++){ - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + i) == 0){ - tcmapclear(mdb->maps[i]); - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + i); - } - } -} - - -/* Remove front records of a map object. */ -void tcmdbcutfront(TCMDB *mdb, int num){ - assert(mdb && num >= 0); - num = num / TCMDBMNUM + 1; - for(int i = 0; i < TCMDBMNUM; i++){ - if(pthread_rwlock_wrlock((pthread_rwlock_t *)mdb->mmtxs + i) == 0){ - tcmapcutfront(mdb->maps[i], num); - pthread_rwlock_unlock((pthread_rwlock_t *)mdb->mmtxs + i); - } - } -} - - - -/************************************************************************************************* - * memory pool - *************************************************************************************************/ - - -#define TCMPOOLUNIT 128 // allocation unit size of memory pool elements - - -/* Global memory pool object. */ -TCMPOOL *tcglobalmemorypool = NULL; - - -/* private function prototypes */ -static void tcmpooldelglobal(void); - - -/* Create a memory pool object. */ -TCMPOOL *tcmpoolnew(void){ - TCMPOOL *mpool; - TCMALLOC(mpool, sizeof(*mpool)); - TCMALLOC(mpool->mutex, sizeof(pthread_mutex_t)); - if(pthread_mutex_init(mpool->mutex, NULL) != 0) tcmyfatal("locking failed"); - mpool->anum = TCMPOOLUNIT; - TCMALLOC(mpool->elems, sizeof(mpool->elems[0]) * mpool->anum); - mpool->num = 0; - return mpool; -} - - -/* Delete a memory pool object. */ -void tcmpooldel(TCMPOOL *mpool){ - assert(mpool); - TCMPELEM *elems = mpool->elems; - for(int i = mpool->num - 1; i >= 0; i--){ - elems[i].del(elems[i].ptr); - } - free(elems); - pthread_mutex_destroy(mpool->mutex); - free(mpool->mutex); - free(mpool); -} - - -/* Relegate an arbitrary object to a memory pool object. */ -void tcmpoolput(TCMPOOL *mpool, void *ptr, void (*del)(void *)){ - assert(mpool && ptr && del); - if(pthread_mutex_lock(mpool->mutex) != 0) tcmyfatal("locking failed"); - int num = mpool->num; - if(num >= mpool->anum){ - mpool->anum *= 2; - TCREALLOC(mpool->elems, mpool->elems, mpool->anum * sizeof(mpool->elems[0])); - } - mpool->elems[num].ptr = ptr; - mpool->elems[num].del = del; - mpool->num++; - pthread_mutex_unlock(mpool->mutex); -} - - -/* Relegate an allocated region to a memory pool object. */ -void tcmpoolputptr(TCMPOOL *mpool, void *ptr){ - assert(mpool && ptr); - tcmpoolput(mpool, ptr, (void (*)(void *))free); -} - - -/* Relegate an extensible string object to a memory pool object. */ -void tcmpoolputxstr(TCMPOOL *mpool, TCXSTR *xstr){ - assert(mpool && xstr); - tcmpoolput(mpool, xstr, (void (*)(void *))tcxstrdel); -} - - -/* Relegate a list object to a memory pool object. */ -void tcmpoolputlist(TCMPOOL *mpool, TCLIST *list){ - assert(mpool && list); - tcmpoolput(mpool, list, (void (*)(void *))tclistdel); -} - - -/* Relegate a map object to a memory pool object. */ -void tcmpoolputmap(TCMPOOL *mpool, TCMAP *map){ - assert(mpool && map); - tcmpoolput(mpool, map, (void (*)(void *))tcmapdel); -} - - -/* Allocate a region relegated to a memory pool object. */ -void *tcmpoolmalloc(TCMPOOL *mpool, size_t size){ - assert(mpool && size > 0); - void *ptr; - TCMALLOC(ptr, size); - tcmpoolput(mpool, ptr, (void (*)(void *))free); - return ptr; -} - - -/* Create an extensible string object relegated to a memory pool object. */ -TCXSTR *tcmpoolxstrnew(TCMPOOL *mpool){ - assert(mpool); - TCXSTR *xstr = tcxstrnew(); - tcmpoolput(mpool, xstr, (void (*)(void *))tcxstrdel); - return xstr; -} - - -/* Create a list object relegated to a memory pool object. */ -TCLIST *tcmpoollistnew(TCMPOOL *mpool){ - assert(mpool); - TCLIST *list = tclistnew(); - tcmpoolput(mpool, list, (void (*)(void *))tclistdel); - return list; -} - - -/* Create a map object relegated to a memory pool object. */ -TCMAP *tcmpoolmapnew(TCMPOOL *mpool){ - assert(mpool); - TCMAP *map = tcmapnew(); - tcmpoolput(mpool, map, (void (*)(void *))tcmapdel); - return map; -} - - -/* Get the global memory pool object. */ -TCMPOOL *tcmpoolglobal(void){ - if(tcglobalmemorypool) return tcglobalmemorypool; - tcglobalmemorypool = tcmpoolnew(); - atexit(tcmpooldelglobal); - return tcglobalmemorypool; -} - - -/* Detete global memory pool object. */ -static void tcmpooldelglobal(void){ - if(tcglobalmemorypool) tcmpooldel(tcglobalmemorypool); -} - - - -/************************************************************************************************* - * miscellaneous utilities - *************************************************************************************************/ - - -#define TCRANDDEV "/dev/urandom" // path of the random device file -#define TCDISTBUFSIZ 16384 // size of an distance buffer - - -/* File descriptor of random number generator. */ -int tcrandomdevfd = -1; - - -/* private function prototypes */ -static void tcrandomfdclose(void); -static time_t tcmkgmtime(struct tm *tm); - - -/* Get the larger value of two integers. */ -long tclmax(long a, long b){ - return (a > b) ? a : b; -} - - -/* Get the lesser value of two integers. */ -long tclmin(long a, long b){ - return (a < b) ? a : b; -} - - -/* Get a random number as long integer based on uniform distribution. */ -unsigned long tclrand(void){ - static unsigned int cnt = 0; - static unsigned int seed = 0; - static unsigned long mask = 0; - static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - if((cnt & 0xff) == 0 && pthread_mutex_lock(&mutex) == 0){ - if(cnt++ == 0) seed = time(NULL); - if(tcrandomdevfd == -1 && (tcrandomdevfd = open(TCRANDDEV, O_RDONLY, 00644)) != -1) - atexit(tcrandomfdclose); - if(tcrandomdevfd != -1) read(tcrandomdevfd, &mask, sizeof(mask)); - pthread_mutex_unlock(&mutex); - } - return (mask ^ cnt++) ^ (unsigned long)rand_r(&seed); -} - - -/* Get a random number as double decimal based on uniform distribution. */ -double tcdrand(void){ - return tclrand() / (ULONG_MAX + 0.01); -} - - -/* Get a random number as double decimal based on normal distribution. */ -double tcdrandnd(double avg, double sd){ - assert(sd >= 0.0); - return sqrt(-2.0 * log(tcdrand())) * cos(2 * 3.141592653589793 * tcdrand()) * sd + avg; -} - - -/* Compare two strings with case insensitive evaluation. */ -int tcstricmp(const char *astr, const char *bstr){ - assert(astr && bstr); - while(*astr != '\0'){ - if(*bstr == '\0') return 1; - int ac = (*astr >= 'A' && *astr <= 'Z') ? *astr + ('a' - 'A') : *(unsigned char *)astr; - int bc = (*bstr >= 'A' && *bstr <= 'Z') ? *bstr + ('a' - 'A') : *(unsigned char *)bstr; - if(ac != bc) return ac - bc; - astr++; - bstr++; - } - return (*bstr == '\0') ? 0 : -1; -} - - -/* Check whether a string begins with a key. */ -bool tcstrfwm(const char *str, const char *key){ - assert(str && key); - while(*key != '\0'){ - if(*str != *key || *str == '\0') return false; - key++; - str++; - } - return true; -} - - -/* Check whether a string begins with a key with case insensitive evaluation. */ -bool tcstrifwm(const char *str, const char *key){ - assert(str && key); - while(*key != '\0'){ - if(*str == '\0') return false; - int sc = *str; - if(sc >= 'A' && sc <= 'Z') sc += 'a' - 'A'; - int kc = *key; - if(kc >= 'A' && kc <= 'Z') kc += 'a' - 'A'; - if(sc != kc) return false; - key++; - str++; - } - return true; -} - - -/* Check whether a string ends with a key. */ -bool tcstrbwm(const char *str, const char *key){ - assert(str && key); - int slen = strlen(str); - int klen = strlen(key); - for(int i = 1; i <= klen; i++){ - if(i > slen || str[slen-i] != key[klen-i]) return false; - } - return true; -} - - -/* Check whether a string ends with a key with case insensitive evaluation. */ -bool tcstribwm(const char *str, const char *key){ - assert(str && key); - int slen = strlen(str); - int klen = strlen(key); - for(int i = 1; i <= klen; i++){ - if(i > slen) return false; - int sc = str[slen-i]; - if(sc >= 'A' && sc <= 'Z') sc += 'a' - 'A'; - int kc = key[klen-i]; - if(kc >= 'A' && kc <= 'Z') kc += 'a' - 'A'; - if(sc != kc) return false; - } - return true; -} - - -/* Calculate the edit distance of two strings. */ -int tcstrdist(const char *astr, const char *bstr){ - assert(astr && bstr); - int alen = strlen(astr); - int blen = strlen(bstr); - int dsiz = blen + 1; - int tbuf[TCDISTBUFSIZ]; - int *tbl; - if((alen + 1) * dsiz < TCDISTBUFSIZ){ - tbl = tbuf; - } else { - TCMALLOC(tbl, (alen + 1) * dsiz * sizeof(*tbl)); - } - for(int i = 0; i <= alen; i++){ - tbl[i*dsiz] = i; - } - for(int i = 1; i <= blen; i++){ - tbl[i] = i; - } - astr--; - bstr--; - for(int i = 1; i <= alen; i++){ - for(int j = 1; j <= blen; j++){ - int ac = tbl[(i-1)*dsiz+j] + 1; - int bc = tbl[i*dsiz+j-1] + 1; - int cc = tbl[(i-1)*dsiz+j-1] + (astr[i] != bstr[j]); - ac = ac < bc ? ac : bc; - tbl[i*dsiz+j] = ac < cc ? ac : cc; - } - } - int rv = tbl[alen*dsiz+blen]; - if(tbl != tbuf) free(tbl); - return rv; -} - - -/* Calculate the edit distance of two UTF-8 strings. */ -int tcstrdistutf(const char *astr, const char *bstr){ - assert(astr && bstr); - int alen = strlen(astr); - uint16_t abuf[TCDISTBUFSIZ]; - uint16_t *aary; - if(alen < TCDISTBUFSIZ){ - aary = abuf; - } else { - TCMALLOC(aary, alen * sizeof(*aary)); - } - tcstrutftoucs(astr, aary, &alen); - int blen = strlen(bstr); - uint16_t bbuf[TCDISTBUFSIZ]; - uint16_t *bary; - if(blen < TCDISTBUFSIZ){ - bary = bbuf; - } else { - TCMALLOC(bary, blen * sizeof(*bary)); - } - tcstrutftoucs(bstr, bary, &blen); - int dsiz = blen + 1; - int tbuf[TCDISTBUFSIZ]; - int *tbl; - if((alen + 1) * dsiz < TCDISTBUFSIZ){ - tbl = tbuf; - } else { - TCMALLOC(tbl, (alen + 1) * dsiz * sizeof(*tbl)); - } - for(int i = 0; i <= alen; i++){ - tbl[i*dsiz] = i; - } - for(int i = 1; i <= blen; i++){ - tbl[i] = i; - } - aary--; - bary--; - for(int i = 1; i <= alen; i++){ - for(int j = 1; j <= blen; j++){ - int ac = tbl[(i-1)*dsiz+j] + 1; - int bc = tbl[i*dsiz+j-1] + 1; - int cc = tbl[(i-1)*dsiz+j-1] + (aary[i] != bary[j]); - ac = ac < bc ? ac : bc; - tbl[i*dsiz+j] = ac < cc ? ac : cc; - } - } - aary++; - bary++; - int rv = tbl[alen*dsiz+blen]; - if(tbl != tbuf) free(tbl); - if(bary != bbuf) free(bary); - if(aary != abuf) free(aary); - return rv; -} - - -/* Convert the letters of a string into upper case. */ -char *tcstrtoupper(char *str){ - assert(str); - char *wp = str; - while(*wp != '\0'){ - if(*wp >= 'a' && *wp <= 'z') *wp -= 'a' - 'A'; - wp++; - } - return str; -} - - -/* Convert the letters of a string into lower case. */ -char *tcstrtolower(char *str){ - assert(str); - char *wp = str; - while(*wp != '\0'){ - if(*wp >= 'A' && *wp <= 'Z') *wp += 'a' - 'A'; - wp++; - } - return str; -} - - -/* Cut space characters at head or tail of a string. */ -char *tcstrtrim(char *str){ - assert(str); - const char *rp = str; - char *wp = str; - bool head = true; - while(*rp != '\0'){ - if(*rp > '\0' && *rp <= ' '){ - if(!head) *(wp++) = *rp; - } else { - *(wp++) = *rp; - head = false; - } - rp++; - } - *wp = '\0'; - while(wp > str && wp[-1] > '\0' && wp[-1] <= ' '){ - *(--wp) = '\0'; - } - return str; -} - - -/* Squeeze space characters in a string and trim it. */ -char *tcstrsqzspc(char *str){ - assert(str); - char *rp = str; - char *wp = str; - bool spc = true; - while(*rp != '\0'){ - if(*rp > 0 && *rp <= ' '){ - if(!spc) *(wp++) = *rp; - spc = true; - } else { - *(wp++) = *rp; - spc = false; - } - rp++; - } - *wp = '\0'; - for(wp--; wp >= str; wp--){ - if(*wp > 0 && *wp <= ' '){ - *wp = '\0'; - } else { - break; - } - } - return str; -} - - -/* Substitute characters in a string. */ -char *tcstrsubchr(char *str, const char *rstr, const char *sstr){ - assert(str && rstr && sstr); - int slen = strlen(sstr); - char *wp = str; - for(int i = 0; str[i] != '\0'; i++){ - const char *p = strchr(rstr, str[i]); - if(p){ - int idx = p - rstr; - if(idx < slen) *(wp++) = sstr[idx]; - } else { - *(wp++) = str[i]; - } - } - *wp = '\0'; - return str; -} - - -/* Count the number of characters in a string of UTF-8. */ -int tcstrcntutf(const char *str){ - assert(str); - const unsigned char *rp = (unsigned char *)str; - int cnt = 0; - while(*rp != '\0'){ - if((*rp & 0x80) == 0x00 || (*rp & 0xe0) == 0xc0 || - (*rp & 0xf0) == 0xe0 || (*rp & 0xf8) == 0xf0) cnt++; - rp++; - } - return cnt; -} - - -/* Cut a string of UTF-8 at the specified number of characters. */ -char *tcstrcututf(char *str, int num){ - assert(str && num >= 0); - unsigned char *wp = (unsigned char *)str; - int cnt = 0; - while(*wp != '\0'){ - if((*wp & 0x80) == 0x00 || (*wp & 0xe0) == 0xc0 || - (*wp & 0xf0) == 0xe0 || (*wp & 0xf8) == 0xf0){ - cnt++; - if(cnt > num){ - *wp = '\0'; - break; - } - } - wp++; - } - return str; -} - - -/* Convert a UTF-8 string into a UCS-2 array. */ -void tcstrutftoucs(const char *str, uint16_t *ary, int *np){ - assert(str && ary && np); - const unsigned char *rp = (unsigned char *)str; - unsigned int wi = 0; - while(*rp != '\0'){ - int c = *(unsigned char *)rp; - if(c < 0x80){ - ary[wi++] = c; - } else if(c < 0xe0){ - if(rp[1] >= 0x80){ - ary[wi++] = ((rp[0] & 0x1f) << 6) | (rp[1] & 0x3f); - rp++; - } - } else if(c < 0xf0){ - if(rp[1] >= 0x80 && rp[2] >= 0x80){ - ary[wi++] = ((rp[0] & 0xf) << 12) | ((rp[1] & 0x3f) << 6) | (rp[2] & 0x3f); - rp += 2; - } - } - rp++; - } - *np = wi; -} - - -/* Convert a UCS-2 array into a UTF-8 string. */ -void tcstrucstoutf(const uint16_t *ary, int num, char *str){ - assert(ary && num >= 0 && str); - unsigned char *wp = (unsigned char *)str; - for(int i = 0; i < num; i++){ - unsigned int c = ary[i]; - if(c < 0x80){ - *(wp++) = c; - } else if(c < 0x800){ - *(wp++) = 0xc0 | (c >> 6); - *(wp++) = 0x80 | (c & 0x3f); - } else { - *(wp++) = 0xe0 | (c >> 12); - *(wp++) = 0x80 | ((c & 0xfff) >> 6); - *(wp++) = 0x80 | (c & 0x3f); - } - } - *wp = '\0'; -} - - -/* Create a list object by splitting a string. */ -TCLIST *tcstrsplit(const char *str, const char *delims){ - assert(str && delims); - TCLIST *list = tclistnew(); - while(true){ - const char *sp = str; - while(*str != '\0' && !strchr(delims, *str)){ - str++; - } - TCLISTPUSH(list, sp, str - sp); - if(*str == '\0') break; - str++; - } - return list; -} - - -/* Create a string by joining all elements of a list object. */ -char *tcstrjoin(TCLIST *list, char delim){ - assert(list); - int num = TCLISTNUM(list); - int size = num + 1; - for(int i = 0; i < num; i++){ - size += TCLISTVALNUM(list, i); - } - char *buf; - TCMALLOC(buf, size); - char *wp = buf; - for(int i = 0; i < num; i++){ - if(i > 0) *(wp++) = delim; - int vsiz; - const char *vbuf = tclistval(list, i, &vsiz); - memcpy(wp, vbuf, vsiz); - wp += vsiz; - } - *wp = '\0'; - return buf; -} - - -/* Check whether a string matches a regular expression. */ -bool tcregexmatch(const char *str, const char *regex){ - assert(str && regex); - int options = REG_EXTENDED | REG_NOSUB; - if(*regex == '*'){ - options |= REG_ICASE; - regex++; - } - regex_t rbuf; - if(regcomp(&rbuf, regex, options) != 0) return false; - bool rv = regexec(&rbuf, str, 0, NULL, 0) == 0; - regfree(&rbuf); - return rv; -} - - -/* Replace each substring matching a regular expression string. */ -char *tcregexreplace(const char *str, const char *regex, const char *alt){ - assert(str && regex && alt); - int options = REG_EXTENDED; - if(*regex == '*'){ - options |= REG_ICASE; - regex++; - } - regex_t rbuf; - if(regex[0] == '\0' || regcomp(&rbuf, regex, options) != 0) return tcstrdup(str); - regmatch_t subs[256]; - if(regexec(&rbuf, str, 32, subs, 0) != 0){ - regfree(&rbuf); - return tcstrdup(str); - } - const char *sp = str; - TCXSTR *xstr = tcxstrnew(); - bool first = true; - while(sp[0] != '\0' && regexec(&rbuf, sp, 10, subs, first ? 0 : REG_NOTBOL) == 0){ - first = false; - if(subs[0].rm_so == -1) break; - tcxstrcat(xstr, sp, subs[0].rm_so); - for(const char *rp = alt; *rp != '\0'; rp++){ - if(*rp == '\\'){ - if(rp[1] >= '0' && rp[1] <= '9'){ - int num = rp[1] - '0'; - if(subs[num].rm_so != -1 && subs[num].rm_eo != -1) - tcxstrcat(xstr, sp + subs[num].rm_so, subs[num].rm_eo - subs[num].rm_so); - ++rp; - } else if(rp[1] != '\0'){ - tcxstrcat(xstr, ++rp, 1); - } - } else if(*rp == '&'){ - tcxstrcat(xstr, sp + subs[0].rm_so, subs[0].rm_eo - subs[0].rm_so); - } else { - tcxstrcat(xstr, rp, 1); - } - } - sp += subs[0].rm_eo; - if(subs[0].rm_eo < 1) break; - } - tcxstrcat2(xstr, sp); - regfree(&rbuf); - return tcxstrtomalloc(xstr); -} - - -/* Get the time of day in seconds. */ -double tctime(void){ - struct timeval tv; - if(gettimeofday(&tv, NULL) == -1) return 0.0; - return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0; -} - - -/* Get the Gregorian calendar of a time. */ -void tccalendar(int64_t t, int jl, int *yearp, int *monp, int *dayp, - int *hourp, int *minp, int *secp){ - if(t == INT64_MAX || jl == INT_MAX){ - struct timeval tv; - struct timezone tz; - if(gettimeofday(&tv, &tz) == 0){ - if(t == INT64_MAX) t = tv.tv_sec; - if(jl == INT_MAX) jl = tz.tz_minuteswest * -60; - } else { - if(yearp) *yearp = 0; - if(monp) *monp = 0; - if(dayp) *dayp = 0; - if(hourp) *hourp = 0; - if(minp) *minp = 0; - if(secp) *secp = 0; - } - } - time_t tt = (time_t)t + jl; - struct tm ts; - if(!gmtime_r(&tt, &ts)){ - if(yearp) *yearp = 0; - if(monp) *monp = 0; - if(dayp) *dayp = 0; - if(hourp) *hourp = 0; - if(minp) *minp = 0; - if(secp) *secp = 0; - } - if(yearp) *yearp = ts.tm_year + 1900; - if(monp) *monp = ts.tm_mon + 1; - if(dayp) *dayp = ts.tm_mday; - if(hourp) *hourp = ts.tm_hour; - if(minp) *minp = ts.tm_min; - if(secp) *secp = ts.tm_sec; -} - - -/* Format a date as a string in W3CDTF. */ -void tcdatestrwww(int64_t t, int jl, char *buf){ - assert(buf); - if(t == INT64_MAX || jl == INT_MAX){ - struct timeval tv; - struct timezone tz; - if(gettimeofday(&tv, &tz) == 0){ - if(t == INT64_MAX) t = tv.tv_sec; - if(jl == INT_MAX) jl = tz.tz_minuteswest * -60; - } else { - if(t == INT64_MAX) t = time(NULL); - if(jl == INT_MAX) jl = 0; - } - } - time_t tt = (time_t)t + jl; - struct tm ts; - if(!gmtime_r(&tt, &ts)) memset(&ts, 0, sizeof(ts)); - ts.tm_year += 1900; - ts.tm_mon += 1; - jl /= 60; - char tzone[16]; - if(jl == 0){ - sprintf(tzone, "Z"); - } else if(jl < 0){ - jl *= -1; - sprintf(tzone, "-%02d:%02d", jl / 60, jl % 60); - } else { - sprintf(tzone, "+%02d:%02d", jl / 60, jl % 60); - } - sprintf(buf, "%04d-%02d-%02dT%02d:%02d:%02d%s", - ts.tm_year, ts.tm_mon, ts.tm_mday, ts.tm_hour, ts.tm_min, ts.tm_sec, tzone); -} - - -/* Format a date as a string in RFC 1123 format. */ -void tcdatestrhttp(int64_t t, int jl, char *buf){ - assert(buf); - if(t == INT64_MAX || jl == INT_MAX){ - struct timeval tv; - struct timezone tz; - if(gettimeofday(&tv, &tz) == 0){ - if(t == INT64_MAX) t = tv.tv_sec; - if(jl == INT_MAX) jl = tz.tz_minuteswest * -60; - } else { - if(t == INT64_MAX) t = time(NULL); - if(jl == INT_MAX) jl = 0; - } - } - time_t tt = (time_t)t + jl; - struct tm ts; - if(!gmtime_r(&tt, &ts)) memset(&ts, 0, sizeof(ts)); - ts.tm_year += 1900; - ts.tm_mon += 1; - jl /= 60; - char *wp = buf; - switch(tcdayofweek(ts.tm_year, ts.tm_mon, ts.tm_mday)){ - case 0: wp += sprintf(wp, "Sun, "); break; - case 1: wp += sprintf(wp, "Mon, "); break; - case 2: wp += sprintf(wp, "Tue, "); break; - case 3: wp += sprintf(wp, "Wed, "); break; - case 4: wp += sprintf(wp, "Thu, "); break; - case 5: wp += sprintf(wp, "Fri, "); break; - case 6: wp += sprintf(wp, "Sat, "); break; - } - wp += sprintf(wp, "%02d ", ts.tm_mday); - switch(ts.tm_mon){ - case 1: wp += sprintf(wp, "Jan "); break; - case 2: wp += sprintf(wp, "Feb "); break; - case 3: wp += sprintf(wp, "Mar "); break; - case 4: wp += sprintf(wp, "Apr "); break; - case 5: wp += sprintf(wp, "May "); break; - case 6: wp += sprintf(wp, "Jun "); break; - case 7: wp += sprintf(wp, "Jul "); break; - case 8: wp += sprintf(wp, "Aug "); break; - case 9: wp += sprintf(wp, "Sep "); break; - case 10: wp += sprintf(wp, "Oct "); break; - case 11: wp += sprintf(wp, "Nov "); break; - case 12: wp += sprintf(wp, "Dec "); break; - } - wp += sprintf(wp, "%04d %02d:%02d:%02d ", ts.tm_year, ts.tm_hour, ts.tm_min, ts.tm_sec); - if(jl == 0){ - sprintf(wp, "GMT"); - } else if(jl < 0){ - jl *= -1; - sprintf(wp, "-%02d%02d", jl / 60, jl % 60); - } else { - sprintf(wp, "+%02d%02d", jl / 60, jl % 60); - } -} - - -/* Get the time value of a date string. */ -int64_t tcstrmktime(const char *str){ - assert(str); - while(*str > '\0' && *str <= ' '){ - str++; - } - if(*str == '\0') return 0; - if(str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) - return (int64_t)strtoll(str + 2, NULL, 16); - struct tm ts; - memset(&ts, 0, sizeof(ts)); - ts.tm_year = 70; - ts.tm_mon = 0; - ts.tm_mday = 1; - ts.tm_hour = 0; - ts.tm_min = 0; - ts.tm_sec = 0; - ts.tm_isdst = 0; - int len = strlen(str); - char *pv; - time_t t = (time_t)strtoll(str, &pv, 10); - if(*(signed char *)pv >= '\0' && *pv <= ' '){ - while(*pv > '\0' && *pv <= ' '){ - pv++; - } - if(*pv == '\0') return (int64_t)t; - } - if((pv[0] == 's' || pv[0] == 'S') && ((signed char *)pv)[1] >= '\0' && pv[1] <= ' ') - return (int64_t)t; - if((pv[0] == 'm' || pv[0] == 'M') && ((signed char *)pv)[1] >= '\0' && pv[1] <= ' ') - return (int64_t)t * 60; - if((pv[0] == 'h' || pv[0] == 'H') && ((signed char *)pv)[1] >= '\0' && pv[1] <= ' ') - return (int64_t)t * 60 * 60; - if((pv[0] == 'd' || pv[0] == 'D') && ((signed char *)pv)[1] >= '\0' && pv[1] <= ' ') - return (int64_t)t * 60 * 60 * 24; - if(len > 4 && str[4] == '-'){ - ts.tm_year = atoi(str) - 1900; - if((pv = strchr(str, '-')) != NULL && pv - str == 4){ - char *rp = pv + 1; - ts.tm_mon = atoi(rp) - 1; - if((pv = strchr(rp, '-')) != NULL && pv - str == 7){ - rp = pv + 1; - ts.tm_mday = atoi(rp); - if((pv = strchr(rp, 'T')) != NULL && pv - str == 10){ - rp = pv + 1; - ts.tm_hour = atoi(rp); - if((pv = strchr(rp, ':')) != NULL && pv - str == 13){ - rp = pv + 1; - ts.tm_min = atoi(rp); - } - if((pv = strchr(rp, ':')) != NULL && pv - str == 16){ - rp = pv + 1; - ts.tm_sec = atoi(rp); - } - if((pv = strchr(rp, '.')) != NULL && pv - str >= 19) rp = pv + 1; - strtol(rp, &pv, 10); - if((*pv == '+' || *pv == '-') && strlen(pv) >= 6 && pv[3] == ':') - ts.tm_sec -= (atoi(pv + 1) * 3600 + atoi(pv + 4) * 60) * (pv[0] == '+' ? 1 : -1); - } - } - } - return (int64_t)tcmkgmtime(&ts); - } - if(len > 4 && str[4] == '/'){ - ts.tm_year = atoi(str) - 1900; - if((pv = strchr(str, '/')) != NULL && pv - str == 4){ - char *rp = pv + 1; - ts.tm_mon = atoi(rp) - 1; - if((pv = strchr(rp, '/')) != NULL && pv - str == 7){ - rp = pv + 1; - ts.tm_mday = atoi(rp); - if((pv = strchr(rp, ' ')) != NULL && pv - str == 10){ - rp = pv + 1; - ts.tm_hour = atoi(rp); - if((pv = strchr(rp, ':')) != NULL && pv - str == 13){ - rp = pv + 1; - ts.tm_min = atoi(rp); - } - if((pv = strchr(rp, ':')) != NULL && pv - str == 16){ - rp = pv + 1; - ts.tm_sec = atoi(rp); - } - if((pv = strchr(rp, '.')) != NULL && pv - str >= 19) rp = pv + 1; - strtol(rp, &pv, 10); - if((*pv == '+' || *pv == '-') && strlen(pv) >= 6 && pv[3] == ':') - ts.tm_sec -= (atoi(pv + 1) * 3600 + atoi(pv + 4) * 60) * (pv[0] == '+' ? 1 : -1); - } - } - } - return (int64_t)tcmkgmtime(&ts); - } - const char *crp = str; - if(len >= 4 && str[3] == ',') crp = str + 4; - while(*crp == ' '){ - crp++; - } - ts.tm_mday = atoi(crp); - while((*crp >= '0' && *crp <= '9') || *crp == ' '){ - crp++; - } - if(tcstrifwm(crp, "Jan")){ - ts.tm_mon = 0; - } else if(tcstrifwm(crp, "Feb")){ - ts.tm_mon = 1; - } else if(tcstrifwm(crp, "Mar")){ - ts.tm_mon = 2; - } else if(tcstrifwm(crp, "Apr")){ - ts.tm_mon = 3; - } else if(tcstrifwm(crp, "May")){ - ts.tm_mon = 4; - } else if(tcstrifwm(crp, "Jun")){ - ts.tm_mon = 5; - } else if(tcstrifwm(crp, "Jul")){ - ts.tm_mon = 6; - } else if(tcstrifwm(crp, "Aug")){ - ts.tm_mon = 7; - } else if(tcstrifwm(crp, "Sep")){ - ts.tm_mon = 8; - } else if(tcstrifwm(crp, "Oct")){ - ts.tm_mon = 9; - } else if(tcstrifwm(crp, "Nov")){ - ts.tm_mon = 10; - } else if(tcstrifwm(crp, "Dec")){ - ts.tm_mon = 11; - } else { - ts.tm_mon = -1; - } - if(ts.tm_mon >= 0) crp += 3; - while(*crp == ' '){ - crp++; - } - ts.tm_year = atoi(crp); - if(ts.tm_year >= 1969) ts.tm_year -= 1900; - while(*crp >= '0' && *crp <= '9'){ - crp++; - } - while(*crp == ' '){ - crp++; - } - if(ts.tm_mday > 0 && ts.tm_mon >= 0 && ts.tm_year >= 0){ - int clen = strlen(crp); - if(clen >= 8 && crp[2] == ':' && crp[5] == ':'){ - ts.tm_hour = atoi(crp + 0); - ts.tm_min = atoi(crp + 3); - ts.tm_sec = atoi(crp + 6); - if(clen >= 14 && crp[8] == ' ' && (crp[9] == '+' || crp[9] == '-')){ - ts.tm_sec -= ((crp[10] - '0') * 36000 + (crp[11] - '0') * 3600 + - (crp[12] - '0') * 600 + (crp[13] - '0') * 60) * (crp[9] == '+' ? 1 : -1); - } else if(clen > 9){ - if(!strcmp(crp + 9, "JST")){ - ts.tm_sec -= 9 * 3600; - } else if(!strcmp(crp + 9, "CCT")){ - ts.tm_sec -= 8 * 3600; - } else if(!strcmp(crp + 9, "KST")){ - ts.tm_sec -= 9 * 3600; - } else if(!strcmp(crp + 9, "EDT")){ - ts.tm_sec -= -4 * 3600; - } else if(!strcmp(crp + 9, "EST")){ - ts.tm_sec -= -5 * 3600; - } else if(!strcmp(crp + 9, "CDT")){ - ts.tm_sec -= -5 * 3600; - } else if(!strcmp(crp + 9, "CST")){ - ts.tm_sec -= -6 * 3600; - } else if(!strcmp(crp + 9, "MDT")){ - ts.tm_sec -= -6 * 3600; - } else if(!strcmp(crp + 9, "MST")){ - ts.tm_sec -= -7 * 3600; - } else if(!strcmp(crp + 9, "PDT")){ - ts.tm_sec -= -7 * 3600; - } else if(!strcmp(crp + 9, "PST")){ - ts.tm_sec -= -8 * 3600; - } else if(!strcmp(crp + 9, "HDT")){ - ts.tm_sec -= -9 * 3600; - } else if(!strcmp(crp + 9, "HST")){ - ts.tm_sec -= -10 * 3600; - } - } - } - return (int64_t)tcmkgmtime(&ts); - } - return 0; -} - - -/* Get the day of week of a date. */ -int tcdayofweek(int year, int mon, int day){ - if(mon < 3){ - year--; - mon += 12; - } - return (day + ((8 + (13 * mon)) / 5) + (year + (year / 4) - (year / 100) + (year / 400))) % 7; -} - - -/* Close the random number generator. */ -static void tcrandomfdclose(void){ - close(tcrandomdevfd); -} - - -/* Make the GMT from a time structure. - `tm' specifies the pointer to the time structure. - The return value is the GMT. */ -static time_t tcmkgmtime(struct tm *tm){ -#if defined(_SYS_LINUX_) - assert(tm); - return timegm(tm); -#else - assert(tm); - static int jl = INT_MAX; - if(jl == INT_MAX){ - struct timeval tv; - struct timezone tz; - if(gettimeofday(&tv, &tz) == 0){ - jl = tz.tz_minuteswest * -60; - } else { - jl = 0; - } - } - tm->tm_sec += jl; - return mktime(tm); -#endif -} - - - -/************************************************************************************************* - * filesystem utilities - *************************************************************************************************/ - - -#define TCFILEMODE 00644 // permission of a creating file -#define TCIOBUFSIZ 16384 // size of an I/O buffer - - -/* Get the canonicalized absolute path of a file. */ -char *tcrealpath(const char *path){ - assert(path); - char buf[PATH_MAX]; - if(!realpath(path, buf)) return NULL; - return tcstrdup(buf); -} - - -/* Read whole data of a file. */ -void *tcreadfile(const char *path, int limit, int *sp){ - int fd = path ? open(path, O_RDONLY, TCFILEMODE) : 0; - if(fd == -1) return NULL; - if(fd == 0){ - TCXSTR *xstr = tcxstrnew(); - char buf[TCIOBUFSIZ]; - limit = limit > 0 ? limit : INT_MAX; - int rsiz; - while((rsiz = read(fd, buf, tclmin(TCIOBUFSIZ, limit))) > 0){ - TCXSTRCAT(xstr, buf, rsiz); - limit -= rsiz; - } - if(sp) *sp = TCXSTRSIZE(xstr); - return tcxstrtomalloc(xstr); - } - struct stat sbuf; - if(fstat(fd, &sbuf) == -1 || !S_ISREG(sbuf.st_mode)){ - close(fd); - return NULL; - } - limit = limit > 0 ? tclmin((int)sbuf.st_size, limit) : sbuf.st_size; - char *buf; - TCMALLOC(buf, sbuf.st_size + 1); - char *wp = buf; - int rsiz; - while((rsiz = read(fd, wp, limit - (wp - buf))) > 0){ - wp += rsiz; - } - *wp = '\0'; - close(fd); - if(sp) *sp = wp - buf; - return buf; -} - - -/* Read every line of a file. */ -TCLIST *tcreadfilelines(const char *path){ - int fd = path ? open(path, O_RDONLY, TCFILEMODE) : 0; - if(fd == -1) return NULL; - TCLIST *list = tclistnew(); - TCXSTR *xstr = tcxstrnew(); - char buf[TCIOBUFSIZ]; - int rsiz; - while((rsiz = read(fd, buf, TCIOBUFSIZ)) > 0){ - for(int i = 0; i < rsiz; i++){ - switch(buf[i]){ - case '\r': - break; - case '\n': - TCLISTPUSH(list, TCXSTRPTR(xstr), TCXSTRSIZE(xstr)); - tcxstrclear(xstr); - break; - default: - TCXSTRCAT(xstr, buf + i, 1); - break; - } - } - } - TCLISTPUSH(list, TCXSTRPTR(xstr), TCXSTRSIZE(xstr)); - tcxstrdel(xstr); - if(path) close(fd); - return list; -} - - -/* Write data into a file. */ -bool tcwritefile(const char *path, const void *ptr, int size){ - assert(ptr && size >= 0); - int fd = 1; - if(path && (fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, TCFILEMODE)) == -1) return false; - bool err = false; - if(!tcwrite(fd, ptr, size)) err = true; - if(close(fd) == -1) err = true; - return !err; -} - - -/* Copy a file. */ -bool tccopyfile(const char *src, const char *dest){ - int ifd = open(src, O_RDONLY, TCFILEMODE); - if(ifd == -1) return false; - int ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, TCFILEMODE); - if(ofd == -1){ - close(ifd); - return false; - } - bool err = false; - while(true){ - char buf[TCIOBUFSIZ]; - int size = read(ifd, buf, TCIOBUFSIZ); - if(size > 0){ - if(!tcwrite(ofd, buf, size)){ - err = true; - break; - } - } else if(size == -1){ - if(errno != EINTR){ - err = true; - break; - } - } else { - break; - } - } - if(close(ofd) == -1) err = true; - if(close(ifd) == -1) err = true; - return !err; -} - - -/* Read names of files in a directory. */ -TCLIST *tcreaddir(const char *path){ - assert(path); - DIR *DD; - struct dirent *dp; - if(!(DD = opendir(path))) return NULL; - TCLIST *list = tclistnew(); - while((dp = readdir(DD)) != NULL){ - if(!strcmp(dp->d_name, MYCDIRSTR) || !strcmp(dp->d_name, MYPDIRSTR)) continue; - TCLISTPUSH(list, dp->d_name, strlen(dp->d_name)); - } - closedir(DD); - return list; -} - - -/* Expand a pattern into a list of matched paths. */ -TCLIST *tcglobpat(const char *pattern){ - assert(pattern); - TCLIST *list = tclistnew(); - glob_t gbuf; - memset(&gbuf, 0, sizeof(gbuf)); - if(glob(pattern, GLOB_ERR | GLOB_NOSORT, NULL, &gbuf) == 0){ - for(int i = 0; i < gbuf.gl_pathc; i++){ - tclistpush2(list, gbuf.gl_pathv[i]); - } - globfree(&gbuf); - } - return list; -} - - -/* Remove a file or a directory and its sub ones recursively. */ -bool tcremovelink(const char *path){ - assert(path); - struct stat sbuf; - if(lstat(path, &sbuf) == -1) return false; - if(unlink(path) == 0) return true; - TCLIST *list; - if(!S_ISDIR(sbuf.st_mode) || !(list = tcreaddir(path))) return false; - bool tail = path[0] != '\0' && path[strlen(path)-1] == MYPATHCHR; - for(int i = 0; i < TCLISTNUM(list); i++){ - const char *elem = TCLISTVALPTR(list, i); - if(!strcmp(MYCDIRSTR, elem) || !strcmp(MYPDIRSTR, elem)) continue; - char *cpath; - if(tail){ - cpath = tcsprintf("%s%s", path, elem); - } else { - cpath = tcsprintf("%s%c%s", path, MYPATHCHR, elem); - } - tcremovelink(cpath); - free(cpath); - } - tclistdel(list); - return rmdir(path) == 0 ? true : false; -} - - -/* Write data into a file. */ -bool tcwrite(int fd, const void *buf, size_t size){ - assert(fd >= 0 && buf && size >= 0); - const char *rp = buf; - do { - int wb = write(fd, rp, size); - switch(wb){ - case -1: if(errno != EINTR) return false; - case 0: break; - default: - rp += wb; - size -= wb; - break; - } - } while(size > 0); - return true; -} - - -/* Read data from a file. */ -bool tcread(int fd, void *buf, size_t size){ - assert(fd >= 0 && buf && size >= 0); - char *wp = buf; - do { - int rb = read(fd, wp, size); - switch(rb){ - case -1: if(errno != EINTR) return false; - case 0: return size < 1; - default: - wp += rb; - size -= rb; - } - } while(size > 0); - return true; -} - - -/* Lock a file. */ -bool tclock(int fd, bool ex, bool nb){ - assert(fd >= 0); - struct flock lock; - memset(&lock, 0, sizeof(struct flock)); - lock.l_type = ex ? F_WRLCK : F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; - lock.l_pid = 0; - while(fcntl(fd, nb ? F_SETLK : F_SETLKW, &lock) == -1){ - if(errno != EINTR) return false; - } - return true; -} - - - -/************************************************************************************************* - * encoding utilities - *************************************************************************************************/ - - -#define TCURLELBNUM 31 // bucket number of URL elements -#define TCENCBUFSIZ 32 // size of a buffer for encoding name -#define TCXMLATBNUM 31 // bucket number of XML attributes - - -/* Encode a serial object with URL encoding. */ -char *tcurlencode(const char *ptr, int size){ - assert(ptr && size >= 0); - char *buf; - TCMALLOC(buf, size * 3 + 1); - char *wp = buf; - for(int i = 0; i < size; i++){ - int c = ((unsigned char *)ptr)[i]; - if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') || (c != '\0' && strchr("_-.!~*'()", c))){ - *(wp++) = c; - } else { - wp += sprintf(wp, "%%%02X", c); - } - } - *wp = '\0'; - return buf; -} - - -/* Decode a string encoded with URL encoding. */ -char *tcurldecode(const char *str, int *sp){ - assert(str && sp); - char *buf = tcstrdup(str); - char *wp = buf; - while(*str != '\0'){ - if(*str == '%'){ - str++; - if(((str[0] >= '0' && str[0] <= '9') || (str[0] >= 'A' && str[0] <= 'F') || - (str[0] >= 'a' && str[0] <= 'f')) && - ((str[1] >= '0' && str[1] <= '9') || (str[1] >= 'A' && str[1] <= 'F') || - (str[1] >= 'a' && str[1] <= 'f'))){ - unsigned char c = *str; - if(c >= 'A' && c <= 'Z') c += 'a' - 'A'; - if(c >= 'a' && c <= 'z'){ - *wp = c - 'a' + 10; - } else { - *wp = c - '0'; - } - *wp *= 0x10; - str++; - c = *str; - if(c >= 'A' && c <= 'Z') c += 'a' - 'A'; - if(c >= 'a' && c <= 'z'){ - *wp += c - 'a' + 10; - } else { - *wp += c - '0'; - } - str++; - wp++; - } else { - break; - } - } else if(*str == '+'){ - *wp = ' '; - str++; - wp++; - } else { - *wp = *str; - str++; - wp++; - } - } - *wp = '\0'; - *sp = wp - buf; - return buf; -} - - -/* Break up a URL into elements. */ -TCMAP *tcurlbreak(const char *str){ - assert(str); - TCMAP *map = tcmapnew2(TCURLELBNUM); - char *tmp = tcstrdup(str); - const char *rp = tcstrtrim(tmp); - tcmapput2(map, "self", rp); - bool serv = false; - if(tcstrifwm(rp, "http://")){ - tcmapput2(map, "scheme", "http"); - rp += 7; - serv = true; - } else if(tcstrifwm(rp, "https://")){ - tcmapput2(map, "scheme", "https"); - rp += 8; - serv = true; - } else if(tcstrifwm(rp, "ftp://")){ - tcmapput2(map, "scheme", "ftp"); - rp += 6; - serv = true; - } else if(tcstrifwm(rp, "sftp://")){ - tcmapput2(map, "scheme", "sftp"); - rp += 7; - serv = true; - } else if(tcstrifwm(rp, "ftps://")){ - tcmapput2(map, "scheme", "ftps"); - rp += 7; - serv = true; - } else if(tcstrifwm(rp, "tftp://")){ - tcmapput2(map, "scheme", "tftp"); - rp += 7; - serv = true; - } else if(tcstrifwm(rp, "ldap://")){ - tcmapput2(map, "scheme", "ldap"); - rp += 7; - serv = true; - } else if(tcstrifwm(rp, "ldaps://")){ - tcmapput2(map, "scheme", "ldaps"); - rp += 8; - serv = true; - } else if(tcstrifwm(rp, "file://")){ - tcmapput2(map, "scheme", "file"); - rp += 7; - serv = true; - } - char *ep; - if((ep = strchr(rp, '#')) != NULL){ - tcmapput2(map, "fragment", ep + 1); - *ep = '\0'; - } - if((ep = strchr(rp, '?')) != NULL){ - tcmapput2(map, "query", ep + 1); - *ep = '\0'; - } - if(serv){ - if((ep = strchr(rp, '/')) != NULL){ - tcmapput2(map, "path", ep); - *ep = '\0'; - } else { - tcmapput2(map, "path", "/"); - } - if((ep = strchr(rp, '@')) != NULL){ - *ep = '\0'; - if(rp[0] != '\0') tcmapput2(map, "authority", rp); - rp = ep + 1; - } - if((ep = strchr(rp, ':')) != NULL){ - if(ep[1] != '\0') tcmapput2(map, "port", ep + 1); - *ep = '\0'; - } - if(rp[0] != '\0') tcmapput2(map, "host", rp); - } else { - tcmapput2(map, "path", rp); - } - free(tmp); - if((rp = tcmapget2(map, "path")) != NULL){ - if((ep = strrchr(rp, '/')) != NULL){ - if(ep[1] != '\0') tcmapput2(map, "file", ep + 1); - } else { - tcmapput2(map, "file", rp); - } - } - if((rp = tcmapget2(map, "file")) != NULL && (!strcmp(rp, ".") || !strcmp(rp, ".."))) - tcmapout2(map, "file"); - return map; -} - - -/* Resolve a relative URL with an absolute URL. */ -char *tcurlresolve(const char *base, const char *target){ - assert(base && target); - const char *vbuf, *path; - char *tmp, *wp, *enc; - while(*base > '\0' && *base <= ' '){ - base++; - } - while(*target > '\0' && *target <= ' '){ - target++; - } - if(*target == '\0') target = base; - TCXSTR *rbuf = tcxstrnew(); - TCMAP *telems = tcurlbreak(target); - int port = 80; - TCMAP *belems = tcurlbreak(tcmapget2(telems, "scheme") ? target : base); - if((vbuf = tcmapget2(belems, "scheme")) != NULL){ - tcxstrcat2(rbuf, vbuf); - TCXSTRCAT(rbuf, "://", 3); - if(!tcstricmp(vbuf, "https")){ - port = 443; - } else if(!tcstricmp(vbuf, "ftp")){ - port = 21; - } else if(!tcstricmp(vbuf, "sftp")){ - port = 115; - } else if(!tcstricmp(vbuf, "ftps")){ - port = 22; - } else if(!tcstricmp(vbuf, "tftp")){ - port = 69; - } else if(!tcstricmp(vbuf, "ldap")){ - port = 389; - } else if(!tcstricmp(vbuf, "ldaps")){ - port = 636; - } - } else { - tcxstrcat2(rbuf, "http://"); - } - int vsiz; - if((vbuf = tcmapget2(belems, "authority")) != NULL){ - if((wp = strchr(vbuf, ':')) != NULL){ - *wp = '\0'; - tmp = tcurldecode(vbuf, &vsiz); - enc = tcurlencode(tmp, vsiz); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - TCXSTRCAT(rbuf, ":", 1); - wp++; - tmp = tcurldecode(wp, &vsiz); - enc = tcurlencode(tmp, vsiz); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - } else { - tmp = tcurldecode(vbuf, &vsiz); - enc = tcurlencode(tmp, vsiz); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - } - TCXSTRCAT(rbuf, "@", 1); - } - if((vbuf = tcmapget2(belems, "host")) != NULL){ - tmp = tcurldecode(vbuf, &vsiz); - tcstrtolower(tmp); - enc = tcurlencode(tmp, vsiz); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - } else { - TCXSTRCAT(rbuf, "localhost", 9); - } - int num; - char numbuf[TCNUMBUFSIZ]; - if((vbuf = tcmapget2(belems, "port")) != NULL && (num = atoi(vbuf)) != port && num > 0){ - sprintf(numbuf, ":%d", num); - tcxstrcat2(rbuf, numbuf); - } - if(!(path = tcmapget2(telems, "path"))) path = "/"; - if(path[0] == '\0' && (vbuf = tcmapget2(belems, "path")) != NULL) path = vbuf; - if(path[0] == '\0') path = "/"; - TCLIST *bpaths = tclistnew(); - TCLIST *opaths; - if(path[0] != '/' && (vbuf = tcmapget2(belems, "path")) != NULL){ - opaths = tcstrsplit(vbuf, "/"); - } else { - opaths = tcstrsplit("/", "/"); - } - free(tclistpop2(opaths)); - for(int i = 0; i < TCLISTNUM(opaths); i++){ - vbuf = tclistval(opaths, i, &vsiz); - if(vsiz < 1 || !strcmp(vbuf, ".")) continue; - if(!strcmp(vbuf, "..")){ - free(tclistpop2(bpaths)); - } else { - TCLISTPUSH(bpaths, vbuf, vsiz); - } - } - tclistdel(opaths); - opaths = tcstrsplit(path, "/"); - for(int i = 0; i < TCLISTNUM(opaths); i++){ - vbuf = tclistval(opaths, i, &vsiz); - if(vsiz < 1 || !strcmp(vbuf, ".")) continue; - if(!strcmp(vbuf, "..")){ - free(tclistpop2(bpaths)); - } else { - TCLISTPUSH(bpaths, vbuf, vsiz); - } - } - tclistdel(opaths); - for(int i = 0; i < TCLISTNUM(bpaths); i++){ - vbuf = TCLISTVALPTR(bpaths, i); - if(strchr(vbuf, '%')){ - tmp = tcurldecode(vbuf, &vsiz); - } else { - tmp = tcstrdup(vbuf); - } - enc = tcurlencode(tmp, strlen(tmp)); - TCXSTRCAT(rbuf, "/", 1); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - } - if(tcstrbwm(path, "/")) TCXSTRCAT(rbuf, "/", 1); - tclistdel(bpaths); - if((vbuf = tcmapget2(telems, "query")) != NULL || - (*target == '#' && (vbuf = tcmapget2(belems, "query")) != NULL)){ - TCXSTRCAT(rbuf, "?", 1); - TCLIST *qelems = tcstrsplit(vbuf, "&;"); - for(int i = 0; i < TCLISTNUM(qelems); i++){ - vbuf = TCLISTVALPTR(qelems, i); - if(i > 0) TCXSTRCAT(rbuf, "&", 1); - if((wp = strchr(vbuf, '=')) != NULL){ - *wp = '\0'; - tmp = tcurldecode(vbuf, &vsiz); - enc = tcurlencode(tmp, vsiz); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - TCXSTRCAT(rbuf, "=", 1); - wp++; - tmp = tcurldecode(wp, &vsiz); - enc = tcurlencode(tmp, strlen(tmp)); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - } else { - tmp = tcurldecode(vbuf, &vsiz); - enc = tcurlencode(tmp, vsiz); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - } - } - tclistdel(qelems); - } - if((vbuf = tcmapget2(telems, "fragment")) != NULL){ - tmp = tcurldecode(vbuf, &vsiz); - enc = tcurlencode(tmp, vsiz); - TCXSTRCAT(rbuf, "#", 1); - tcxstrcat2(rbuf, enc); - free(enc); - free(tmp); - } - tcmapdel(belems); - tcmapdel(telems); - return tcxstrtomalloc(rbuf); -} - - -/* Encode a serial object with Base64 encoding. */ -char *tcbaseencode(const char *ptr, int size){ - assert(ptr && size >= 0); - char *tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - const unsigned char *obj = (const unsigned char *)ptr; - char *buf; - TCMALLOC(buf, 4 * (size + 2) / 3 + 1); - char *wp = buf; - for(int i = 0; i < size; i += 3){ - switch(size - i){ - case 1: - *wp++ = tbl[obj[0] >> 2]; - *wp++ = tbl[(obj[0] & 3) << 4]; - *wp++ = '='; - *wp++ = '='; - break; - case 2: - *wp++ = tbl[obj[0] >> 2]; - *wp++ = tbl[((obj[0] & 3) << 4) + (obj[1] >> 4)]; - *wp++ = tbl[(obj[1] & 0xf) << 2]; - *wp++ = '='; - break; - default: - *wp++ = tbl[obj[0] >> 2]; - *wp++ = tbl[((obj[0] & 3) << 4) + (obj[1] >> 4)]; - *wp++ = tbl[((obj[1] & 0xf) << 2) + (obj[2] >> 6)]; - *wp++ = tbl[obj[2] & 0x3f]; - break; - } - obj += 3; - } - *wp = '\0'; - return buf; -} - - -/* Decode a string encoded with Base64 encoding. */ -char *tcbasedecode(const char *str, int *sp){ - assert(str && sp); - int cnt = 0; - int bpos = 0; - int eqcnt = 0; - int len = strlen(str); - unsigned char *obj; - TCMALLOC(obj, len + 4); - unsigned char *wp = obj; - while(bpos < len && eqcnt == 0){ - int bits = 0; - int i; - for(i = 0; bpos < len && i < 4; bpos++){ - if(str[bpos] >= 'A' && str[bpos] <= 'Z'){ - bits = (bits << 6) | (str[bpos] - 'A'); - i++; - } else if(str[bpos] >= 'a' && str[bpos] <= 'z'){ - bits = (bits << 6) | (str[bpos] - 'a' + 26); - i++; - } else if(str[bpos] >= '0' && str[bpos] <= '9'){ - bits = (bits << 6) | (str[bpos] - '0' + 52); - i++; - } else if(str[bpos] == '+'){ - bits = (bits << 6) | 62; - i++; - } else if(str[bpos] == '/'){ - bits = (bits << 6) | 63; - i++; - } else if(str[bpos] == '='){ - bits <<= 6; - i++; - eqcnt++; - } - } - if(i == 0 && bpos >= len) continue; - switch(eqcnt){ - case 0: - *wp++ = (bits >> 16) & 0xff; - *wp++ = (bits >> 8) & 0xff; - *wp++ = bits & 0xff; - cnt += 3; - break; - case 1: - *wp++ = (bits >> 16) & 0xff; - *wp++ = (bits >> 8) & 0xff; - cnt += 2; - break; - case 2: - *wp++ = (bits >> 16) & 0xff; - cnt += 1; - break; - } - } - obj[cnt] = '\0'; - *sp = cnt; - return (char *)obj; -} - - -/* Encode a serial object with Quoted-printable encoding. */ -char *tcquoteencode(const char *ptr, int size){ - assert(ptr && size >= 0); - const unsigned char *rp = (const unsigned char *)ptr; - char *buf; - TCMALLOC(buf, size * 3 + 1); - char *wp = buf; - int cols = 0; - for(int i = 0; i < size; i++){ - if(rp[i] == '=' || (rp[i] < 0x20 && rp[i] != '\r' && rp[i] != '\n' && rp[i] != '\t') || - rp[i] > 0x7e){ - wp += sprintf(wp, "=%02X", rp[i]); - cols += 3; - } else { - *(wp++) = rp[i]; - cols++; - } - } - *wp = '\0'; - return buf; -} - - -/* Decode a string encoded with Quoted-printable encoding. */ -char *tcquotedecode(const char *str, int *sp){ - assert(str && sp); - char *buf; - TCMALLOC(buf, strlen(str) + 1); - char *wp = buf; - for(; *str != '\0'; str++){ - if(*str == '='){ - str++; - if(*str == '\0'){ - break; - } else if(str[0] == '\r' && str[1] == '\n'){ - str++; - } else if(str[0] != '\n' && str[0] != '\r'){ - if(*str >= 'A' && *str <= 'Z'){ - *wp = (*str - 'A' + 10) * 16; - } else if(*str >= 'a' && *str <= 'z'){ - *wp = (*str - 'a' + 10) * 16; - } else { - *wp = (*str - '0') * 16; - } - str++; - if(*str == '\0') break; - if(*str >= 'A' && *str <= 'Z'){ - *wp += *str - 'A' + 10; - } else if(*str >= 'a' && *str <= 'z'){ - *wp += *str - 'a' + 10; - } else { - *wp += *str - '0'; - } - wp++; - } - } else { - *wp = *str; - wp++; - } - } - *wp = '\0'; - *sp = wp - buf; - return buf; -} - - -/* Encode a string with MIME encoding. */ -char *tcmimeencode(const char *str, const char *encname, bool base){ - assert(str && encname); - int len = strlen(str); - char *buf; - TCMALLOC(buf, len * 3 + strlen(encname) + 16); - char *wp = buf; - wp += sprintf(wp, "=?%s?%c?", encname, base ? 'B' : 'Q'); - char *enc = base ? tcbaseencode(str, len) : tcquoteencode(str, len); - wp += sprintf(wp, "%s?=", enc); - free(enc); - return buf; -} - - -/* Decode a string encoded with MIME encoding. */ -char *tcmimedecode(const char *str, char *enp){ - assert(str); - if(enp) sprintf(enp, "US-ASCII"); - char *buf; - TCMALLOC(buf, strlen(str) + 1); - char *wp = buf; - while(*str != '\0'){ - if(tcstrfwm(str, "=?")){ - str += 2; - const char *pv = str; - const char *ep = strchr(str, '?'); - if(!ep) continue; - if(enp && ep - pv < TCENCBUFSIZ){ - memcpy(enp, pv, ep - pv); - enp[ep-pv] = '\0'; - } - pv = ep + 1; - bool quoted = (*pv == 'Q' || *pv == 'q'); - if(*pv != '\0') pv++; - if(*pv != '\0') pv++; - if(!(ep = strchr(pv, '?'))) continue; - char *tmp; - TCMEMDUP(tmp, pv, ep - pv); - int len; - char *dec = quoted ? tcquotedecode(tmp, &len) : tcbasedecode(tmp, &len); - wp += sprintf(wp, "%s", dec); - free(dec); - free(tmp); - str = ep + 1; - if(*str != '\0') str++; - } else { - *(wp++) = *str; - str++; - } - } - *wp = '\0'; - return buf; -} - - -/* Compress a serial object with Packbits encoding. */ -char *tcpackencode(const char *ptr, int size, int *sp){ - assert(ptr && size >= 0 && sp); - char *buf; - TCMALLOC(buf, size * 2 + 1); - char *wp = buf; - const char *end = ptr + size; - while(ptr < end){ - char *sp = wp; - const char *rp = ptr + 1; - int step = 1; - while(rp < end && step < 0x7f && *rp == *ptr){ - step++; - rp++; - } - if(step <= 1 && rp < end){ - wp = sp + 1; - *(wp++) = *ptr; - while(rp < end && step < 0x7f && *rp != *(rp - 1)){ - *(wp++) = *rp; - step++; - rp++; - } - if(rp < end && *(rp - 1) == *rp){ - wp--; - rp--; - step--; - } - *sp = step == 1 ? 1 : -step; - } else { - *(wp++) = step; - *(wp++) = *ptr; - } - ptr += step; - } - *sp = wp - buf; - return buf; -} - - -/* Decompress a serial object compressed with Packbits encoding. */ -char *tcpackdecode(const char *ptr, int size, int *sp){ - assert(ptr && size >= 0 && sp); - int asiz = size * 3; - char *buf; - TCMALLOC(buf, asiz + 1); - int wi = 0; - const char *end = ptr + size; - while(ptr < end){ - int step = abs(*ptr); - if(wi + step >= asiz){ - asiz = asiz * 2 + step; - TCREALLOC(buf, buf, asiz + 1); - } - if(*(ptr++) >= 0){ - memset(buf + wi, *ptr, step); - ptr++; - } else { - step = tclmin(step, end - ptr); - memcpy(buf + wi, ptr, step); - ptr += step; - } - wi += step; - } - buf[wi] = '\0'; - *sp = wi; - return buf; -} - - -/* Compress a serial object with Deflate encoding. */ -char *tcdeflate(const char *ptr, int size, int *sp){ - assert(ptr && sp); - if(!_tc_deflate) return NULL; - return _tc_deflate(ptr, size, sp, _TCZMZLIB); -} - - -/* Decompress a serial object compressed with Deflate encoding. */ -char *tcinflate(const char *ptr, int size, int *sp){ - assert(ptr && size >= 0); - if(!_tc_inflate) return NULL; - return _tc_inflate(ptr, size, sp, _TCZMZLIB); -} - - -/* Compress a serial object with GZIP encoding. */ -char *tcgzipencode(const char *ptr, int size, int *sp){ - assert(ptr && sp); - if(!_tc_deflate) return NULL; - return _tc_deflate(ptr, size, sp, _TCZMGZIP); -} - - -/* Decompress a serial object compressed with GZIP encoding. */ -char *tcgzipdecode(const char *ptr, int size, int *sp){ - assert(ptr && size >= 0); - if(!_tc_inflate) return NULL; - return _tc_inflate(ptr, size, sp, _TCZMGZIP); -} - - -/* Get the CRC32 checksum of a serial object. */ -unsigned int tcgetcrc(const char *ptr, int size){ - assert(ptr && size >= 0); - if(!_tc_getcrc) return 0; - return _tc_getcrc(ptr, size); -} - - -/* Encode an array of nonnegative integers with BER encoding. */ -char *tcberencode(const unsigned int *ary, int anum, int *sp){ - assert(ary && anum >= 0 && sp); - char *buf; - TCMALLOC(buf, anum * (sizeof(int) + 1) + 1); - char *wp = buf; - for(int i = 0; i < anum; i++){ - unsigned int num = ary[i]; - if(num < (1 << 7)){ - *(wp++) = num; - } else if(num < (1 << 14)){ - *(wp++) = (num >> 7) | 0x80; - *(wp++) = num & 0x7f; - } else if(num < (1 << 21)){ - *(wp++) = (num >> 14) | 0x80; - *(wp++) = ((num >> 7) & 0x7f) | 0x80; - *(wp++) = num & 0x7f; - } else if(num < (1 << 28)){ - *(wp++) = (num >> 21) | 0x80; - *(wp++) = ((num >> 14) & 0x7f) | 0x80; - *(wp++) = ((num >> 7) & 0x7f) | 0x80; - *(wp++) = num & 0x7f; - } else { - *(wp++) = (num >> 28) | 0x80; - *(wp++) = ((num >> 21) & 0x7f) | 0x80; - *(wp++) = ((num >> 14) & 0x7f) | 0x80; - *(wp++) = ((num >> 7) & 0x7f) | 0x80; - *(wp++) = num & 0x7f; - } - } - *sp = wp - buf; - return buf; -} - - -/* Decode a serial object encoded with BER encoding. */ -unsigned int *tcberdecode(const char *ptr, int size, int *np){ - assert(ptr && size >= 0 && np); - unsigned int *buf; - TCMALLOC(buf, size * sizeof(*buf) + 1); - unsigned int *wp = buf; - while(size > 0){ - unsigned int num = 0; - int c; - do { - c = *(unsigned char *)ptr; - num = num * 0x80 + (c & 0x7f); - ptr++; - size--; - } while(c >= 0x80 && size > 0); - *(wp++) = num; - } - *np = wp - buf; - return buf; -} - - -/* Escape meta characters in a string with the entity references of XML. */ -char *tcxmlescape(const char *str){ - assert(str); - const char *rp = str; - int bsiz = 0; - while(*rp != '\0'){ - switch(*rp){ - case '&': - bsiz += 5; - break; - case '<': - bsiz += 4; - break; - case '>': - bsiz += 4; - break; - case '"': - bsiz += 6; - break; - default: - bsiz++; - break; - } - rp++; - } - char *buf; - TCMALLOC(buf, bsiz + 1); - char *wp = buf; - while(*str != '\0'){ - switch(*str){ - case '&': - memcpy(wp, "&", 5); - wp += 5; - break; - case '<': - memcpy(wp, "<", 4); - wp += 4; - break; - case '>': - memcpy(wp, ">", 4); - wp += 4; - break; - case '"': - memcpy(wp, """, 6); - wp += 6; - break; - default: - *(wp++) = *str; - break; - } - str++; - } - *wp = '\0'; - return buf; -} - - -/* Unescape entity references in a string of XML. */ -char *tcxmlunescape(const char *str){ - assert(str); - char *buf; - TCMALLOC(buf, strlen(str) + 1); - char *wp = buf; - while(*str != '\0'){ - if(*str == '&'){ - if(tcstrfwm(str, "&")){ - *(wp++) = '&'; - str += 5; - } else if(tcstrfwm(str, "<")){ - *(wp++) = '<'; - str += 4; - } else if(tcstrfwm(str, ">")){ - *(wp++) = '>'; - str += 4; - } else if(tcstrfwm(str, """)){ - *(wp++) = '"'; - str += 6; - } else { - *(wp++) = *(str++); - } - } else { - *(wp++) = *(str++); - } - } - *wp = '\0'; - return buf; -} - - -/* Split an XML string into tags and text sections. */ -TCLIST *tcxmlbreak(const char *str){ - assert(str); - TCLIST *list = tclistnew(); - int i = 0; - int pv = 0; - bool tag = false; - char *ep; - while(true){ - if(str[i] == '\0'){ - if(i > pv) TCLISTPUSH(list, str + pv, i - pv); - break; - } else if(!tag && str[i] == '<'){ - if(str[i+1] == '!' && str[i+2] == '-' && str[i+3] == '-'){ - if(i > pv) TCLISTPUSH(list, str + pv, i - pv); - if((ep = strstr(str + i, "-->")) != NULL){ - TCLISTPUSH(list, str + i, ep - str - i + 3); - i = ep - str + 2; - pv = i + 1; - } - } else if(str[i+1] == '!' && str[i+2] == '[' && tcstrifwm(str + i, " pv) TCLISTPUSH(list, str + pv, i - pv); - if((ep = strstr(str + i, "]]>")) != NULL){ - i += 9; - TCXSTR *xstr = tcxstrnew(); - while(str + i < ep){ - if(str[i] == '&'){ - TCXSTRCAT(xstr, "&", 5); - } else if(str[i] == '<'){ - TCXSTRCAT(xstr, "<", 4); - } else if(str[i] == '>'){ - TCXSTRCAT(xstr, ">", 4); - } else { - TCXSTRCAT(xstr, str + i, 1); - } - i++; - } - if(TCXSTRSIZE(xstr) > 0) TCLISTPUSH(list, TCXSTRPTR(xstr), TCXSTRSIZE(xstr)); - tcxstrdel(xstr); - i = ep - str + 2; - pv = i + 1; - } - } else { - if(i > pv) TCLISTPUSH(list, str + pv, i - pv); - tag = true; - pv = i; - } - } else if(tag && str[i] == '>'){ - if(i > pv) TCLISTPUSH(list, str + pv, i - pv + 1); - tag = false; - pv = i + 1; - } - i++; - } - return list; -} - - -/* Get the map of attributes of an XML tag. */ -TCMAP *tcxmlattrs(const char *str){ - assert(str); - TCMAP *map = tcmapnew2(TCXMLATBNUM); - const unsigned char *rp = (unsigned char *)str; - while(*rp == '<' || *rp == '/' || *rp == '?' || *rp == '!' || *rp == ' '){ - rp++; - } - const unsigned char *key = rp; - while(*rp > 0x20 && *rp != '/' && *rp != '>'){ - rp++; - } - tcmapputkeep(map, "", 0, (char *)key, rp - key); - while(*rp != '\0'){ - while(*rp != '\0' && (*rp <= 0x20 || *rp == '/' || *rp == '?' || *rp == '>')){ - rp++; - } - key = rp; - while(*rp > 0x20 && *rp != '/' && *rp != '>' && *rp != '='){ - rp++; - } - int ksiz = rp - key; - while(*rp != '\0' && (*rp == '=' || *rp <= 0x20)){ - rp++; - } - const unsigned char *val; - int vsiz; - if(*rp == '"'){ - rp++; - val = rp; - while(*rp != '\0' && *rp != '"'){ - rp++; - } - vsiz = rp - val; - } else if(*rp == '\''){ - rp++; - val = rp; - while(*rp != '\0' && *rp != '\''){ - rp++; - } - vsiz = rp - val; - } else { - val = rp; - while(*rp > 0x20 && *rp != '"' && *rp != '\'' && *rp != '>'){ - rp++; - } - vsiz = rp - val; - } - if(*rp != '\0') rp++; - if(ksiz > 0){ - char *copy; - TCMEMDUP(copy, val, vsiz); - char *raw = tcxmlunescape(copy); - tcmapputkeep(map, (char *)key, ksiz, raw, strlen(raw)); - free(raw); - free(copy); - } - } - return map; -} - - - -/************************************************************************************************* - * features for experts - *************************************************************************************************/ - - -#define TCBSENCUNIT 8192 // unit size of TCBS encoding -#define TCBWTCNTMIN 64 // minimum element number of counting sort -#define TCBWTCNTLV 4 // maximum recursion level of counting sort -#define TCBWTBUFNUM 16384 // number of elements of BWT buffer - -typedef struct { // type of structure for a BWT character - int fchr; // character code of the first character - int tchr; // character code of the last character -} TCBWTREC; - - -/* private function prototypes */ -static void tcglobalmutexinit(void); -static void tcglobalmutexdestroy(void); -static void tcbwtsortstrcount(const char **arrays, int anum, int len, int level); -static void tcbwtsortstrinsert(const char **arrays, int anum, int len, int skip); -static void tcbwtsortstrheap(const char **arrays, int anum, int len, int skip); -static void tcbwtsortchrcount(unsigned char *str, int len); -static void tcbwtsortchrinsert(unsigned char *str, int len); -static void tcbwtsortreccount(TCBWTREC *arrays, int anum); -static void tcbwtsortrecinsert(TCBWTREC *array, int anum); -static int tcbwtsearchrec(TCBWTREC *array, int anum, int tchr); -static void tcmtfencode(char *ptr, int size); -static void tcmtfdecode(char *ptr, int size); -static int tcgammaencode(const char *ptr, int size, char *obuf); -static int tcgammadecode(const char *ptr, int size, char *obuf); - - -/* Show error message on the standard error output and exit. */ -void *tcmyfatal(const char *message){ - assert(message); - if(tcfatalfunc){ - tcfatalfunc(message); - } else { - fprintf(stderr, "fatal error: %s\n", message); - } - exit(1); - return NULL; -} - - -/* Global mutex object. */ -static pthread_rwlock_t tcglobalmutex; -static pthread_once_t tcglobalmutexonce = PTHREAD_ONCE_INIT; - - -/* Lock the global mutex object. */ -bool tcglobalmutexlock(void){ - pthread_once(&tcglobalmutexonce, tcglobalmutexinit); - return pthread_rwlock_wrlock(&tcglobalmutex) == 0; -} - - -/* Lock the global mutex object by shared locking. */ -bool tcglobalmutexlockshared(void){ - pthread_once(&tcglobalmutexonce, tcglobalmutexinit); - return pthread_rwlock_rdlock(&tcglobalmutex) == 0; -} - - -/* Unlock the global mutex object. */ -bool tcglobalmutexunlock(void){ - return pthread_rwlock_unlock(&tcglobalmutex) == 0; -} - - -/* Compress a serial object with TCBS encoding. */ -char *tcbsencode(const char *ptr, int size, int *sp){ - assert(ptr && size >= 0 && sp); - char *result; - TCMALLOC(result, (size * 7) / 3 + (size / TCBSENCUNIT + 1) * sizeof(uint16_t) + - TCBSENCUNIT * 2 + 0x200); - char *pv = result + size + 0x100; - char *wp = pv; - char *tp = pv + size + 0x100; - const char *end = ptr + size; - while(ptr < end){ - int usiz = tclmin(TCBSENCUNIT, end - ptr); - memcpy(tp, ptr, usiz); - memcpy(tp + usiz, ptr, usiz); - char *sp = wp; - uint16_t idx = 0; - wp += sizeof(idx); - const char *arrays[usiz+1]; - for(int i = 0; i < usiz; i++){ - arrays[i] = tp + i; - } - const char *fp = arrays[0]; - if(usiz >= TCBWTCNTMIN){ - tcbwtsortstrcount(arrays, usiz, usiz, 0); - } else if(usiz > 1){ - tcbwtsortstrinsert(arrays, usiz, usiz, 0); - } - for(int i = 0; i < usiz; i++){ - int tidx = arrays[i] - fp; - if(tidx == 0){ - idx = i; - *(wp++) = ptr[usiz-1]; - } else { - *(wp++) = ptr[tidx-1]; - } - } - idx = TCHTOIS(idx); - memcpy(sp, &idx, sizeof(idx)); - ptr += TCBSENCUNIT; - } - size = wp - pv; - tcmtfencode(pv, size); - int nsiz = tcgammaencode(pv, size, result); - *sp = nsiz; - return result; -} - - -/* Decompress a serial object compressed with TCBS encoding. */ -char *tcbsdecode(const char *ptr, int size, int *sp){ - char *result; - TCMALLOC(result, size * 9 + 0x200); - char *wp = result + size + 0x100; - int nsiz = tcgammadecode(ptr, size, wp); - tcmtfdecode(wp, nsiz); - ptr = wp; - wp = result; - const char *end = ptr + nsiz; - while(ptr < end){ - uint16_t idx; - memcpy(&idx, ptr, sizeof(idx)); - idx = TCITOHS(idx); - ptr += sizeof(idx); - int usiz = tclmin(TCBSENCUNIT, end - ptr); - if(idx >= usiz) idx = 0; - char rbuf[usiz+1]; - memcpy(rbuf, ptr, usiz); - if(usiz >= TCBWTCNTMIN){ - tcbwtsortchrcount((unsigned char *)rbuf, usiz); - } else if(usiz > 0){ - tcbwtsortchrinsert((unsigned char *)rbuf, usiz); - } - int fnums[0x100], tnums[0x100]; - memset(fnums, 0, sizeof(fnums)); - memset(tnums, 0, sizeof(tnums)); - TCBWTREC array[usiz+1]; - TCBWTREC *rp = array; - for(int i = 0; i < usiz; i++){ - int fc = *(unsigned char *)(rbuf + i); - rp->fchr = (fc << 23) + fnums[fc]++; - int tc = *(unsigned char *)(ptr + i); - rp->tchr = (tc << 23) + tnums[tc]++; - rp++; - } - unsigned int fchr = array[idx].fchr; - if(usiz >= TCBWTCNTMIN){ - tcbwtsortreccount(array, usiz); - } else if(usiz > 1){ - tcbwtsortrecinsert(array, usiz); - } - for(int i = 0; i < usiz; i++){ - if(array[i].fchr == fchr){ - idx = i; - break; - } - } - for(int i = 0; i < usiz; i++){ - *(wp++) = array[idx].fchr >> 23; - idx = tcbwtsearchrec(array, usiz, array[idx].fchr); - } - ptr += usiz; - } - *wp = '\0'; - *sp = wp - result; - return result; -} - - -/* Encode a serial object with BWT encoding. */ -char *tcbwtencode(const char *ptr, int size, int *idxp){ - assert(ptr && size >= 0 && idxp); - if(size < 1){ - *idxp = 0; - char *rv; - TCMEMDUP(rv, "", 0); - return rv; - } - char *result; - TCMALLOC(result, size * 3 + 1); - char *tp = result + size + 1; - memcpy(tp, ptr, size); - memcpy(tp + size, ptr, size); - const char *abuf[TCBWTBUFNUM]; - const char **arrays = abuf; - if(size > TCBWTBUFNUM) TCMALLOC(arrays, sizeof(*arrays) * size); - for(int i = 0; i < size; i++){ - arrays[i] = tp + i; - } - const char *fp = arrays[0]; - if(size >= TCBWTCNTMIN){ - tcbwtsortstrcount(arrays, size, size, -1); - } else if(size > 1){ - tcbwtsortstrinsert(arrays, size, size, 0); - } - for(int i = 0; i < size; i++){ - int idx = arrays[i] - fp; - if(idx == 0){ - *idxp = i; - result[i] = ptr[size-1]; - } else { - result[i] = ptr[idx-1]; - } - } - if(arrays != abuf) free(arrays); - result[size] = '\0'; - return result; -} - - -/* Decode a serial object encoded with BWT encoding. */ -char *tcbwtdecode(const char *ptr, int size, int idx){ - assert(ptr && size >= 0); - if(size < 1 || idx < 0){ - char *rv; - TCMEMDUP(rv, "", 0); - return rv; - } - if(idx >= size) idx = 0; - char *result; - TCMALLOC(result, size + 1); - memcpy(result, ptr, size); - if(size >= TCBWTCNTMIN){ - tcbwtsortchrcount((unsigned char *)result, size); - } else { - tcbwtsortchrinsert((unsigned char *)result, size); - } - int fnums[0x100], tnums[0x100]; - memset(fnums, 0, sizeof(fnums)); - memset(tnums, 0, sizeof(tnums)); - TCBWTREC abuf[TCBWTBUFNUM]; - TCBWTREC *array = abuf; - if(size > TCBWTBUFNUM) TCMALLOC(array, sizeof(*array) * size); - TCBWTREC *rp = array; - for(int i = 0; i < size; i++){ - int fc = *(unsigned char *)(result + i); - rp->fchr = (fc << 23) + fnums[fc]++; - int tc = *(unsigned char *)(ptr + i); - rp->tchr = (tc << 23) + tnums[tc]++; - rp++; - } - unsigned int fchr = array[idx].fchr; - if(size >= TCBWTCNTMIN){ - tcbwtsortreccount(array, size); - } else if(size > 1){ - tcbwtsortrecinsert(array, size); - } - for(int i = 0; i < size; i++){ - if(array[i].fchr == fchr){ - idx = i; - break; - } - } - char *wp = result; - for(int i = 0; i < size; i++){ - *(wp++) = array[idx].fchr >> 23; - idx = tcbwtsearchrec(array, size, array[idx].fchr); - } - *wp = '\0'; - if(array != abuf) free(array); - return result; -} - - -/* Initialize the global mutex object */ -static void tcglobalmutexinit(void){ - if(!TCUSEPTHREAD) memset(&tcglobalmutex, 0, sizeof(tcglobalmutex)); - if(pthread_rwlock_init(&tcglobalmutex, NULL) != 0) tcmyfatal("rwlock error"); - atexit(tcglobalmutexdestroy); -} - - -/* Destroy the global mutex object */ -static void tcglobalmutexdestroy(void){ - pthread_rwlock_destroy(&tcglobalmutex); -} - - -/* Sort BWT string arrays by dicrionary order by counting sort. - `array' specifies an array of string arrays. - `anum' specifies the number of the array. - `len' specifies the size of each string. - `level' specifies the level of recursion. */ -static void tcbwtsortstrcount(const char **arrays, int anum, int len, int level){ - assert(arrays && anum >= 0 && len >= 0); - const char *nbuf[TCBWTBUFNUM]; - const char **narrays = nbuf; - if(anum > TCBWTBUFNUM) TCMALLOC(narrays, sizeof(*narrays) * anum); - int count[0x100], accum[0x100]; - memset(count, 0, sizeof(count)); - int skip = level < 0 ? 0 : level; - for(int i = 0; i < anum; i++){ - count[((unsigned char *)arrays[i])[skip]]++; - } - memcpy(accum, count, sizeof(count)); - for(int i = 1; i < 0x100; i++){ - accum[i] = accum[i-1] + accum[i]; - } - for(int i = 0; i < anum; i++){ - narrays[--accum[((unsigned char *)arrays[i])[skip]]] = arrays[i]; - } - int off = 0; - if(level >= 0 && level < TCBWTCNTLV){ - for(int i = 0; i < 0x100; i++){ - int c = count[i]; - if(c > 1){ - if(c >= TCBWTCNTMIN){ - tcbwtsortstrcount(narrays + off, c, len, level + 1); - } else { - tcbwtsortstrinsert(narrays + off, c, len, skip + 1); - } - } - off += c; - } - } else { - for(int i = 0; i < 0x100; i++){ - int c = count[i]; - if(c > 1){ - if(c >= TCBWTCNTMIN){ - tcbwtsortstrheap(narrays + off, c, len, skip + 1); - } else { - tcbwtsortstrinsert(narrays + off, c, len, skip + 1); - } - } - off += c; - } - } - memcpy(arrays, narrays, anum * sizeof(*narrays)); - if(narrays != nbuf) free(narrays); -} - - -/* Sort BWT string arrays by dicrionary order by insertion sort. - `array' specifies an array of string arrays. - `anum' specifies the number of the array. - `len' specifies the size of each string. - `skip' specifies the number of skipped bytes. */ -static void tcbwtsortstrinsert(const char **arrays, int anum, int len, int skip){ - assert(arrays && anum >= 0 && len >= 0); - for(int i = 1; i < anum; i++){ - int cmp = 0; - const unsigned char *ap = (unsigned char *)arrays[i-1]; - const unsigned char *bp = (unsigned char *)arrays[i]; - for(int j = skip; j < len; j++){ - if(ap[j] != bp[j]){ - cmp = ap[j] - bp[j]; - break; - } - } - if(cmp > 0){ - const char *swap = arrays[i]; - int j; - for(j = i; j > 0; j--){ - int cmp = 0; - const unsigned char *ap = (unsigned char *)arrays[j-1]; - const unsigned char *bp = (unsigned char *)swap; - for(int k = skip; k < len; k++){ - if(ap[k] != bp[k]){ - cmp = ap[k] - bp[k]; - break; - } - } - if(cmp < 0) break; - arrays[j] = arrays[j-1]; - } - arrays[j] = swap; - } - } -} - - -/* Sort BWT string arrays by dicrionary order by heap sort. - `array' specifies an array of string arrays. - `anum' specifies the number of the array. - `len' specifies the size of each string. - `skip' specifies the number of skipped bytes. */ -static void tcbwtsortstrheap(const char **arrays, int anum, int len, int skip){ - assert(arrays && anum >= 0 && len >= 0); - anum--; - int bottom = (anum >> 1) + 1; - int top = anum; - while(bottom > 0){ - bottom--; - int mybot = bottom; - int i = mybot << 1; - while(i <= top){ - if(i < top){ - int cmp = 0; - const unsigned char *ap = (unsigned char *)arrays[i+1]; - const unsigned char *bp = (unsigned char *)arrays[i]; - for(int j = skip; j < len; j++){ - if(ap[j] != bp[j]){ - cmp = ap[j] - bp[j]; - break; - } - } - if(cmp > 0) i++; - } - int cmp = 0; - const unsigned char *ap = (unsigned char *)arrays[mybot]; - const unsigned char *bp = (unsigned char *)arrays[i]; - for(int j = skip; j < len; j++){ - if(ap[j] != bp[j]){ - cmp = ap[j] - bp[j]; - break; - } - } - if(cmp >= 0) break; - const char *swap = arrays[mybot]; - arrays[mybot] = arrays[i]; - arrays[i] = swap; - mybot = i; - i = mybot << 1; - } - } - while(top > 0){ - const char *swap = arrays[0]; - arrays[0] = arrays[top]; - arrays[top] = swap; - top--; - int mybot = bottom; - int i = mybot << 1; - while(i <= top){ - if(i < top){ - int cmp = 0; - const unsigned char *ap = (unsigned char *)arrays[i+1]; - const unsigned char *bp = (unsigned char *)arrays[i]; - for(int j = 0; j < len; j++){ - if(ap[j] != bp[j]){ - cmp = ap[j] - bp[j]; - break; - } - } - if(cmp > 0) i++; - } - int cmp = 0; - const unsigned char *ap = (unsigned char *)arrays[mybot]; - const unsigned char *bp = (unsigned char *)arrays[i]; - for(int j = 0; j < len; j++){ - if(ap[j] != bp[j]){ - cmp = ap[j] - bp[j]; - break; - } - } - if(cmp >= 0) break; - swap = arrays[mybot]; - arrays[mybot] = arrays[i]; - arrays[i] = swap; - mybot = i; - i = mybot << 1; - } - } -} - - -/* Sort BWT characters by code number by counting sort. - `str' specifies a string. - `len' specifies the length of the string. */ -static void tcbwtsortchrcount(unsigned char *str, int len){ - assert(str && len >= 0); - int cnt[0x100]; - memset(cnt, 0, sizeof(cnt)); - for(int i = 0; i < len; i++){ - cnt[str[i]]++; - } - int pos = 0; - for(int i = 0; i < 0x100; i++){ - memset(str + pos, i, cnt[i]); - pos += cnt[i]; - } -} - - -/* Sort BWT characters by code number by insertion sort. - `str' specifies a string. - `len' specifies the length of the string. */ -static void tcbwtsortchrinsert(unsigned char *str, int len){ - assert(str && len >= 0); - for(int i = 1; i < len; i++){ - if(str[i-1] - str[i] > 0){ - unsigned char swap = str[i]; - int j; - for(j = i; j > 0; j--){ - if(str[j-1] - swap < 0) break; - str[j] = str[j-1]; - } - str[j] = swap; - } - } -} - - -/* Sort BWT records by code number by counting sort. - `array' specifies an array of records. - `anum' specifies the number of the array. */ -static void tcbwtsortreccount(TCBWTREC *array, int anum){ - assert(array && anum >= 0); - TCBWTREC nbuf[TCBWTBUFNUM]; - TCBWTREC *narray = nbuf; - if(anum > TCBWTBUFNUM) TCMALLOC(narray, sizeof(*narray) * anum); - int count[0x100], accum[0x100]; - memset(count, 0, sizeof(count)); - for(int i = 0; i < anum; i++){ - count[array[i].tchr>>23]++; - } - memcpy(accum, count, sizeof(count)); - for(int i = 1; i < 0x100; i++){ - accum[i] = accum[i-1] + accum[i]; - } - for(int i = 0; i < 0x100; i++){ - accum[i] -= count[i]; - } - for(int i = 0; i < anum; i++){ - narray[accum[array[i].tchr>>23]++] = array[i]; - } - memcpy(array, narray, anum * sizeof(*narray)); - if(narray != nbuf) free(narray); -} - - -/* Sort BWT records by code number by insertion sort. - `array' specifies an array of records.. - `anum' specifies the number of the array. */ -static void tcbwtsortrecinsert(TCBWTREC *array, int anum){ - assert(array && anum >= 0); - for(int i = 1; i < anum; i++){ - if(array[i-1].tchr - array[i].tchr > 0){ - TCBWTREC swap = array[i]; - int j; - for(j = i; j > 0; j--){ - if(array[j-1].tchr - swap.tchr < 0) break; - array[j] = array[j-1]; - } - array[j] = swap; - } - } -} - - -/* Search the element of BWT records. - `array' specifies an array of records. - `anum' specifies the number of the array. - `tchr' specifies the last code number. */ -static int tcbwtsearchrec(TCBWTREC *array, int anum, int tchr){ - assert(array && anum >= 0); - int bottom = 0; - int top = anum; - int mid; - do { - mid = (bottom + top) >> 1; - if(array[mid].tchr == tchr){ - return mid; - } else if(array[mid].tchr < tchr){ - bottom = mid + 1; - if(bottom >= anum) break; - } else { - top = mid - 1; - } - } while(bottom <= top); - return -1; -} - - -/* Initialization table for MTF encoder. */ -const unsigned char tcmtftable[] = { - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, - 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, - 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, - 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, - 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, - 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, - 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, - 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, - 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f, - 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, - 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf, - 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, - 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, - 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, - 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef, - 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff -}; - - -/* Encode a region with MTF encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. */ -static void tcmtfencode(char *ptr, int size){ - unsigned char table1[0x100], table2[0x100], *table, *another; - assert(ptr && size >= 0); - memcpy(table1, tcmtftable, sizeof(tcmtftable)); - table = table1; - another = table2; - const char *end = ptr + size; - char *wp = ptr; - while(ptr < end){ - unsigned char c = *ptr; - unsigned char *tp = table; - unsigned char *tend = table + 0x100; - while(tp < tend && *tp != c){ - tp++; - } - int idx = tp - table; - *(wp++) = idx; - if(idx > 0){ - memcpy(another, &c, 1); - memcpy(another + 1, table, idx); - memcpy(another + 1 + idx, table + idx + 1, 255 - idx); - unsigned char *swap = table; - table = another; - another = swap; - } - ptr++; - } -} - - -/* Decode a region compressed with MTF encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. */ -static void tcmtfdecode(char *ptr, int size){ - assert(ptr && size >= 0); - unsigned char table1[0x100], table2[0x100], *table, *another; - assert(ptr && size >= 0); - memcpy(table1, tcmtftable, sizeof(tcmtftable)); - table = table1; - another = table2; - const char *end = ptr + size; - char *wp = ptr; - while(ptr < end){ - int idx = *(unsigned char *)ptr; - unsigned char c = table[idx]; - *(wp++) = c; - if(idx > 0){ - memcpy(another, &c, 1); - memcpy(another + 1, table, idx); - memcpy(another + 1 + idx, table + idx + 1, 255 - idx); - unsigned char *swap = table; - table = another; - another = swap; - } - ptr++; - } -} - - -/* Encode a region with Elias gamma encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `ptr' specifies the pointer to the output buffer. */ -static int tcgammaencode(const char *ptr, int size, char *obuf){ - assert(ptr && size >= 0 && obuf); - TCBITSTRM strm; - TCBITSTRMINITW(strm, obuf); - const char *end = ptr + size; - while(ptr < end){ - unsigned int c = *(unsigned char *)ptr; - if(!c){ - TCBITSTRMCAT(strm, 1); - } else { - c++; - int plen = 8; - while(plen > 0 && !(c & (1 << plen))){ - plen--; - } - int jlen = plen; - while(jlen-- > 0){ - TCBITSTRMCAT(strm, 0); - } - while(plen >= 0){ - int sign = (c & (1 << plen)) > 0; - TCBITSTRMCAT(strm, sign); - plen--; - } - } - ptr++; - } - TCBITSTRMSETEND(strm); - return TCBITSTRMSIZE(strm); -} - - -/* Decode a region compressed with Elias gamma encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `ptr' specifies the pointer to the output buffer. */ -static int tcgammadecode(const char *ptr, int size, char *obuf){ - assert(ptr && size >= 0 && obuf); - char *wp = obuf; - TCBITSTRM strm; - TCBITSTRMINITR(strm, ptr, size); - int bnum = TCBITSTRMNUM(strm); - while(bnum > 0){ - int sign; - TCBITSTRMREAD(strm, sign); - bnum--; - if(sign){ - *(wp++) = 0; - } else { - int plen = 1; - while(bnum > 0){ - TCBITSTRMREAD(strm, sign); - bnum--; - if(sign) break; - plen++; - } - unsigned int c = 1; - while(bnum > 0 && plen-- > 0){ - TCBITSTRMREAD(strm, sign); - bnum--; - c = (c << 1) + (sign > 0); - } - *(wp++) = c - 1; - } - } - return wp - obuf;; -} - - - -// END OF FILE diff --git a/bacula/src/lib/tokyocabinet/tcutil.h b/bacula/src/lib/tokyocabinet/tcutil.h deleted file mode 100644 index 05a1e1da00..0000000000 --- a/bacula/src/lib/tokyocabinet/tcutil.h +++ /dev/null @@ -1,2169 +0,0 @@ -/************************************************************************************************* - * The utility API of Tokyo Cabinet - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -#ifndef _TCUTIL_H /* duplication check */ -#define _TCUTIL_H - -#if defined(__cplusplus) -#define __TCUTIL_CLINKAGEBEGIN extern "C" { -#define __TCUTIL_CLINKAGEEND } -#else -#define __TCUTIL_CLINKAGEBEGIN -#define __TCUTIL_CLINKAGEEND -#endif -__TCUTIL_CLINKAGEBEGIN - - -#include -#include -#include -#include - - - -/************************************************************************************************* - * basic utilities - *************************************************************************************************/ - - -/* String containing the version information. */ -extern const char *tcversion; - - -/* Pointer to the call back function for handling a fatal error. - The argument specifies the error message. - The initial value of this variable is `NULL'. If the value is `NULL', the default function is - called when a fatal error occurs. A fatal error occurs when memory allocation is failed. */ -extern void (*tcfatalfunc)(const char *); - - -/* Allocate a region on memory. - `size' specifies the size of the region. - The return value is the pointer to the allocated region. - This function handles failure of memory allocation implicitly. Because the region of the - return value is allocated with the `malloc' call, it should be released with the `free' call - when it is no longer in use. */ -void *tcmalloc(size_t size); - - -/* Allocate a nullified region on memory. - `nmemb' specifies the number of elements. - `size' specifies the size of each element. - The return value is the pointer to the allocated nullified region. - This function handles failure of memory allocation implicitly. Because the region of the - return value is allocated with the `calloc' call, it should be released with the `free' call - when it is no longer in use. */ -void *tccalloc(size_t nmemb, size_t size); - - -/* Re-allocate a region on memory. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - The return value is the pointer to the re-allocated region. - This function handles failure of memory allocation implicitly. Because the region of the - return value is allocated with the `realloc' call, it should be released with the `free' call - when it is no longer in use. */ -void *tcrealloc(void *ptr, size_t size); - - -/* Duplicate a region on memory. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - The return value is the pointer to the allocated region of the duplicate. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -void *tcmemdup(const void *ptr, size_t size); - - -/* Duplicate a string on memory. - `str' specifies the string. - The return value is the allocated string equivalent to the specified string. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcstrdup(const void *str); - - -/* Free a region on memory. - `ptr' specifies the pointer to the region. If it is `NULL', this function has no effect. - Although this function is just a wrapper of `free' call, this is useful in applications using - another package of the `malloc' series. */ -void tcfree(void *ptr); - - - -/************************************************************************************************* - * extensible string - *************************************************************************************************/ - - -typedef struct { /* type of structure for an extensible string object */ - char *ptr; /* pointer to the region */ - int size; /* size of the region */ - int asize; /* size of the allocated region */ -} TCXSTR; - - -/* Create an extensible string object. - The return value is the new extensible string object. */ -TCXSTR *tcxstrnew(void); - - -/* Create an extensible string object from a character string. - `str' specifies the string of the initial content. - The return value is the new extensible string object containing the specified string. */ -TCXSTR *tcxstrnew2(const char *str); - - -/* Create an extensible string object with the initial allocation size. - `asiz' specifies the initial allocation size. - The return value is the new extensible string object. */ -TCXSTR *tcxstrnew3(int asiz); - - -/* Copy an extensible string object. - `xstr' specifies the extensible string object. - The return value is the new extensible string object equivalent to the specified object. */ -TCXSTR *tcxstrdup(const TCXSTR *xstr); - - -/* Delete an extensible string object. - `xstr' specifies the extensible string object. - Note that the deleted object and its derivatives can not be used anymore. */ -void tcxstrdel(TCXSTR *xstr); - - -/* Concatenate a region to the end of an extensible string object. - `xstr' specifies the extensible string object. - `ptr' specifies the pointer to the region to be appended. - `size' specifies the size of the region. */ -void tcxstrcat(TCXSTR *xstr, const void *ptr, int size); - - -/* Concatenate a character string to the end of an extensible string object. - `xstr' specifies the extensible string object. - `str' specifies the string to be appended. */ -void tcxstrcat2(TCXSTR *xstr, const char *str); - - -/* Get the pointer of the region of an extensible string object. - `xstr' specifies the extensible string object. - The return value is the pointer of the region of the object. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. */ -const void *tcxstrptr(const TCXSTR *xstr); - - -/* Get the size of the region of an extensible string object. - `xstr' specifies the extensible string object. - The return value is the size of the region of the object. */ -int tcxstrsize(const TCXSTR *xstr); - - -/* Clear an extensible string object. - `xstr' specifies the extensible string object. - The internal buffer of the object is cleared and the size is set zero. */ -void tcxstrclear(TCXSTR *xstr); - - -/* Convert an extensible string object into a usual allocated region. - `xstr' specifies the extensible string object. - The return value is the pointer to the allocated region of the object. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. Because the region of the original object is deleted, it should not be - deleted again. */ -void *tcxstrtomalloc(TCXSTR *xstr); - - -/* Create an extensible string object from an allocated region. - `ptr' specifies the pointer to the region allocated with `malloc' call. - `size' specifies the size of the region. - The return value is the new extensible string object wrapping the specified region. - Note that the specified region is released when the object is deleted. */ -TCXSTR *tcxstrfrommalloc(void *ptr, int size); - - -/* Perform formatted output into an extensible string object. - `xstr' specifies the extensible string object. - `format' specifies the printf-like format string. - The conversion character `%' can be used with such flag characters as `s', `d', `o', `u', - `x', `X', `c', `e', `E', `f', `g', `G', `@', `?', `%'. `@' works as with `s' but escapes meta - characters of XML. `?' works as with `s' but escapes meta characters of URL. The other - conversion character work as with each original. - The other arguments are used according to the format string. */ -void tcxstrprintf(TCXSTR *xstr, const char *format, ...); - - -/* Allocate a formatted string on memory. - `format' specifies the printf-like format string. - The conversion character `%' can be used with such flag characters as `s', `d', `o', `u', - `x', `X', `c', `e', `E', `f', `g', `G', `@', `?', `%'. `@' works as with `s' but escapes meta - characters of XML. `?' works as with `s' but escapes meta characters of URL. The other - conversion character work as with each original. - The other arguments are used according to the format string. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcsprintf(const char *format, ...); - - - -/************************************************************************************************* - * array list - *************************************************************************************************/ - - -typedef struct { /* type of structure for an element of a list */ - char *ptr; /* pointer to the region */ - int size; /* size of the effective region */ -} TCLISTDATUM; - -typedef struct { /* type of structure for an array list */ - TCLISTDATUM *array; /* array of data */ - int anum; /* number of the elements of the array */ - int start; /* start index of used elements */ - int num; /* number of used elements */ -} TCLIST; - - -/* Create a list object. - The return value is the new list object. */ -TCLIST *tclistnew(void); - - -/* Create a list object with expecting the number of elements. - `anum' specifies the number of elements expected to be stored in the list. - The return value is the new list object. */ -TCLIST *tclistnew2(int anum); - - -/* Copy a list object. - `list' specifies the list object. - The return value is the new list object equivalent to the specified object. */ -TCLIST *tclistdup(const TCLIST *list); - - -/* Delete a list object. - `list' specifies the list object. - Note that the deleted object and its derivatives can not be used anymore. */ -void tclistdel(TCLIST *list); - - -/* Get the number of elements of a list object. - `list' specifies the list object. - The return value is the number of elements of the list. */ -int tclistnum(const TCLIST *list); - - -/* Get the pointer to the region of an element of a list object. - `list' specifies the list object. - `index' specifies the index of the element. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the value. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. If `index' is equal to or more than - the number of elements, the return value is `NULL'. */ -const void *tclistval(const TCLIST *list, int index, int *sp); - - -/* Get the string of an element of a list object. - `list' specifies the list object. - `index' specifies the index of the element. - The return value is the string of the value. - If `index' is equal to or more than the number of elements, the return value is `NULL'. */ -const char *tclistval2(const TCLIST *list, int index); - - -/* Add an element at the end of a list object. - `list' specifies the list object. - `ptr' specifies the pointer to the region of the new element. - `size' specifies the size of the region. */ -void tclistpush(TCLIST *list, const void *ptr, int size); - - -/* Add a string element at the end of a list object. - `list' specifies the list object. - `str' specifies the string of the new element. */ -void tclistpush2(TCLIST *list, const char *str); - - -/* Add an allocated element at the end of a list object. - `list' specifies the list object. - `ptr' specifies the pointer to the region allocated with `malloc' call. - `size' specifies the size of the region. - Note that the specified region is released when the object is deleted. */ -void tclistpushmalloc(TCLIST *list, void *ptr, int size); - - -/* Remove an element of the end of a list object. - `list' specifies the list object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the removed element. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. If the list is empty, the return value is `NULL'. */ -void *tclistpop(TCLIST *list, int *sp); - - -/* Remove a string element of the end of a list object. - `list' specifies the list object. - The return value is the string of the removed element. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. If the list is empty, the return - value is `NULL'. */ -char *tclistpop2(TCLIST *list); - - -/* Add an element at the top of a list object. - `list' specifies the list object. - `ptr' specifies the pointer to the region of the new element. - `size' specifies the size of the region. */ -void tclistunshift(TCLIST *list, const void *ptr, int size); - - -/* Add a string element at the top of a list object. - `list' specifies the list object. - `str' specifies the string of the new element. */ -void tclistunshift2(TCLIST *list, const char *str); - - -/* Remove an element of the top of a list object. - `list' specifies the list object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the removed element. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. If the list is empty, the return value is `NULL'. */ -void *tclistshift(TCLIST *list, int *sp); - - -/* Remove a string element of the top of a list object. - `list' specifies the list object. - The return value is the string of the removed element. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. If the list is empty, the return - value is `NULL'. */ -char *tclistshift2(TCLIST *list); - - -/* Add an element at the specified location of a list object. - `list' specifies the list object. - `index' specifies the index of the new element. - `ptr' specifies the pointer to the region of the new element. - `size' specifies the size of the region. - If `index' is equal to or more than the number of elements, this function has no effect. */ -void tclistinsert(TCLIST *list, int index, const void *ptr, int size); - - -/* Add a string element at the specified location of a list object. - `list' specifies the list object. - `index' specifies the index of the new element. - `str' specifies the string of the new element. - If `index' is equal to or more than the number of elements, this function has no effect. */ -void tclistinsert2(TCLIST *list, int index, const char *str); - - -/* Remove an element at the specified location of a list object. - `list' specifies the list object. - `index' specifies the index of the element to be removed. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the removed element. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. If `index' is equal to or more than the number of elements, no element - is removed and the return value is `NULL'. */ -void *tclistremove(TCLIST *list, int index, int *sp); - - -/* Remove a string element at the specified location of a list object. - `list' specifies the list object. - `index' specifies the index of the element to be removed. - The return value is the string of the removed element. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. If `index' is equal to or more - than the number of elements, no element is removed and the return value is `NULL'. */ -char *tclistremove2(TCLIST *list, int index); - - -/* Overwrite an element at the specified location of a list object. - `list' specifies the list object. - `index' specifies the index of the element to be overwritten. - `ptr' specifies the pointer to the region of the new content. - `size' specifies the size of the new content. - If `index' is equal to or more than the number of elements, this function has no effect. */ -void tclistover(TCLIST *list, int index, const void *ptr, int size); - - -/* Overwrite a string element at the specified location of a list object. - `list' specifies the list object. - `index' specifies the index of the element to be overwritten. - `str' specifies the string of the new content. - If `index' is equal to or more than the number of elements, this function has no effect. */ -void tclistover2(TCLIST *list, int index, const char *str); - - -/* Sort elements of a list object in lexical order. - `list' specifies the list object. */ -void tclistsort(TCLIST *list); - - -/* Sort elements of a list object in case-insensitive lexical order. - `list' specifies the list object. */ -void tclistsortci(TCLIST *list); - - -/* Sort elements of a list object by an arbitrary comparison function. - `list' specifies the list object. - `cmp' specifies the pointer to the comparison function. The structure TCLISTDATUM has the - member "ptr" which is the pointer to the region of the element, and the member "size" which is - the size of the region. */ -void tclistsortex(TCLIST *list, int (*cmp)(const TCLISTDATUM *, const TCLISTDATUM *)); - - -/* Search a list object for an element using liner search. - `list' specifies the list object. - `ptr' specifies the pointer to the region of the key. - `size' specifies the size of the region. - The return value is the index of a corresponding element or -1 if there is no corresponding - element. - If two or more elements correspond, the former returns. */ -int tclistlsearch(const TCLIST *list, const void *ptr, int size); - - -/* Search a list object for an element using binary search. - `list' specifies the list object. It should be sorted in lexical order. - `ptr' specifies the pointer to the region of the key. - `size' specifies the size of the region. - The return value is the index of a corresponding element or -1 if there is no corresponding - element. - If two or more elements correspond, which returns is not defined. */ -int tclistbsearch(const TCLIST *list, const void *ptr, int size); - - -/* Clear a list object. - `list' specifies the list object. - All elements are removed. */ -void tclistclear(TCLIST *list); - - -/* Serialize a list object into a byte array. - `list' specifies the list object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the result serial region. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -void *tclistdump(const TCLIST *list, int *sp); - - -/* Create a list object from a serialized byte array. - `ptr' specifies the pointer to the region of serialized byte array. - `size' specifies the size of the region. - The return value is a new list object. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tclistload(const void *ptr, int size); - - - -/************************************************************************************************* - * hash map - *************************************************************************************************/ - - -typedef struct _TCMAPREC { /* type of structure for an element of a map */ - int ksiz; /* size of the region of the key */ - int vsiz; /* size of the region of the value */ - unsigned int hash; /* second hash value */ - struct _TCMAPREC *left; /* pointer to the left child */ - struct _TCMAPREC *right; /* pointer to the right child */ - struct _TCMAPREC *prev; /* pointer to the previous element */ - struct _TCMAPREC *next; /* pointer to the next element */ -} TCMAPREC; - -typedef struct { /* type of structure for a map */ - TCMAPREC **buckets; /* bucket array */ - TCMAPREC *first; /* pointer to the first element */ - TCMAPREC *last; /* pointer to the last element */ - TCMAPREC *cur; /* pointer to the current element */ - uint32_t bnum; /* number of buckets */ - uint64_t rnum; /* number of records */ - uint64_t msiz; /* total size of records */ -} TCMAP; - - -/* Create a map object. - The return value is the new map object. */ -TCMAP *tcmapnew(void); - - -/* Create a map object with specifying the number of the buckets. - `bnum' specifies the number of the buckets. - The return value is the new map object. */ -TCMAP *tcmapnew2(uint32_t bnum); - - -/* Copy a map object. - `map' specifies the map object. - The return value is the new map object equivalent to the specified object. */ -TCMAP *tcmapdup(const TCMAP *map); - - -/* Delete a map object. - `map' specifies the map object. - Note that the deleted object and its derivatives can not be used anymore. */ -void tcmapdel(TCMAP *map); - - -/* Store a record into a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If a record with the same key exists in the map, it is overwritten. */ -void tcmapput(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a string record into a map object. - `map' specifies the map object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If a record with the same key exists in the map, it is overwritten. */ -void tcmapput2(TCMAP *map, const char *kstr, const char *vstr); - - -/* Store a record of the value of two regions into a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `fvbuf' specifies the pointer to the former region of the value. - `fvsiz' specifies the size of the former region of the value. - `lvbuf' specifies the pointer to the latter region of the value. - `lvsiz' specifies the size of the latter region of the value. - If a record with the same key exists in the map, it is overwritten. */ -void tcmapput3(TCMAP *map, const char *kbuf, int ksiz, - const void *fvbuf, int fvsiz, const char *lvbuf, int lvsiz); - - -/* Store a new record into a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the map, this function has no effect. */ -bool tcmapputkeep(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a new string record into a map object. - `map' specifies the map object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the map, this function has no effect. */ -bool tcmapputkeep2(TCMAP *map, const char *kstr, const char *vstr); - - -/* Concatenate a value at the end of the value of the existing record in a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If there is no corresponding record, a new record is created. */ -void tcmapputcat(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Concatenate a string value at the end of the value of the existing record in a map object. - `map' specifies the map object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If there is no corresponding record, a new record is created. */ -void tcmapputcat2(TCMAP *map, const char *kstr, const char *vstr); - - -/* Remove a record of a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true. False is returned when no record corresponds to - the specified key. */ -bool tcmapout(TCMAP *map, const void *kbuf, int ksiz); - - -/* Remove a string record of a map object. - `map' specifies the map object. - `kstr' specifies the string of the key. - If successful, the return value is true. False is returned when no record corresponds to - the specified key. */ -bool tcmapout2(TCMAP *map, const char *kstr); - - -/* Retrieve a record in a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the - corresponding record. `NULL' is returned when no record corresponds. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. */ -const void *tcmapget(const TCMAP *map, const void *kbuf, int ksiz, int *sp); - - -/* Retrieve a string record in a map object. - `map' specifies the map object. - `kstr' specifies the string of the key. - If successful, the return value is the string of the value of the corresponding record. - `NULL' is returned when no record corresponds. */ -const char *tcmapget2(const TCMAP *map, const char *kstr); - - -/* Retrieve a semivolatile record in a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the - corresponding record. `NULL' is returned when no record corresponds. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. The internal region of the returned - record is moved to the tail so that the record will survive for a time under LRU cache - algorithm removing records from the head. */ -const void *tcmapget3(TCMAP *map, const void *kbuf, int ksiz, int *sp); - - -/* Move a record to the edge of a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of a key. - `ksiz' specifies the size of the region of the key. - `head' specifies the destination which is head if it is true or tail if else. - If successful, the return value is true. False is returned when no record corresponds to - the specified key. */ -bool tcmapmove(TCMAP *map, const void *kbuf, int ksiz, bool head); - - -/* Move a string record to the edge of a map object. - `map' specifies the map object. - `kstr' specifies the string of a key. - `head' specifies the destination which is head if it is true or tail if else. - If successful, the return value is true. False is returned when no record corresponds to - the specified key. */ -bool tcmapmove2(TCMAP *map, const char *kstr, bool head); - - -/* Initialize the iterator of a map object. - `map' specifies the map object. - The iterator is used in order to access the key of every record stored in the map object. */ -void tcmapiterinit(TCMAP *map); - - -/* Get the next key of the iterator of a map object. - `map' specifies the map object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the next key, else, it is - `NULL'. `NULL' is returned when no record can be fetched from the iterator. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. - The order of iteration is assured to be the same as the stored order. */ -const void *tcmapiternext(TCMAP *map, int *sp); - - -/* Get the next key string of the iterator of a map object. - `map' specifies the map object. - If successful, the return value is the pointer to the region of the next key, else, it is - `NULL'. `NULL' is returned when no record can be fetched from the iterator. - The order of iteration is assured to be the same as the stored order. */ -const char *tcmapiternext2(TCMAP *map); - - -/* Get the value bound to the key fetched from the iterator of a map object. - `kbuf' specifies the pointer to the region of the iteration key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the value of the corresponding record. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. */ -const void *tcmapiterval(const void *kbuf, int *sp); - - -/* Get the value string bound to the key fetched from the iterator of a map object. - `kstr' specifies the string of the iteration key. - The return value is the pointer to the region of the value of the corresponding record. */ -const char *tcmapiterval2(const char *kstr); - - -/* Get the number of records stored in a map object. - `map' specifies the map object. - The return value is the number of the records stored in the map object. */ -uint64_t tcmaprnum(const TCMAP *map); - - -/* Get the total size of memory used in a map object. - `map' specifies the map object. - The return value is the total size of memory used in a map object. */ -uint64_t tcmapmsiz(const TCMAP *map); - - -/* Create a list object containing all keys in a map object. - `map' specifies the map object. - The return value is the new list object containing all keys in the map object. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcmapkeys(const TCMAP *map); - - -/* Create a list object containing all values in a map object. - `map' specifies the map object. - The return value is the new list object containing all values in the map object. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcmapvals(const TCMAP *map); - - -/* Add an integer to a record in a map object. - `map' specifies the map object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `num' specifies the additional value. - If the corresponding record exists, the value is treated as a integer and is added to. If no - record corresponds, a new record of the additional value is stored. */ -void tcmapaddint(TCMAP *map, const char *kbuf, int ksiz, int num); - - -/* Clear a map object. - `map' specifies the map object. - All records are removed. */ -void tcmapclear(TCMAP *map); - - -/* Remove front records of a map object. - `map' specifies the map object. - `num' specifies the number of records to be removed. - If successful, the return value is true. False is returned when no record corresponds to - the specified key. */ -void tcmapcutfront(TCMAP *map, int num); - - -/* Serialize a map object into a byte array. - `map' specifies the map object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the result serial region. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -void *tcmapdump(const TCMAP *map, int *sp); - - -/* Create a map object from a serialized byte array. - `ptr' specifies the pointer to the region of serialized byte array. - `size' specifies the size of the region. - The return value is a new map object. - Because the object of the return value is created with the function `tcmapnew', it should be - deleted with the function `tcmapdel' when it is no longer in use. */ -TCMAP *tcmapload(const void *ptr, int size); - - -/* Extract a map record from a serialized byte array. - `ptr' specifies the pointer to the region of serialized byte array. - `size' specifies the size of the region. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the - corresponding record. `NULL' is returned when no record corresponds. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. */ -void *tcmaploadone(const void *ptr, int size, const void *kbuf, int ksiz, int *sp); - - - -/************************************************************************************************* - * on-memory database - *************************************************************************************************/ - - -typedef struct { /* type of structure for a on-memory database */ - void **mmtxs; /* mutexes for method */ - void *imtx; /* mutex for iterator */ - TCMAP **maps; /* internal map object */ - int iter; /* index of maps for the iterator */ -} TCMDB; - - -/* Create an on-memory database object. - The return value is the new on-memory database object. - The object can be shared by plural threads because of the internal mutex. */ -TCMDB *tcmdbnew(void); - - -/* Create an on-memory database object with specifying the number of the buckets. - `bnum' specifies the number of the buckets. - The return value is the new on-memory database object. - The object can be shared by plural threads because of the internal mutex. */ -TCMDB *tcmdbnew2(uint32_t bnum); - - -/* Delete an on-memory database object. - `mdb' specifies the on-memory database object. */ -void tcmdbdel(TCMDB *mdb); - - -/* Store a record into an on-memory database object. - `mdb' specifies the on-memory database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If a record with the same key exists in the database, it is overwritten. */ -void tcmdbput(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a string record into an on-memory database object. - `mdb' specifies the on-memory database object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If a record with the same key exists in the database, it is overwritten. */ -void tcmdbput2(TCMDB *mdb, const char *kstr, const char *vstr); - - -/* Store a record of the value of two regions into an on-memory database object. - `mdb' specifies the on-memory database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `fvbuf' specifies the pointer to the former region of the value. - `fvsiz' specifies the size of the former region of the value. - `lvbuf' specifies the pointer to the latter region of the value. - `lvsiz' specifies the size of the latter region of the value. - If a record with the same key exists in the database, it is overwritten. */ -void tcmdbput3(TCMDB *mdb, const char *kbuf, int ksiz, - const void *fvbuf, int fvsiz, const char *lvbuf, int lvsiz); - - -/* Store a new record into an on-memory database object. - `mdb' specifies the on-memory database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tcmdbputkeep(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Store a new string record into an on-memory database object. - `mdb' specifies the on-memory database object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If successful, the return value is true, else, it is false. - If a record with the same key exists in the database, this function has no effect. */ -bool tcmdbputkeep2(TCMDB *mdb, const char *kstr, const char *vstr); - - -/* Concatenate a value at the end of the value of the existing record in an on-memory database. - `mdb' specifies the on-memory database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `vbuf' specifies the pointer to the region of the value. - `vsiz' specifies the size of the region of the value. - If there is no corresponding record, a new record is created. */ -void tcmdbputcat(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz); - - -/* Concatenate a string at the end of the value of the existing record in an on-memory database. - `mdb' specifies the on-memory database object. - `kstr' specifies the string of the key. - `vstr' specifies the string of the value. - If there is no corresponding record, a new record is created. */ -void tcmdbputcat2(TCMDB *mdb, const char *kstr, const char *vstr); - - -/* Remove a record of an on-memory database object. - `mdb' specifies the on-memory database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is true. False is returned when no record corresponds to - the specified key. */ -bool tcmdbout(TCMDB *mdb, const void *kbuf, int ksiz); - - -/* Remove a string record of an on-memory database object. - `mdb' specifies the on-memory database object. - `kstr' specifies the string of the key. - If successful, the return value is true. False is returned when no record corresponds to - the specified key. */ -bool tcmdbout2(TCMDB *mdb, const char *kstr); - - -/* Retrieve a record in an on-memory database object. - `mdb' specifies the on-memory database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the - corresponding record. `NULL' is returned when no record corresponds. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -void *tcmdbget(TCMDB *mdb, const void *kbuf, int ksiz, int *sp); - - -/* Retrieve a string record in an on-memory database object. - `mdb' specifies the on-memory database object. - `kstr' specifies the string of the key. - If successful, the return value is the string of the value of the corresponding record. - `NULL' is returned when no record corresponds. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcmdbget2(TCMDB *mdb, const char *kstr); - - -/* Retrieve a record and move it astern in an on-memory database object. - `mdb' specifies the on-memory database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the value of the - corresponding record. `NULL' is returned when no record corresponds. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return value - is allocated with the `malloc' call, it should be released with the `free' call when it is no - longer in use. The internal region of the returned record is moved to the tail so that the - record will survive for a time under LRU cache algorithm removing records from the head. */ -void *tcmdbget3(TCMDB *mdb, const void *kbuf, int ksiz, int *sp); - - -/* Get the size of the value of a record in an on-memory database object. - `mdb' specifies the on-memory database object. - `kbuf' specifies the pointer to the region of the key. - `ksiz' specifies the size of the region of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. */ -int tcmdbvsiz(TCMDB *mdb, const void *kbuf, int ksiz); - - -/* Get the size of the value of a string record in an on-memory database object. - `mdb' specifies the on-memory database object. - `kstr' specifies the string of the key. - If successful, the return value is the size of the value of the corresponding record, else, - it is -1. */ -int tcmdbvsiz2(TCMDB *mdb, const char *kstr); - - -/* Initialize the iterator of an on-memory database object. - `mdb' specifies the on-memory database object. - The iterator is used in order to access the key of every record stored in the on-memory - database. */ -void tcmdbiterinit(TCMDB *mdb); - - -/* Get the next key of the iterator of an on-memory database object. - `mdb' specifies the on-memory database object. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the region of the next key, else, it is - `NULL'. `NULL' is returned when no record can be fetched from the iterator. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. The order of iteration is assured to be the same as the stored - order. */ -void *tcmdbiternext(TCMDB *mdb, int *sp); - - -/* Get the next key string of the iterator of an on-memory database object. - `mdb' specifies the on-memory database object. - If successful, the return value is the pointer to the region of the next key, else, it is - `NULL'. `NULL' is returned when no record can be fetched from the iterator. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. The order of iteration is assured - to be the same as the stored order. */ -char *tcmdbiternext2(TCMDB *mdb); - - -/* Get forward matching keys in an on-memory database object. - `mdb' specifies the on-memory database object. - `pbuf' specifies the pointer to the region of the prefix. - `psiz' specifies the size of the region of the prefix. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the corresponding keys. This function does never fail - and return an empty list even if no key corresponds. - Because the object of the return value is created with the function `tclistnew', it should be - deleted with the function `tclistdel' when it is no longer in use. Note that this function - may be very slow because every key in the database is scanned. */ -TCLIST *tcmdbfwmkeys(TCMDB *mdb, const void *pbuf, int psiz, int max); - - -/* Get forward matching string keys in an on-memory database object. - `mdb' specifies the on-memory database object. - `pstr' specifies the string of the prefix. - `max' specifies the maximum number of keys to be fetched. If it is negative, no limit is - specified. - The return value is a list object of the corresponding keys. This function does never fail - and return an empty list even if no key corresponds. - Because the object of the return value is created with the function `tclistnew', it should be - deleted with the function `tclistdel' when it is no longer in use. Note that this function - may be very slow because every key in the database is scanned. */ -TCLIST *tcmdbfwmkeys2(TCMDB *mdb, const char *pstr, int max); - - -/* Get the number of records stored in an on-memory database object. - `mdb' specifies the on-memory database object. - The return value is the number of the records stored in the database. */ -uint64_t tcmdbrnum(TCMDB *mdb); - - -/* Get the total size of memory used in an on-memory database object. - `mdb' specifies the on-memory database object. - The return value is the total size of memory used in the database. */ -uint64_t tcmdbmsiz(TCMDB *mdb); - - -/* Clear an on-memory database object. - `mdb' specifies the on-memory database object. - All records are removed. */ -void tcmdbvanish(TCMDB *mdb); - - -/* Remove front records of an on-memory database object. - `mdb' specifies the on-memory database object. - `num' specifies the number of records to be removed. - If successful, the return value is true. False is returned when no record corresponds to - the specified key. */ -void tcmdbcutfront(TCMDB *mdb, int num); - - - -/************************************************************************************************* - * memory pool - *************************************************************************************************/ - - -typedef struct { /* type of an element of memory pool */ - void *ptr; /* pointer */ - void (*del)(void *); /* deleting function */ -} TCMPELEM; - -typedef struct { /* type of structure for a memory pool object */ - void *mutex; /* mutex for operations */ - TCMPELEM *elems; /* array of elements */ - int anum; /* number of the elements of the array */ - int num; /* number of used elements */ -} TCMPOOL; - - -/* Create a memory pool object. - The return value is the new memory pool object. */ -TCMPOOL *tcmpoolnew(void); - - -/* Delete a memory pool object. - `mpool' specifies the memory pool object. - Note that the deleted object and its derivatives can not be used anymore. */ -void tcmpooldel(TCMPOOL *mpool); - - -/* Relegate an arbitrary object to a memory pool object. - `mpool' specifies the memory pool object. - `ptr' specifies the pointer to the object to be relegated. - `del' specifies the pointer to the function to delete the object. - This function assures that the specified object is deleted when the memory pool object is - deleted. */ -void tcmpoolput(TCMPOOL *mpool, void *ptr, void (*del)(void *)); - - -/* Relegate an allocated region to a memory pool object. - `ptr' specifies the pointer to the region to be relegated. - This function assures that the specified region is released when the memory pool object is - deleted. */ -void tcmpoolputptr(TCMPOOL *mpool, void *ptr); - - -/* Relegate an extensible string object to a memory pool object. - `mpool' specifies the memory pool object. - `xstr' specifies the extensible string object. - This function assures that the specified object is deleted when the memory pool object is - deleted. */ -void tcmpoolputxstr(TCMPOOL *mpool, TCXSTR *xstr); - - -/* Relegate a list object to a memory pool object. - `mpool' specifies the memory pool object. - `list' specifies the list object. - This function assures that the specified object is deleted when the memory pool object is - deleted. */ -void tcmpoolputlist(TCMPOOL *mpool, TCLIST *list); - - -/* Relegate a map object to a memory pool object. - `mpool' specifies the memory pool object. - `map' specifies the map object. - This function assures that the specified object is deleted when the memory pool object is - deleted. */ -void tcmpoolputmap(TCMPOOL *mpool, TCMAP *map); - - -/* Allocate a region relegated to a memory pool object. - `mpool' specifies the memory pool object. - The return value is the pointer to the allocated region under the memory pool. */ -void *tcmpoolmalloc(TCMPOOL *mpool, size_t size); - - -/* Create an extensible string object relegated to a memory pool object. - The return value is the new extensible string object under the memory pool. */ -TCXSTR *tcmpoolxstrnew(TCMPOOL *mpool); - - -/* Create a list object relegated to a memory pool object. - The return value is the new list object under the memory pool. */ -TCLIST *tcmpoollistnew(TCMPOOL *mpool); - - -/* Create a map object relegated to a memory pool object. - The return value is the new map object under the memory pool. */ -TCMAP *tcmpoolmapnew(TCMPOOL *mpool); - - -/* Get the global memory pool object. - The return value is the global memory pool object. - The global memory pool object is a singleton and assured to be deleted when the porcess is - terminating normally. */ -TCMPOOL *tcmpoolglobal(void); - - - -/************************************************************************************************* - * miscellaneous utilities - *************************************************************************************************/ - - -/* Get the larger value of two integers. - `a' specifies an integer. - `b' specifies the other integer. - The return value is the larger value of the two. */ -long tclmax(long a, long b); - - -/* Get the lesser value of two integers. - `a' specifies an integer. - `b' specifies the other integer. - The return value is the lesser value of the two. */ -long tclmin(long a, long b); - - -/* Get a random number as long integer based on uniform distribution. - The return value is the random number between 0 and `ULONG_MAX'. - This function uses the random number source device and generates a real random number if - possible. */ -unsigned long tclrand(void); - - -/* Get a random number as double decimal based on uniform distribution. - The return value is the random number equal to or greater than 0, and less than 1.0. - This function uses the random number source device and generates a real random number if - possible. */ -double tcdrand(void); - - -/* Get a random number as double decimal based on normal distribution. - `avg' specifies the average. - `sd' specifies the standard deviation. - The return value is the random number. - This function uses the random number source device and generates a real random number if - possible. */ -double tcdrandnd(double avg, double sd); - - -/* Compare two strings with case insensitive evaluation. - `astr' specifies a string. - `bstr' specifies of the other string. - The return value is positive if the former is big, negative if the latter is big, 0 if both - are equivalent. */ -int tcstricmp(const char *astr, const char *bstr); - - -/* Check whether a string begins with a key. - `str' specifies the target string. - `key' specifies the forward matching key string. - The return value is true if the target string begins with the key, else, it is false. */ -bool tcstrfwm(const char *str, const char *key); - - -/* Check whether a string begins with a key with case insensitive evaluation. - `str' specifies the target string. - `key' specifies the forward matching key string. - The return value is true if the target string begins with the key, else, it is false. */ -bool tcstrifwm(const char *str, const char *key); - - -/* Check whether a string ends with a key. - `str' specifies the target string. - `key' specifies the backward matching key string. - The return value is true if the target string ends with the key, else, it is false. */ -bool tcstrbwm(const char *str, const char *key); - - -/* Check whether a string ends with a key with case insensitive evaluation. - `str' specifies the target string. - `key' specifies the backward matching key string. - The return value is true if the target string ends with the key, else, it is false. */ -bool tcstribwm(const char *str, const char *key); - - -/* Calculate the edit distance of two strings. - `astr' specifies a string. - `bstr' specifies of the other string. - The return value is the edit distance which is known as the Levenshtein distance. The cost is - calculated by byte. */ -int tcstrdist(const char *astr, const char *bstr); - - -/* Calculate the edit distance of two UTF-8 strings. - `astr' specifies a string. - `bstr' specifies of the other string. - The return value is the edit distance which is known as the Levenshtein distance. The cost is - calculated by Unicode character. */ -int tcstrdistutf(const char *astr, const char *bstr); - - -/* Convert the letters of a string into upper case. - `str' specifies the string to be converted. - The return value is the string itself. */ -char *tcstrtoupper(char *str); - - -/* Convert the letters of a string into lower case. - `str' specifies the string to be converted. - The return value is the string itself. */ -char *tcstrtolower(char *str); - - -/* Cut space characters at head or tail of a string. - `str' specifies the string to be converted. - The return value is the string itself. */ -char *tcstrtrim(char *str); - - -/* Squeeze space characters in a string and trim it. - `str' specifies the string to be converted. - The return value is the string itself. */ -char *tcstrsqzspc(char *str); - - -/* Substitute characters in a string. - `str' specifies the string to be converted. - `rstr' specifies the string containing characters to be replaced. - `sstr' specifies the string containing characters to be substituted. - If the substitute string is shorter then the replacement string, corresponding characters are - removed. */ -char *tcstrsubchr(char *str, const char *rstr, const char *sstr); - - -/* Count the number of characters in a string of UTF-8. - `str' specifies the string of UTF-8. - The return value is the number of characters in the string. */ -int tcstrcntutf(const char *str); - - -/* Cut a string of UTF-8 at the specified number of characters. - `str' specifies the string of UTF-8. - `num' specifies the number of characters to be kept. - The return value is the string itself. */ -char *tcstrcututf(char *str, int num); - - -/* Convert a UTF-8 string into a UCS-2 array. - `str' specifies the UTF-8 string. - `ary' specifies the pointer to the region into which the result UCS-2 codes are written. The - size of the buffer should be sufficient. - `np' specifies the pointer to a variable into which the number of elements of the result array - is assigned. */ -void tcstrutftoucs(const char *str, uint16_t *ary, int *np); - - -/* Convert a UCS-2 array into a UTF-8 string. - `ary' specifies the array of UCS-2 code codes. - `num' specifies the number of the array. - `str' specifies the pointer to the region into which the result UTF-8 string is written. The - size of the buffer should be sufficient. */ -void tcstrucstoutf(const uint16_t *ary, int num, char *str); - - -/* Create a list object by splitting a string. - `str' specifies the source string. - `delim' specifies a string containing delimiting characters. - The return value is a list object of the split elements. - If two delimiters are successive, it is assumed that an empty element is between the two. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcstrsplit(const char *str, const char *delims); - - -/* Create a string by joining all elements of a list object. - `list' specifies a list object. - `delim' specifies a delimiting character. - The return value is the result string. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcstrjoin(TCLIST *list, char delim); - - -/* Check whether a string matches a regular expression. - `str' specifies the target string. - `regex' specifies the regular expression string. If it begins with `*', the trailing - substring is used as a case-insensitive regular expression. - The return value is true if matching is success, else, it is false. */ -bool tcregexmatch(const char *str, const char *regex); - - -/* Replace each substring matching a regular expression string. - `str' specifies the target string. - `regex' specifies the regular expression string for substrings. If it begins with `*', the - trailing substring is used as a case-insensitive regular expression. - `alt' specifies the alternative string with which each substrings is replaced. Each `&' in - the string is replaced with the matched substring. Each `\' in the string escapes the - following character. Special escapes "\1" through "\9" referring to the corresponding - matching sub-expressions in the regular expression string are supported. - The return value is a new converted string. Even if the regular expression is invalid, a copy - of the original string is returned. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcregexreplace(const char *str, const char *regex, const char *alt); - - -/* Get the time of day in seconds. - The return value is the time of day in seconds. The accuracy is in microseconds. */ -double tctime(void); - - -/* Get the Gregorian calendar of a time. - `t' specifies the source time in seconds from the epoch. If it is `INT64_MAX', the current - time is specified. - `jl' specifies the jet lag of a location in seconds. If it is `INT_MAX', the local jet lag is - specified. - `yearp' specifies the pointer to a variable to which the year is assigned. If it is `NULL', - it is not used. - `monp' specifies the pointer to a variable to which the month is assigned. If it is `NULL', - it is not used. 1 means January and 12 means December. - `dayp' specifies the pointer to a variable to which the day of the month is assigned. If it - is `NULL', it is not used. - `hourp' specifies the pointer to a variable to which the hours is assigned. If it is `NULL', - it is not used. - `minp' specifies the pointer to a variable to which the minutes is assigned. If it is `NULL', - it is not used. - `secp' specifies the pointer to a variable to which the seconds is assigned. If it is `NULL', - it is not used. */ -void tccalendar(int64_t t, int jl, int *yearp, int *monp, int *dayp, - int *hourp, int *minp, int *secp); - - -/* Format a date as a string in W3CDTF. - `t' specifies the source time in seconds from the epoch. If it is `INT64_MAX', the current - time is specified. - `jl' specifies the jet lag of a location in seconds. If it is `INT_MAX', the local jet lag is - specified. - `buf' specifies the pointer to the region into which the result string is written. The size - of the buffer should be equal to or more than 48 bytes. - W3CDTF represents a date as "YYYY-MM-DDThh:mm:ddTZD". */ -void tcdatestrwww(int64_t t, int jl, char *buf); - - -/* Format a date as a string in RFC 1123 format. - `t' specifies the source time in seconds from the epoch. If it is `INT64_MAX', the current - time is specified. - `jl' specifies the jet lag of a location in seconds. If it is `INT_MAX', the local jet lag is - specified. - `buf' specifies the pointer to the region into which the result string is written. The size - of the buffer should be equal to or more than 48 bytes. - RFC 1123 format represents a date as "Wdy, DD-Mon-YYYY hh:mm:dd TZD". */ -void tcdatestrhttp(int64_t t, int jl, char *buf); - - -/* Get the time value of a date string. - `str' specifies the date string in decimal, hexadecimal, W3CDTF, or RFC 822 (1123). Decimal - can be trailed by "s" for in seconds, "m" for in minutes, "h" for in hours, and "d" for in - days. - The return value is the time value of the date or `INT64_MAX' if the format is invalid. */ -int64_t tcstrmktime(const char *str); - - -/* Get the day of week of a date. - `year' specifies the year of a date. - `mon' specifies the month of the date. - `day' specifies the day of the date. - The return value is the day of week of the date. 0 means Sunday and 6 means Saturday. */ -int tcdayofweek(int year, int mon, int day); - - - -/************************************************************************************************* - * filesystem utilities - *************************************************************************************************/ - - -/* Get the canonicalized absolute path of a file. - `path' specifies the path of the file. - The return value is the canonicalized absolute path of a file, or `NULL' if the path is - invalid. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcrealpath(const char *path); - - -/* Read whole data of a file. - `path' specifies the path of the file. If it is `NULL', the standard input is specified. - `limit' specifies the limiting size of reading data. If it is not more than 0, the limitation - is not specified. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. If it is `NULL', it is not used. - The return value is the pointer to the allocated region of the read data, or `NULL' if the - file could not be opened. - Because an additional zero code is appended at the end of the region of the return value, the - return value can be treated as a character string. Because the region of the return value is - allocated with the `malloc' call, it should be released with the `free' call when when is no - longer in use. */ -void *tcreadfile(const char *path, int limit, int *sp); - - -/* Read every line of a file. - `path' specifies the path of the file. If it is `NULL', the standard input is specified. - The return value is a list object of every lines if successful, else it is `NULL'. - Line separators are cut out. Because the object of the return value is created with the - function `tclistnew', it should be deleted with the function `tclistdel' when it is no longer - in use. */ -TCLIST *tcreadfilelines(const char *path); - - -/* Write data into a file. - `path' specifies the path of the file. If it is `NULL', the standard output is specified. - `ptr' specifies the pointer to the data region. - `size' specifies the size of the region. - If successful, the return value is true, else, it is false. */ -bool tcwritefile(const char *path, const void *ptr, int size); - - -/* Copy a file. - `src' specifies the path of the source file. - `dest' specifies the path of the destination file. - The return value is true if successful, else, it is false. - If the destination file exists, it is overwritten. */ -bool tccopyfile(const char *src, const char *dest); - - -/* Read names of files in a directory. - `path' specifies the path of the directory. - The return value is a list object of names if successful, else it is `NULL'. - Links to the directory itself and to the parent directory are ignored. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcreaddir(const char *path); - - -/* Expand a pattern into a list of matched paths. - `pattern' specifies the matching pattern. - The return value is a list object of matched paths. If no path is matched, an empty list is - returned. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. */ -TCLIST *tcglobpat(const char *pattern); - - -/* Remove a file or a directory and its sub ones recursively. - `path' specifies the path of the link. - If successful, the return value is true, else, it is false. False is returned when the link - does not exist or the permission is denied. */ -bool tcremovelink(const char *path); - - -/* Write data into a file. - `fd' specifies the file descriptor. - `buf' specifies the buffer to be written. - `size' specifies the size of the buffer. - The return value is true if successful, else, it is false. */ -bool tcwrite(int fd, const void *buf, size_t size); - - -/* Read data from a file. - `fd' specifies the file descriptor. - `buf' specifies the buffer to store into. - `size' specifies the size of the buffer. - The return value is true if successful, else, it is false. */ -bool tcread(int fd, void *buf, size_t size); - - -/* Lock a file. - `fd' specifies the file descriptor. - `ex' specifies whether an exclusive lock or a shared lock is performed. - `nb' specifies whether to request with non-blocking. - The return value is true if successful, else, it is false. */ -bool tclock(int fd, bool ex, bool nb); - - - -/************************************************************************************************* - * encoding utilities - *************************************************************************************************/ - - -/* Encode a serial object with URL encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - The return value is the result string. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call if when is no longer in use. */ -char *tcurlencode(const char *ptr, int size); - - -/* Decode a string encoded with URL encoding. - `str' specifies the encoded string. - `sp' specifies the pointer to a variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the result. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -char *tcurldecode(const char *str, int *sp); - - -/* Break up a URL into elements. - `str' specifies the URL string. - The return value is the map handle whose keys are the name of elements. The key "self" - specifies the URL itself. The key "scheme" specifies the scheme. The key "host" specifies - the host of the server. The key "port" specifies the port number of the server. The key - "authority" specifies the authority information. The key "path" specifies the path of the - resource. The key "file" specifies the file name without the directory section. The key - "query" specifies the query string. The key "fragment" specifies the fragment string. - Supported schema are HTTP, HTTPS, FTP, and FILE. Absolute URL and relative URL are supported. - Because the object of the return value is created with the function `tcmapnew', it should be - deleted with the function `tcmapdel' when it is no longer in use. */ -TCMAP *tcurlbreak(const char *str); - - -/* Resolve a relative URL with an absolute URL. - `base' specifies the absolute URL of the base location. - `target' specifies the URL to be resolved. - The return value is the resolved URL. If the target URL is relative, a new URL of relative - location from the base location is returned. Else, a copy of the target URL is returned. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcurlresolve(const char *base, const char *target); - - -/* Encode a serial object with Base64 encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - The return value is the result string. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call if when is no longer in use. */ -char *tcbaseencode(const char *ptr, int size); - - -/* Decode a string encoded with Base64 encoding. - `str' specifies the encoded string. - `sp' specifies the pointer to a variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the result. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -char *tcbasedecode(const char *str, int *sp); - - -/* Encode a serial object with Quoted-printable encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - The return value is the result string. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call if when is no longer in use. */ -char *tcquoteencode(const char *ptr, int size); - - -/* Decode a string encoded with Quoted-printable encoding. - `str' specifies the encoded string. - `sp' specifies the pointer to a variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the result. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when - it is no longer in use. */ -char *tcquotedecode(const char *str, int *sp); - - -/* Encode a string with MIME encoding. - `str' specifies the string. - `encname' specifies the string of the name of the character encoding. - `base' specifies whether to use Base64 encoding. If it is false, Quoted-printable is used. - The return value is the result string. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcmimeencode(const char *str, const char *encname, bool base); - - -/* Decode a string encoded with MIME encoding. - `str' specifies the encoded string. - `enp' specifies the pointer to the region into which the name of encoding is written. If it - is `NULL', it is not used. The size of the buffer should be equal to or more than 32 bytes. - The return value is the result string. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcmimedecode(const char *str, char *enp); - - -/* Compress a serial object with Packbits encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the result object, else, it is `NULL'. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcpackencode(const char *ptr, int size, int *sp); - - -/* Decompress a serial object compressed with Packbits encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `sp' specifies the pointer to a variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the result object, else, it is `NULL'. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. */ -char *tcpackdecode(const char *ptr, int size, int *sp); - - -/* Compress a serial object with TCBS encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the result object, else, it is `NULL'. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcbsencode(const char *ptr, int size, int *sp); - - -/* Decompress a serial object compressed with TCBS encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `sp' specifies the pointer to a variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the result object, else, it is `NULL'. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. */ -char *tcbsdecode(const char *ptr, int size, int *sp); - - -/* Compress a serial object with Deflate encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the result object, else, it is `NULL'. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcdeflate(const char *ptr, int size, int *sp); - - -/* Decompress a serial object compressed with Deflate encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `sp' specifies the pointer to a variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the result object, else, it is `NULL'. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. */ -char *tcinflate(const char *ptr, int size, int *sp); - - -/* Compress a serial object with GZIP encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `sp' specifies the pointer to the variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the result object, else, it is `NULL'. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call when it is no longer in use. */ -char *tcgzipencode(const char *ptr, int size, int *sp); - - -/* Decompress a serial object compressed with GZIP encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `sp' specifies the pointer to a variable into which the size of the region of the return - value is assigned. - If successful, the return value is the pointer to the result object, else, it is `NULL'. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. */ -char *tcgzipdecode(const char *ptr, int size, int *sp); - - -/* Get the CRC32 checksum of a serial object. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - The return value is the CRC32 checksum of the object. */ -unsigned int tcgetcrc(const char *ptr, int size); - - -/* Encode an array of nonnegative integers with BER encoding. - `ary' specifies the pointer to the array of nonnegative integers. - `anum' specifies the size of the array. - `sp' specifies the pointer to a variable into which the size of the region of the return - value is assigned. - The return value is the pointer to the region of the result. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call if when is no longer in use. */ -char *tcberencode(const unsigned int *ary, int anum, int *sp); - - -/* Decode a serial object encoded with BER encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `np' specifies the pointer to a variable into which the number of elements of the return value - is assigned. - The return value is the pointer to the array of the result. - Because the region of the return value is allocated with the `malloc' call, it should be - released with the `free' call if when is no longer in use. */ -unsigned int *tcberdecode(const char *ptr, int size, int *np); - - -/* Escape meta characters in a string with the entity references of XML. - `str' specifies the string. - The return value is the pointer to the escaped string. - This function escapes only `&', `<', `>', and `"'. Because the region of the return value - is allocated with the `malloc' call, it should be released with the `free' call when it is no - longer in use. */ -char *tcxmlescape(const char *str); - - -/* Unescape entity references in a string of XML. - `str' specifies the string. - The return value is the unescaped string. - This function restores only `&', `<', `>', and `"'. Because the region of the - return value is allocated with the `malloc' call, it should be released with the `free' call - when it is no longer in use. */ -char *tcxmlunescape(const char *str); - - -/* Split an XML string into tags and text sections. - `str' specifies the XML string. - The return value is the list object whose elements are strings of tags or text sections. - Because the object of the return value is created with the function `tclistnew', it should - be deleted with the function `tclistdel' when it is no longer in use. Because this function - does not check validation, it can handle also HTML and SGML. */ -TCLIST *tcxmlbreak(const char *str); - - -/* Get the map of attributes of an XML tag. - `str' specifies the pointer to the region of a tag string. - The return value is the map object containing attribute names and their values which are - unescaped. You can get the name of the tag with the key of an empty string. - Because the object of the return value is created with the function `tcmapnew', it should - be deleted with the function `tcmapdel' when it is no longer in use. */ -TCMAP *tcxmlattrs(const char *str); - - - -/************************************************************************************************* - * bit operation utilities - *************************************************************************************************/ - - -typedef struct { /* type of structure for a bit stream object */ - uint8_t *sp; /* start pointer */ - uint8_t *cp; /* current pointer */ - int idx; /* bit index */ - int size; /* size of used region */ -} TCBITSTRM; - - -/* Create a bitmap object. */ -#define TCBITMAPNEW(TC_num) \ - tccalloc(((TC_num) >> 3) + 1, 1); - - -/* Delete a bitmap object */ -#define TCBITMAPDEL(TC_bitmap) \ - do { \ - free((TC_bitmap)); \ - } while(false); - - -/* Turn on a field of a bitmap object. */ -#define TCBITMAPON(TC_bitmap, TC_idx) \ - do { \ - (TC_bitmap)[(TC_idx)>>3] |= 0x1 << ((TC_idx) & 0x7); \ - } while(false); - - -/* Turn off a field of a bitmap object. */ -#define TCBITMAPOFF(TC_bitmap, TC_idx) \ - do { \ - (TC_bitmap)[(TC_idx)>>3] &= ~(0x1 << ((TC_idx) & 0x7)); \ - } while(false); - - -/* Check a field of a bitmap object. */ -#define TCBITMAPCHECK(TC_bitmap, TC_idx) \ - ((TC_bitmap)[(TC_idx)>>3] & 0x1 << ((TC_idx) & 0x7)) - - -/* Initialize a bit stream object as writer. */ -#define TCBITSTRMINITW(TC_bitstrm, TC_ptr) \ - do { \ - (TC_bitstrm).sp = (uint8_t *)(TC_ptr); \ - (TC_bitstrm).cp = (TC_bitstrm).sp; \ - *(TC_bitstrm).cp = 0; \ - (TC_bitstrm).idx = 3; \ - (TC_bitstrm).size = 1; \ - } while(false); - - -/* Concatenate a bit to a bit stream object. */ -#define TCBITSTRMCAT(TC_bitstrm, sign) \ - do { \ - if((TC_bitstrm).idx >= 8){ \ - *(++(TC_bitstrm).cp) = 0; \ - (TC_bitstrm).idx = 0; \ - (TC_bitstrm).size++; \ - } \ - *(TC_bitstrm).cp |= (sign << (TC_bitstrm).idx); \ - (TC_bitstrm).idx++; \ - } while(false); - - -/* Set the end mark to a bit stream object. */ -#define TCBITSTRMSETEND(TC_bitstrm) \ - do { \ - if((TC_bitstrm).idx >= 8){ \ - *(++(TC_bitstrm).cp) = 0; \ - (TC_bitstrm).idx = 0; \ - (TC_bitstrm).size++; \ - } \ - *(TC_bitstrm).sp |= (TC_bitstrm).idx & 7; \ - } while(false); - - -/* Get the size of the used region of a bit stream object. */ -#define TCBITSTRMSIZE(TC_bitstrm) \ - ((TC_bitstrm).size) - - -/* Initialize a bit stream object as reader. */ -#define TCBITSTRMINITR(TC_bitstrm, TC_ptr, TC_size) \ - do { \ - (TC_bitstrm).sp = (uint8_t *)(TC_ptr); \ - (TC_bitstrm).cp = (TC_bitstrm).sp; \ - (TC_bitstrm).idx = 3; \ - (TC_bitstrm).size = (TC_size); \ - } while(false); - - -/* Read a bit from a bit stream object. */ -#define TCBITSTRMREAD(TC_bitstrm, TC_sign) \ - do { \ - if((TC_bitstrm).idx >= 8){ \ - (TC_bitstrm).cp++; \ - (TC_bitstrm).idx = 0; \ - } \ - (TC_sign) = (*((TC_bitstrm).cp) & (1 << (TC_bitstrm).idx)) > 0; \ - (TC_bitstrm).idx++; \ - } while(false); - - -/* Get the number of bits of a bit stream object. */ -#define TCBITSTRMNUM(TC_bitstrm) \ - ((((TC_bitstrm).size - 1) << 3) + (*(TC_bitstrm).sp & 7) - 3) - - - -/************************************************************************************************* - * features for experts - *************************************************************************************************/ - - -#include - -#define _TC_VERSION "1.2.5" -#define _TC_LIBVER 306 -#define _TC_FORMATVER "1.0" - - -/* Show error message on the standard error output and exit. - `message' specifies an error message. - This function does not return. */ -void *tcmyfatal(const char *message); - - -/* Lock the global mutex object. - If successful, the return value is true, else, it is false. */ -bool tcglobalmutexlock(void); - - -/* Lock the global mutex object by shared locking. - If successful, the return value is true, else, it is false. */ -bool tcglobalmutexlockshared(void); - - -/* Unlock the global mutex object. - If successful, the return value is true, else, it is false. */ -bool tcglobalmutexunlock(void); - - -/* Encode a serial object with BWT encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `idxp' specifies the pointer to the variable into which the index of the original string in - the rotation array is assigned. - The return value is the pointer to the result object. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. */ -char *tcbwtencode(const char *ptr, int size, int *idxp); - - -/* Decode a serial object encoded with BWT encoding. - `ptr' specifies the pointer to the region. - `size' specifies the size of the region. - `idx' specifies the index of the original string in the rotation array is assigned. - The return value is the pointer to the result object. - Because an additional zero code is appended at the end of the region of the return value, - the return value can be treated as a character string. Because the region of the return - value is allocated with the `malloc' call, it should be released with the `free' call when it - is no longer in use. */ -char *tcbwtdecode(const char *ptr, int size, int idx); - - -/* Print debug information with a formatted string as with `printf'. */ -#if __STDC_VERSION__ >= 199901L -#define TCDPRINTF(...) \ - do { \ - fprintf(stderr, "%s:%d:%s: ", __FILE__, __LINE__, __func__); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } while(false); -#else -#define TCDPRINTF(TC_str) \ - do { \ - fprintf(stderr, "%s:%d:%s: %s\n", __FILE__, __LINE__, __func__, TC_str); \ - } while(false); -#endif - - -/* Print hexadecimal pattern of a binary region. */ -#define TCPRINTHEX(TC_ptr, TC_size) \ - do { \ - for(int TC_i = 0; TC_i < (TC_size); TC_i++){ \ - if(TC_i > 0) putchar(' '); \ - printf("%02X", ((unsigned char *)(TC_ptr))[TC_i]); \ - } \ - putchar('\n'); \ - } while(false); - - -/* Print an extensible string object. */ -#define TCPRINTXSTR(TC_xstr) \ - do { \ - fwrite(tcxstrptr((TC_xstr)), tcxstrsize((TC_xstr)), 1, stdout); \ - putchar('\n'); \ - } while(false); - - -/* Print all elements of a list object. */ -#define TCPRINTLIST(TC_list) \ - do { \ - for(int TC_i = 0; TC_i < tclistnum((TC_list)); TC_i++){ \ - int TC_size; \ - const char *TC_ptr = tclistval((TC_list), TC_i, &TC_size); \ - printf("%p\t", (void *)(TC_list)); \ - fwrite(TC_ptr, TC_size, 1, stdout); \ - putchar('\n'); \ - } \ - putchar('\n'); \ - } while(false); - - -/* Print all records of a list object. */ -#define TCPRINTMAP(TC_map) \ - do { \ - TCLIST *TC_keys = tcmapkeys((TC_map)); \ - for(int TC_i = 0; TC_i < tclistnum(TC_keys); TC_i++){ \ - int TC_ksiz; \ - const char *TC_kbuf = tclistval(TC_keys, TC_i, &TC_ksiz); \ - int TC_vsiz; \ - const char *TC_vbuf = tcmapget((TC_map), TC_kbuf, TC_ksiz, &TC_vsiz); \ - printf("%p\t", (void *)(TC_map)); \ - fwrite(TC_kbuf, TC_ksiz, 1, stdout); \ - putchar('\t'); \ - fwrite(TC_vbuf, TC_vsiz, 1, stdout); \ - putchar('\n'); \ - } \ - putchar('\n'); \ - tclistdel(TC_keys); \ - } while(false); - - -/* Alias of `tcmemdup'. */ -#if defined(_MYFASTEST) -#define TCMALLOC(TC_res, TC_size) \ - do { \ - (TC_res) = malloc(TC_size); \ - } while(false) -#else -#define TCMALLOC(TC_res, TC_size) \ - do { \ - if(!((TC_res) = malloc(TC_size))) tcmyfatal("out of memory"); \ - } while(false) -#endif - -/* Alias of `tccalloc'. */ -#if defined(_MYFASTEST) -#define TCCALLOC(TC_res, TC_nmemb, TC_size) \ - do { \ - (TC_res) = calloc((TC_nmemb), (TC_size)); \ - } while(false) -#else -#define TCCALLOC(TC_res, TC_nmemb, TC_size) \ - do { \ - if(!((TC_res) = calloc((TC_nmemb), (TC_size)))) tcmyfatal("out of memory"); \ - } while(false) -#endif - -/* Alias of `tcrealloc'. */ -#if defined(_MYFASTEST) -#define TCREALLOC(TC_res, TC_ptr, TC_size) \ - do { \ - (TC_res) = realloc((TC_ptr), (TC_size)); \ - } while(false) -#else -#define TCREALLOC(TC_res, TC_ptr, TC_size) \ - do { \ - if(!((TC_res) = realloc((TC_ptr), (TC_size)))) tcmyfatal("out of memory"); \ - } while(false) -#endif - -/* Alias of `tcmemdup'. */ -#define TCMEMDUP(TC_res, TC_ptr, TC_size) \ - do { \ - TCMALLOC((TC_res), (TC_size) + 1); \ - memcpy((TC_res), (TC_ptr), (TC_size)); \ - (TC_res)[TC_size] = '\0'; \ - } while(false) - - -/* Alias of `tcxstrcat'. */ -#define TCXSTRCAT(TC_xstr, TC_ptr, TC_size) \ - do { \ - int TC_mysize = (TC_size); \ - int TC_nsize = (TC_xstr)->size + TC_mysize + 1; \ - if((TC_xstr)->asize < TC_nsize){ \ - while((TC_xstr)->asize < TC_nsize){ \ - (TC_xstr)->asize *= 2; \ - if((TC_xstr)->asize < TC_nsize) (TC_xstr)->asize = TC_nsize; \ - } \ - TCREALLOC((TC_xstr)->ptr, (TC_xstr)->ptr, (TC_xstr)->asize); \ - } \ - memcpy((TC_xstr)->ptr + (TC_xstr)->size, (TC_ptr), TC_mysize); \ - (TC_xstr)->size += TC_mysize; \ - (TC_xstr)->ptr[(TC_xstr)->size] = '\0'; \ - } while(false) - - -/* Alias of `tcxstrptr'. */ -#define TCXSTRPTR(TC_xstr) \ - ((TC_xstr)->ptr) - - -/* Alias of `tcxstrsize'. */ -#define TCXSTRSIZE(TC_xstr) \ - ((TC_xstr)->size) - - -/* Alias of `tclistnum'. */ -#define TCLISTNUM(TC_list) \ - ((TC_list)->num) - - -/* Alias of `tclistval' but not checking size and not using the third parameter. */ -#define TCLISTVALPTR(TC_list, TC_index) \ - ((void *)((TC_list)->array[(TC_index)+(TC_list)->start].ptr)) - - -/* Alias of `tclistval' but not checking size and returning the size of the value. */ -#define TCLISTVALNUM(TC_list, TC_index) \ - ((TC_list)->array[(TC_index)+(TC_list)->start].size) - - -/* Add an element at the end of a list object. */ -#define TCLISTPUSH(TC_list, TC_ptr, TC_size) \ - do { \ - int TC_mysize = (TC_size); \ - int TC_index = (TC_list)->start + (TC_list)->num; \ - if(TC_index >= (TC_list)->anum){ \ - (TC_list)->anum += (TC_list)->num + 1; \ - TCREALLOC((TC_list)->array, (TC_list)->array, \ - (TC_list)->anum * sizeof((TC_list)->array[0])); \ - } \ - TCLISTDATUM *array = (TC_list)->array; \ - TCMALLOC(array[TC_index].ptr, TC_mysize + 1); \ - memcpy(array[TC_index].ptr, (TC_ptr), TC_mysize); \ - array[TC_index].ptr[TC_mysize] = '\0'; \ - array[TC_index].size = TC_mysize; \ - (TC_list)->num++; \ - } while(false) - - -/* Alias of `tcmaprnum'. */ -#define TCMAPRNUM(TC_map) \ - ((TC_map)->rnum) - - - -__TCUTIL_CLINKAGEEND -#endif /* duplication check */ - - -/* END OF FILE */ diff --git a/bacula/src/lib/tokyocabinet/tokyocabinet.idl b/bacula/src/lib/tokyocabinet/tokyocabinet.idl deleted file mode 100644 index 77cdf9f376..0000000000 --- a/bacula/src/lib/tokyocabinet/tokyocabinet.idl +++ /dev/null @@ -1,158 +0,0 @@ -/************************************************************************************************* - * IDL for bindings of scripting languages - * Copyright (C) 2006-2008 Mikio Hirabayashi - * This file is part of Tokyo Cabinet. - * Tokyo Cabinet 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 2.1 of the License or any later version. Tokyo Cabinet 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 Lesser General Public - * License for more details. - * You should have received a copy of the GNU Lesser General Public License along with Tokyo - * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, - * Boston, MA 02111-1307 USA. - *************************************************************************************************/ - - -/** - * namespace of Tokyo Cabinet - */ -module TokyoCabinet { - //---------------------------------------------------------------- - // list of strings (substituted for by the native mechanism). - //---------------------------------------------------------------- - interface List { - string get(in long index); - }; - //---------------------------------------------------------------- - // the error codes - //---------------------------------------------------------------- - interface ECODE { - const long ESUCCESS = 0; - const long ETHREAD = 1; - const long EINVALID = 2; - const long ENOFILE = 3; - const long ENOPERM = 4; - const long EMETA = 5; - const long ERHEAD = 6; - const long EOPEN = 7; - const long ECLOSE = 8; - const long ETRUNC = 9; - const long ESYNC = 10; - const long ESTAT = 11; - const long ESEEK = 12; - const long EREAD = 13; - const long EWRITE = 14; - const long EMMAP = 15; - const long ELOCK = 16; - const long EUNLINK = 17; - const long ERENAME = 18; - const long EMKDIR = 19; - const long ERMDIR = 20; - const long EKEEP = 21; - const long ENOREC = 22; - const long EMISC = 9999; - string errmsg(in long ecode); - }; - //---------------------------------------------------------------- - // the hash database API - //---------------------------------------------------------------- - interface HDB :ECODE { - const long TLARGE = 1 << 0; - const long TDEFLATE = 1 << 1; - const long TTCBS = 1 << 2; - const long OREADER = 1 << 0; - const long OWRITER = 1 << 1; - const long OCREAT = 1 << 2; - const long OTRUNC = 1 << 3; - const long ONOLCK = 1 << 4; - const long OLCKNB = 1 << 5; - long ecode(); - boolean tune(in long long bnum, in long apow, in long fpow, in long opts); - boolean setcache(in long rcnum); - boolean open(in string path, in long omode); - boolean close(); - boolean put(in string key, in string value); - boolean putkeep(in string key, in string value); - boolean putcat(in string key, in string value); - boolean putasync(in string key, in string value); - boolean out(in string key); - string get(in string key); - long vsiz(in string key); - boolean iterinit(); - string iternext(); - List fwmkeys(in string prefix, in long max); - boolean sync(); - boolean optimize(in long long bnum, in long apow, in long fpow, in long opts); - boolean vanish(); - boolean copy(in string path); - string path(); - long long rnum(); - long long fsiz(); - }; - //---------------------------------------------------------------- - // the B+ tree database API - //---------------------------------------------------------------- - interface BDB :ECODE { - const long TLARGE = 1 << 0; - const long TDEFLATE = 1 << 1; - const long TTCBS = 1 << 2; - const long OREADER = 1 << 0; - const long OWRITER = 1 << 1; - const long OCREAT = 1 << 2; - const long OTRUNC = 1 << 3; - const long ONOLCK = 1 << 4; - const long OLCKNB = 1 << 5; - long ecode(); - boolean tune(in long lmemb, in long nmemb, - in long long bnum, in long apow, in long fpow, in long opts); - boolean setcache(in long lcnum, in long ncnum); - boolean open(in string path, in long omode); - boolean close(); - boolean put(in string key, in string value); - boolean putkeep(in string key, in string value); - boolean putcat(in string key, in string value); - boolean putdup(in string key, in string value); - boolean putlist(in string key, in List values); - boolean out(in string key); - boolean outlist(in string key); - string get(in string key); - List getlist(in string key); - long vnum(in string key); - long vsiz(in string key); - List range(in string bkey, in boolean binc, in string ekey, in boolean einc, in long max); - List fwmkeys(in string prefix, in long max); - boolean sync(); - boolean optimize(in long lmemb, in long nmemb, - in long long bnum, in long apow, in long fpow, in long opts); - boolean vanish(); - boolean copy(in string path); - boolean tranbegin(); - boolean trancommit(); - boolean tranabort(); - string path(); - long long rnum(); - long long fsiz(); - }; - //---------------------------------------------------------------- - // the B+ tree cursor API - //---------------------------------------------------------------- - interface BDBCUR { - const long CPCURRENT = 0; - const long CPBEFORE = 1; - const long CPAFTER = 2; - boolean first(); - boolean last(); - boolean jump(in string key); - boolean prev(); - boolean next(); - boolean put(in string value, in long cpmode); - boolean out(); - string key(); - string val(); - }; -}; - - - -/* END OF FILE */ diff --git a/bacula/src/lib/tokyocabinet/tokyocabinet.pc.in b/bacula/src/lib/tokyocabinet/tokyocabinet.pc.in deleted file mode 100644 index e12d6063fb..0000000000 --- a/bacula/src/lib/tokyocabinet/tokyocabinet.pc.in +++ /dev/null @@ -1,14 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -datarootdir = @datarootdir@ -bindir=@bindir@ -libdir=@libdir@ -libexecdir=@libexecdir@ -includedir=@includedir@ -datadir=@datadir@ - -Name: Tokyo Cabinet -Description: a modern implementation of DBM -Version: @PACKAGE_VERSION@ -Libs: -L${libdir} -ltokyocabinet @LIBS@ -Cflags: -I${includedir}