Imported Upstream version 11.2
This commit is contained in:
commit
8d2a0b593e
27
AUTHORS
Normal file
27
AUTHORS
Normal file
@ -0,0 +1,27 @@
|
||||
SnapRAID AUTHORS
|
||||
================
|
||||
|
||||
The author of SnapRAID is Andrea Mazzoleni.
|
||||
|
||||
You can contact me sending an email at:
|
||||
|
||||
amadvance@gmail.com
|
||||
|
||||
Please don't send support requests at this address, but use the
|
||||
SnapRAID Forum.
|
||||
|
||||
|
||||
ACKNOWLEDGMENTS
|
||||
===============
|
||||
|
||||
Special thanks to Leifi, the king of the Forum!
|
||||
|
||||
Thanks for the testing, suggestions and bug reports to klbl,
|
||||
jwill42, tholiin, uhclem, reardonia, Jens, rubylaser and the
|
||||
whole SnapRAID Forum.
|
||||
|
||||
Thanks to Maxim Tikhonov for making the Ubuntu packages.
|
||||
|
||||
Also thanks for the support to Ben_in_COSprings, Darin, micksh, RamanRB
|
||||
and the whole AVS Forum.
|
||||
|
32
CHECK
Normal file
32
CHECK
Normal file
@ -0,0 +1,32 @@
|
||||
SnapRAID CHECK
|
||||
==============
|
||||
|
||||
The regression test of SnapRAID is run using the command:
|
||||
|
||||
make check
|
||||
|
||||
You can also run the regression test in valgrind with:
|
||||
|
||||
./configure --enable-valgrind
|
||||
make check
|
||||
|
||||
To run a coverage test you should use:
|
||||
|
||||
./configure --enable-coverage
|
||||
make lcov_reset
|
||||
make check
|
||||
make lcov_capture
|
||||
make lcov_html
|
||||
|
||||
and open the file ./cov/index.html in your browser to see the results.
|
||||
|
||||
Please note that in the coverage analysis we exclude the handling of all
|
||||
the error conditions that result in an immediate termination of the program.
|
||||
You can recognize this excluded code because it's enclosed between
|
||||
the LCOV_EXCL_START and LCOV_EXCL_STOP keywords.
|
||||
|
||||
To test with the clang static analyzer use:
|
||||
|
||||
scan-build ./configure
|
||||
scan-build make
|
||||
|
674
COPYING
Normal file
674
COPYING
Normal file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
763
HISTORY
Normal file
763
HISTORY
Normal file
@ -0,0 +1,763 @@
|
||||
SnapRAID HISTORY
|
||||
================
|
||||
|
||||
11.2 2017/12
|
||||
============
|
||||
* Fixed recognition of NTFS hardlinks. They behave differently than
|
||||
standard Unix hardlinks and this could result in SnapRAID reporting
|
||||
internal inconsistency errors for detecting links to the same file
|
||||
with different metadata attributes.
|
||||
* More efficient 'pool' command that updates only the links
|
||||
that need to be updated. This ensures that no change is
|
||||
done, avoiding to trigger a directory rescan of other programs.
|
||||
* In Linux use by default the advise "discard" mode instead of "flush".
|
||||
This avoids to swap-out the other process memory, leaving the system
|
||||
more responsive.
|
||||
* Changed the fallocate() use to work better with Btrfs with parity disks.
|
||||
* Changed the --test-io-stats screen to print the file name in process
|
||||
for each disk.
|
||||
|
||||
11.1 2017/05
|
||||
============
|
||||
* Fixed the check command to correctly ignore errors on unused parity.
|
||||
This was broken in version 9.0.
|
||||
* Allow increasing the number of parity splits of existing parity.
|
||||
* Fixed quoting when printing in Linux. This fixes the UTF-8 screen
|
||||
output. Windows version was not affected.
|
||||
* Fixed recognition of 'hashsize' in the configuration file.
|
||||
The previous incorrect 'hash_size' is still supported for backward
|
||||
compatibility.
|
||||
* Fixed building in platforms that don't provide major/minor definitions
|
||||
in sys/types.h.
|
||||
* When creating 'pool' symbolic links, set their time as the linked files.
|
||||
* Added support for the Windows 10 symbolic link unprivileged creation,
|
||||
using SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE.
|
||||
* Windows binaries built with gcc 4.9.4 using the MXE cross compiler at
|
||||
commit ae56efa2b23a793b0146508bfef33027cdb09fd2 with targets
|
||||
i686-w64-mingw32 and x86_64-w64-mingw32 and optimization -O2.
|
||||
|
||||
11.0 2016/11
|
||||
============
|
||||
* Added support for splitting the parity in multiple partitions. You
|
||||
can now specify multiple files for a single parity. As soon a file
|
||||
cannot grow anymore, the next one starts growing.
|
||||
In the configuration file, just put more files in the same 'parity'
|
||||
line, separated by , (comma).
|
||||
Note that if this feature is used, the saved content file won't be
|
||||
read by older SnapRAID versions.
|
||||
In Windows, 256 MB are left free in each disk to avoid the warning
|
||||
about full disks.
|
||||
* Added a new 'hashsize' configuration option. It could be useful in
|
||||
systems with low memory, to reduce the memory usage.
|
||||
Note that if this feature is used, the saved content file won't be
|
||||
read by older SnapRAID versions.
|
||||
* In Linux added the missing support for Btrfs file-systems. Note that
|
||||
to have full support you need also the 'libblkid' library, otherwise
|
||||
you won't get the UUIDs.
|
||||
* In screen messages don't print the disk directory in file path. You
|
||||
can control the format with the test option:
|
||||
--test-fmt file|disk|path.
|
||||
* In Windows allows to use the escape char '^' to handle file patterns
|
||||
containing real characters matching the globbing '*?[]' ones. In Unix
|
||||
it was already possible to do the same escaping with '\'.
|
||||
* Added a new -R, --force-realloc option to reallocate all the
|
||||
parity information keeping the precomputed hash.
|
||||
This is the previous -F, --force-full that instead now maintains the
|
||||
same parity organization and just recomputes it.
|
||||
* Added test options for selecting the file advise mode to use:
|
||||
--test-io-advise-none for standard mode
|
||||
--test-io-advise-sequential advise sequential access (Linux/Windows)
|
||||
--test-io-advise-flush flush cache after every operation (Linux)
|
||||
--test-io-advise-flush-window flush cache every 8 MB (Linux)
|
||||
--test-io-advise-discard discard cache after every operation (Linux)
|
||||
--test-io-advise-discard-window discard cache every 8 MB (Linux)
|
||||
--test-io-advise-direct use direct/unbuffered mode (Linux/Windows)
|
||||
The new default mode is 'flush' in Linux (before it was 'sequential'),
|
||||
and 'sequential' in Windows (like before).
|
||||
* For Seagate SMR (Shingled Magnetic Recording) ignore the SMART
|
||||
attribute Command_Timeout 188 as not reliable.
|
||||
* Fixed running in Windows platforms that miss the RtlGenRandom()
|
||||
function.
|
||||
* Added the --test-io-cache=1 option to disable the multi-thread IO
|
||||
mode.
|
||||
|
||||
10.0 2016/02
|
||||
============
|
||||
* Boosts the speed of the 'sync' and 'scrub' commands with a new
|
||||
multi-thread implementation. It uses one thread for each disk,
|
||||
dedicated exclusively to read-ahead data and parity and to
|
||||
write-behind parity. This maximizes the data throughput keeping
|
||||
disks always busy.
|
||||
You can control the number of blocks to cache with the option
|
||||
--test-io-cache=NUMBER, where the number is between 3 and 128.
|
||||
The default is 8 MiB of blocks.
|
||||
You can show run-time stats during the process with the
|
||||
--test-io-stats option. You will see a graph with the number of
|
||||
cached blocks, and a graph with the wait time percentage for all the
|
||||
disks and computations.
|
||||
* The -h, --pre-hash command, saves the content file only after having
|
||||
verified all the hashes. This allows recovering of moved files in
|
||||
case a silent error is found during the hash verification check.
|
||||
* Allows to use the -d, --filter-disk option in the 'up' and 'down'
|
||||
commands.
|
||||
* Allows to run the 'smart' command without a configuration file.
|
||||
In such case it operates on all the disks of the machine.
|
||||
* In the configuration file 'data' is now a synonymous of 'disk'.
|
||||
* Adds the 'touch' command intended to arbitrarily set all the zero
|
||||
sub-second timestamps. This improves the SnapRAID capabilities to
|
||||
identify files. The 'status' command recommends to run 'touch' if
|
||||
required.
|
||||
* Restores the functionality of the -D, --force-device option when used
|
||||
to workaround the use of the same disk for two logical data drives
|
||||
when running the 'fix' command.
|
||||
* Uses a correct shell quoting in the example commands that involve
|
||||
files.
|
||||
* The minimum Windows version supported is now Windows Vista. This is
|
||||
required to use the native Windows thread support for the new
|
||||
multi-thread implementation. If you need to run on Windows XP, you
|
||||
have to stick on SnapRAID 9.x.
|
||||
|
||||
9.3 2016/01
|
||||
===========
|
||||
* Fixes an invalid assumption in the copy detection mechanism that
|
||||
could result in an internal inconsistency, and with the impossibility
|
||||
to run the 'sync' and 'diff' commands.
|
||||
This was triggered by a very specific pattern of identical files.
|
||||
At least three of them, with one already in the parity, and at a
|
||||
higher disk number than the others that should be instead new ones.
|
||||
This had no bad effect, if not preventing the 'sync' command to run.
|
||||
A workaround was to just run 'sync' one time with the -N,
|
||||
--force-nocopy option to disable the copy detection.
|
||||
* Restored the -O2 optimization option for Windows binaries, as -Og has
|
||||
a too big performance penality.
|
||||
|
||||
9.2 2016/01
|
||||
===========
|
||||
* Fixes support for symlinks pointing to an empty target. Before they
|
||||
were only partially supported, and their presence could result in a
|
||||
content file not readable.
|
||||
This also disables multi-thread content write, as this was the issue
|
||||
we tried to detect with this feature, and it doesn't provide a
|
||||
performance advantage. Content verification is instead still multi
|
||||
thread.
|
||||
* Autorename disks using the matching UUID. To rename a disk you can
|
||||
now change directly the name in the configuration file, and run a
|
||||
'sync' command.
|
||||
* Improves the physical offset ordering for the Btrfs file-system,
|
||||
correctly detecting files that have not a physical offset, for
|
||||
whatever reason.
|
||||
* Adds UUID support to Btrfs file-systems. It's present only if the
|
||||
'libblkid' development library is available on the system.
|
||||
Usually this requires to install the libblkid-dev or libblkid-devel
|
||||
package.
|
||||
* Added a new --no-warnings option to disable some repetitive warnings
|
||||
that could be annoying to power users.
|
||||
* Improves the error reporting, printing a complete stack trace, that
|
||||
can be used to track down bugs more easily.
|
||||
For this reason the Windows binaries are now built with optimization
|
||||
option -Og, instead than -O2.
|
||||
|
||||
9.1 2015/11
|
||||
===========
|
||||
* Fixes a bug when reading a content file with a deleted entry bigger
|
||||
than 4 GB. This was a regression introduced in version 9.0 that could
|
||||
result in the impossibility to read a valid content file, after a
|
||||
deletion of a file bigger than 4 GB in the array.
|
||||
If this happened to you, just upgrading to 9.1 fixes the issue, and
|
||||
it allows you to continue to work.
|
||||
Note that this bug only prevented to run 9.0, but your data was still
|
||||
protected and could have been recovered using the versions 8.1 or
|
||||
9.1.
|
||||
* In Windows disables the file zero check requiring the --force-zero
|
||||
option. This check is intended for possible case using ext3/4 in
|
||||
Linux, and there is no evidence that in Windows it's possible at all.
|
||||
* Windows binaries built with gcc 4.9.3 using the MXE cross compiler at
|
||||
commit 62bcdbee56e87c81f1faa105b8777a5879d4e2e with targets
|
||||
i686-w64-mingw32 and x86_64-w64-mingw32 and optimization -O2.
|
||||
|
||||
9.0 2015/11
|
||||
===========
|
||||
* Fixes an invalid assumption that could happen when using the -e,
|
||||
--filter-error option with "fix" or "check".
|
||||
This was triggered by a very specific pattern of fragmented files
|
||||
and bad blocks combination, not so easy to reproduce.
|
||||
This had no bad effect, if not preventing the command to run.
|
||||
* Drastically reduces the memory usage. For each block, it now uses 17
|
||||
bytes of memory, instead of the previous 28 bytes (for 32 bit) or 36
|
||||
bytes (for 64 bit).
|
||||
This could result is a memory saving of up the 50%.
|
||||
* The -p, --plan option (old --percentage) can be used to define a
|
||||
scrub plan: "new", "bad" and "full".
|
||||
The "new" plan scrubs all the new synced blocks not yet scrubbed.
|
||||
This allows to verify as early as possible that the written parity
|
||||
during sync is really correct. You can use the "status" command to
|
||||
show the amount blocks not yet scrubbed.
|
||||
The "bad" plan scrubs only bad blocks.
|
||||
The "full" plan scrubs all blocks.
|
||||
* The graph in the "status" command now show scrubbed blocks with '*',
|
||||
and synced, but not yet scrubbed, blocks with 'o'.
|
||||
Note that when upgrading from a previous version, all blocks are
|
||||
assumed scrubbed the first time.
|
||||
* Content files are now written asynchronously from different threads
|
||||
to avoid the unfortunate condition that a memory error affects all of
|
||||
them in the same way.
|
||||
After writing, they are read again to verify their CRC.
|
||||
This is done to ensure that they are really OK, even in the case of
|
||||
the worst possible silent errors.
|
||||
* Extends the -D, --force-device option to ignore more erroneous
|
||||
conditions in the 'fix' command, like inaccessible disks, or disks
|
||||
sharing the same physical device.
|
||||
* Extends the -d, --filter-disk option to allow to filter also by
|
||||
parity disk.
|
||||
* Extends the -h, --pre-hash option to also verify moved and copied
|
||||
files into the array before running a 'sync'.
|
||||
* Updates 'best' RAID functions for recent Atom CPUs.
|
||||
* Validates filters specifications rejecting relative paths.
|
||||
|
||||
8.1 2015/05
|
||||
===========
|
||||
* Fixes build issues in generic Unix platforms, including Mac OS X.
|
||||
* The "diff" command returns with error code 2 if a "sync" is required,
|
||||
to differentiate with the generic error code 1.
|
||||
* Reduces the effect of SMART attribute 193 on the failure probability
|
||||
to avoid some false positive reports.
|
||||
|
||||
8.0 2015/04
|
||||
===========
|
||||
* Allows "sync" and "scrub" to continue after the first bunch of disk
|
||||
errors. Blocks with errors are marked as bad, and you can fix them
|
||||
with the "fix -e" command.
|
||||
The fix is expected to force the disk firmware to reallocate the
|
||||
bad sector, likely fixing the problem.
|
||||
You can control the number of allowed errors with the new
|
||||
-L, --error-limit option. The default is 100.
|
||||
* The -e, --filter-error option doesn't write anymore fixes to
|
||||
unsynced files. This helps in case you are running it on a not
|
||||
synced array, removing the risk to revert some files to an old state.
|
||||
* The -e, --filter-error option is now optimal and reads only the
|
||||
minimal amount of data necessary to fix the errors.
|
||||
* The "diff" command returns with an error code if a "sync" is
|
||||
required.
|
||||
* Adds new "smart" command to print a SMART report of the array.
|
||||
* Adds new "up" and "down" commands to spin up and down the disks of
|
||||
the array.
|
||||
* Adds new "devices" command to print the devices associations in the
|
||||
array.
|
||||
* Changes the log handling. If no log file is specified, all the
|
||||
warnings and not fatal errors messages goes to stderr. If a log file
|
||||
is specified, only fatal error messages are printed on the screen.
|
||||
You can control the amount of informative messages on stdout with
|
||||
the -q, --quiet and -v, --verbose options, that can be specified
|
||||
multiple times to be more quiet or verbose.
|
||||
* In the "status" command the "Wasted" column now shows a negative
|
||||
number for the amount of space that you can still waste without
|
||||
filling up the parity.
|
||||
* In the "status" and others commands we now use GB instead of GiB,
|
||||
when referring to disk space.
|
||||
* Renames the -s and -t options to -S and -B as they are intended to
|
||||
be manual only operations.
|
||||
* Windows binary built with gcc 4.8.1 using the MXE cross compiler
|
||||
2.23, with targets i686-w64-mingw32 and x86_64-w64-mingw32. Before
|
||||
the x86 target was i686-pc-mingw32.
|
||||
|
||||
7.1 2015/01
|
||||
===========
|
||||
* In 'scrub' and 'sync' detects and reports Input/Output errors
|
||||
separately from generic file system errors.
|
||||
* In 'diff' doesn't print the "add" entry if a "copy" one is already
|
||||
printed.
|
||||
* Fixes build with old compilers in the x64 platforms [Leigh Phillips].
|
||||
* Fixes out-of-dir builds [Christoph Junghans].
|
||||
|
||||
7.0 2014/11
|
||||
===========
|
||||
* In 'check' and 'fix' the array is scanned to find any moved files
|
||||
that could be used to recover missing data. Files are identified by
|
||||
time-stamp, and then they are recognized also if moved to a different
|
||||
disk. Note that even if there are false positive they are identified
|
||||
checking the hash, so they have not effect, besides making the
|
||||
process a little slower. To disable this new behavior you can use
|
||||
the -N, --force-nocopy option.
|
||||
* The -i, --import command now identifies files by time-stamp making it
|
||||
very fast in importing directories.
|
||||
* More detailed 'status' report with single disk stats and free space
|
||||
available.
|
||||
* A lot faster directory listing for Windows.
|
||||
* Adds AVX2 support to improve parity generation speed.
|
||||
* Prints the time spent waiting for each disk also in 'scrub'.
|
||||
* The CPU usage, speed and ETA estimations are now based on the last
|
||||
100 seconds rather than from the start.
|
||||
* Keeps track of the UUID of the parity disks to check them before
|
||||
operating.
|
||||
* Windows binary built with gcc 4.8.1 using the MXE cross compiler
|
||||
2.23.
|
||||
|
||||
6.4 2014/11
|
||||
===========
|
||||
* Adds support for the new binary format of SnapRAID 7.0.
|
||||
This allows to downgrade from version 7.0 to 6.x or previous.
|
||||
|
||||
6.3 2014/7
|
||||
==========
|
||||
* The -N, --force-nocopy option now also works if you used previously
|
||||
"sync" commands without it.
|
||||
* In 'sync' keeps stats about the amount of time spent waiting for each
|
||||
disk and what is spent in CPU computation.
|
||||
* Auto exclude the lock file.
|
||||
* A more precise counting of how may block to scrub. Now it's exact
|
||||
regardless the order of the blocks timing.
|
||||
* Don't prints the 'UUID set' message anymore because it's the normal
|
||||
condition for empty disks.
|
||||
* In Windows, if the disk doesn't support reading physical offsets,
|
||||
allows SnapRAID to continue anyway.
|
||||
* Added a new -F, --force-full option that forces a full sync reusing
|
||||
the hash data present in the content file.
|
||||
|
||||
6.2 2014/5
|
||||
==========
|
||||
* Fixed the regression test when run as root.
|
||||
* Added a new heuristic to detect file copies. Now a file is assumed
|
||||
to be a copy if name, size and nanosecond time-stamp are matching,
|
||||
but if the nanosecond part of the time-stamp is 0, it requires
|
||||
the full path matching and not only the name.
|
||||
* Added the -N, --force-nocopy option to disable completely the copy
|
||||
detection. SnapRAID also suggests to use this option in the error
|
||||
message of a data mismatch if likely caused by the copy detection.
|
||||
|
||||
6.1 2014/4
|
||||
==========
|
||||
* Fixed build and regression test in Mac OS X.
|
||||
|
||||
6.0 2014/3
|
||||
==========
|
||||
* In "sync", even if a silent error is found, continue to update the
|
||||
parity if it's possible to correct the error.
|
||||
Note that the block will be marked bad, and the data will be fixed
|
||||
only at the next "fix -e" call.
|
||||
But any new data added will be protected if you are using enough
|
||||
parity to fix both the silent error and at least another potential
|
||||
error.
|
||||
* Detect copied files from one disk to another and reuse the already
|
||||
computed hash information to validate them in "sync".
|
||||
Files are assumed copied if they matches the name, size and
|
||||
time-stamp.
|
||||
* For "sync", added a new -h, --pre-hash option to run a preliminary
|
||||
hashing step for all the new files to ensure to detect silent errors
|
||||
caused by the heavy machine usage of the parity computation.
|
||||
* In "fix", if a previous fixing attempt was made resulting in a
|
||||
.unrecoverable file, uses this file as starting point for the
|
||||
new attempt.
|
||||
* In the log file name allows the use of the '>>', %D, %T modifiers
|
||||
to select append mode, and to insert the date and time in the name.
|
||||
* The options -p, --percentage and -o, --older-than now keep their
|
||||
default value even if the other one is specified.
|
||||
* Moved the .lock file in the same dir of the first specified content
|
||||
file. This avoid to spin-up the parity disks in all commands.
|
||||
* The "diff", "list", "dup", "status" and "pool" commands don't access
|
||||
anymore the parity disks that can now stay powered down.
|
||||
* The default configuration file in Windows is now searched in the same
|
||||
directory where the snapraid.exe file resides.
|
||||
* New source code organization. The RAID engine is now an external
|
||||
component usable also in other projects.
|
||||
|
||||
5.3 2014/3
|
||||
==========
|
||||
* Don't warn about UUID changed if it's for an empty disk.
|
||||
* Fixed the number of blocks that scrub has to process when
|
||||
selecting a high percentage of the array.
|
||||
* Removed duplicate recovery attempts in synced state.
|
||||
|
||||
5.2 2013/12
|
||||
===========
|
||||
* If a disk changes UUID, automatically disable the inode
|
||||
recognition, because this is likely a new file-system with
|
||||
all the inodes reassigned, and we don't want to risk a false
|
||||
positive when searching for inode/time-stamp/size.
|
||||
* Allow to run a fix command with disks that doesn't need to be
|
||||
fixed mounted as read-only.
|
||||
* After a failed sync, always reallocates new files with a not
|
||||
yet computed parity to ensure to minimize the parity usage,
|
||||
if some other file is deleted in the meantime.
|
||||
* Doesn't count empty dirs as files in the diff counters.
|
||||
* Added a new "share" configuration option to allow to share
|
||||
in the network the pool directory also in Windows.
|
||||
* Fixed build problems in OpenBSD due the old assembler.
|
||||
* Fixed build problems in platforms different than x86.
|
||||
|
||||
5.1 2013/12
|
||||
===========
|
||||
* Fixed a potential crash if a file is deleted during a "sync/scrub".
|
||||
This is a problem introduced in version 5.0 due new logging.
|
||||
If happened to you to have a crash in sync, you don't need to take
|
||||
any special action, just run "sync" again.
|
||||
* Restored the functionality of -C, --gen-conf command.
|
||||
* Prints the files with duplicate physical offset if the -v, --verbose
|
||||
option is specified.
|
||||
|
||||
5.0 2013/11
|
||||
===========
|
||||
* Added support for up to six levels of parity.
|
||||
* Added a specific and faster triple parity format for CPUs that
|
||||
don't support SSSE3 instructions like ARM and AMD Phenom, Athlon
|
||||
and Opteron.
|
||||
* Faster RAID5 and RAID6 implementation for ARM 64 bit CPUs.
|
||||
* If a silent error is found during a "sync" command, directly marks
|
||||
the block as bad like in "scrub", without stopping the the "sync"
|
||||
process.
|
||||
* Sort files by inode when listing the directory. This improves
|
||||
the scanning performance.
|
||||
* For files with changes only in some blocks, updates the parity
|
||||
only for blocks that really are changed.
|
||||
This improves the performance in sync for modified files.
|
||||
* Added a new "list" command to see the stored list of files.
|
||||
* Removed the detailed list of errors from the screen output.
|
||||
To get it you must explicitly use the -l, --log option.
|
||||
It's now too detailed for the screen, because it contains a lot
|
||||
of info.
|
||||
* Changed the output format of some commands to make it similar
|
||||
at the new "list" one.
|
||||
* Reduced memory usage removing some unnecessary allocations.
|
||||
* Added a memory test on the memory buffers used in sync, scrub, check,
|
||||
fix before using them.
|
||||
|
||||
4.4 2013/10
|
||||
===========
|
||||
* Relaxed the check about small parity files, to allow to recover after
|
||||
a failed sync before resizing the parity files.
|
||||
|
||||
4.3 2013/10
|
||||
===========
|
||||
* Fixed the scrub command with the -p0 option. Now it really scrubs
|
||||
only the blocks marked as bad and not the full array.
|
||||
|
||||
4.2 2013/10
|
||||
===========
|
||||
* Fixed the wrong warning about physical offsets not supported caused
|
||||
by files not having a real offset because too small.
|
||||
For example, in NTFS it's possible to store such files in the MFT.
|
||||
It's just a cosmetic change, and not a functional one.
|
||||
* Remove unexpected 'Restore' entries in the diff output when dealing
|
||||
with file-system without persistent inodes like NTFS in Linux.
|
||||
* Added support for filenames containing newlines. This happens in Mac
|
||||
OS X.
|
||||
|
||||
4.1 2013/9
|
||||
==========
|
||||
* If the underline file-system doesn't support the FIEMAP command,
|
||||
automatically fall back to use FIBMAP for sorting files.
|
||||
* Fixed the import of content files from previous version of SnapRAID
|
||||
that are the result of an incomplete sync.
|
||||
* Added a new -C, --gen-conf option to generate a dummy configuration
|
||||
file from the info in the content file.
|
||||
Just in case that you lose everything, except the content file.
|
||||
* At the end of sync/scrub/check/fix prints "Everything OK" if no error
|
||||
was found. This should make clear that everything is really OK.
|
||||
|
||||
4.0 2013/9
|
||||
==========
|
||||
* New 'scrub' command to periodically check the oldest blocks for
|
||||
silent errors without the need to scan the whole array.
|
||||
* New 'status' command to check the fragmentation, the last check time
|
||||
distribution, and the silent error status of the array.
|
||||
* Added the new Spooky hash. It's faster in 64 bit architectures.
|
||||
To convert you can use the new 'rehash' command.
|
||||
* Changed to a binary content file to improve speed and reduce size.
|
||||
* Removed the --find-by-name, -N option. Now it always searches
|
||||
by name if a file is not found searching by inode, automatically
|
||||
reassigning inodes in restored files without needing to sync
|
||||
again the file.
|
||||
This happens only if the file has the same path, size and timestamp
|
||||
at nanosecond precision.
|
||||
* Added a hash seed to make harder intentional collision attacks.
|
||||
* When inserting files for the first time, sort them by their physical
|
||||
address to improve read performance.
|
||||
* Optimized the cache use for the all the RAID computations.
|
||||
This improves a lot the RAID performance.
|
||||
* Better selection of the RAID6 implementation for different CPUs.
|
||||
* Added RAID5/RAID6 mmx and sse2 implementations with unrolling by 4.
|
||||
They are a little faster than the previous unroll by 2.
|
||||
* Added a lock file to avoid multiple running instances on the same
|
||||
array. The file is named as parity file adding the .lock extension.
|
||||
There is also the undocumented --test-skip-lock to avoid to check it.
|
||||
* Automatically ignores, with warning, mount points inside the array
|
||||
directory tree.
|
||||
* Changes the 'dup' output format to include the size of each duplicate
|
||||
file.
|
||||
|
||||
3.2 2013/7
|
||||
==========
|
||||
* Fixed a directory creation problem in Windows when the "disk" option
|
||||
points to the root directory of a drive. Now SnapRAID won't complain
|
||||
about the inability to create such directory.
|
||||
If you encounter this problem when trying to recover your data, just
|
||||
upgrade to this version, and you'll be able to complete the
|
||||
recovering process.
|
||||
No need to upgrade for platforms different than Windows.
|
||||
|
||||
3.1 2013/5
|
||||
==========
|
||||
* Direct use of Windows API for disk access to improve error reporting.
|
||||
* If the 'fix' process is aborted, it removes all the new files
|
||||
partially recovered, to allow to reuse again the -m, --filter-missing
|
||||
flag.
|
||||
* In Windows don't exclude anymore system files. Only system
|
||||
directories are excluded.
|
||||
* In Windows applies filters in case insensitive way.
|
||||
* The Windows binaries are now built with gcc 4.7.2.
|
||||
* Reduced memory occupation for hardlinks and directories.
|
||||
* In 'dup' don't list files with 0 size.
|
||||
|
||||
3.0 2013/3
|
||||
==========
|
||||
* Added pooling support with the new 'pool' command. It creates a
|
||||
virtual view of the array using symbolic links pointing to the
|
||||
original files.
|
||||
* Added a new -m, --filter-missing option that allow to undelete files,
|
||||
without checking/fixing the others.
|
||||
* Added a new -i, --import option to automatically import deleted files
|
||||
when fixing.
|
||||
* Added a new -l, --log option to save to disk the detailed log.
|
||||
* Added support for hardlinks and empty directories.
|
||||
* Added support to save symlinks to files in Windows. Note that only
|
||||
the symlink is saved and not the linked file.
|
||||
Note that Windows Symlinks to dirs and junctions are still not
|
||||
supported.
|
||||
* Files without read permission generate an error instead of a warning.
|
||||
You now must explicitly exclude them in the configuration file with
|
||||
exclusion rules.
|
||||
* In 'check' and 'fix', if verbose is enabled, prints the result for
|
||||
each processed file.
|
||||
* Added an UUID check to detect when a disk is replaced, and to prevent
|
||||
unwanted disk swaps.
|
||||
|
||||
2.1 2013/1
|
||||
==========
|
||||
* Checks for wrong empty fields in the configuration file.
|
||||
* Filter rules for files are not anymore applied to directories.
|
||||
|
||||
2.0 2012/12
|
||||
===========
|
||||
* Added a new -a option to make the 'check' command to only check file
|
||||
hashes without checking the parity data.
|
||||
* Added a new -d option to filter by disk name.
|
||||
* The file modification time is now saved using nanosecond precision.
|
||||
This allows to restore the exact modification time in 'fix'.
|
||||
The new 'content' files written with this version are not backward
|
||||
compatible, but it's still possible to read the old format.
|
||||
* Fixed hard-links automatic exclusion. All the hardlinks after the
|
||||
first one are now correctly ignored.
|
||||
* If it isn't possible to grow a parity file, prints the list of files
|
||||
outside the maximum size allocated.
|
||||
* Autosave isn't triggered if we are near the end of the 'sync'
|
||||
process.
|
||||
* Before starting a 'sync', we wait for two seconds, to workaround the
|
||||
FAT limitation of having two seconds modification time precision.
|
||||
This a safe measure to be 100% sure to always detect file changes.
|
||||
* Always fill the memory after allocating it to avoid the OOM (Out Of
|
||||
Memory) killer in Linux.
|
||||
* Fixed compilation in Solaris/OpenIndiana for lacking both futimes()
|
||||
and futimens().
|
||||
* Now 'sync' ensures that the parity files are not too small to contain
|
||||
the just loaded data.
|
||||
* Removed the '-H,--filter-nohidden' option. It doesn't make sense to
|
||||
have it as command line option.
|
||||
You must use the 'nohidden' option in the configuration file.
|
||||
* When opening files in read-only mode, also specify the noatime flag,
|
||||
to avoid to update the file access time.
|
||||
* Exclude rules for files are now also applied to directories.
|
||||
This allows to excludes some file/directory without the need to call
|
||||
the stat() function on them.
|
||||
* The -N, --find-by-name option also ignores the nanosecond part of
|
||||
timestamps to work with copy programs not supporting nanoseconds.
|
||||
* Fixed deduplicated files handling in Windows Server 2012.
|
||||
* Removed MD5 support.
|
||||
|
||||
1.13 2012/11
|
||||
============
|
||||
* Fixed a Segmentation Fault when checking/fixing if there are three
|
||||
or more errors in a specific block.
|
||||
|
||||
1.12 2012/9
|
||||
===========
|
||||
* Fixed file renaming in Windows during a 'fix' command.
|
||||
This is only a Windows only issue, no reason to upgrade for other
|
||||
platforms.
|
||||
|
||||
1.11 2012/7
|
||||
===========
|
||||
* Fixed again directories inclusion. Exclusion rules for directories
|
||||
were ignored.
|
||||
|
||||
1.10 2012/6
|
||||
===========
|
||||
* Fixed directory inclusion, in case the last rule is an "include" one.
|
||||
* Fixed very long paths in Windows. We now always use the special '\\?'
|
||||
prefix to remove the 260 chars limitation.
|
||||
* If a file is excluded, it prints explicitly which attribute caused
|
||||
the exclusion.
|
||||
* Automatically excludes also the temporary copy of content file,
|
||||
the one with the ".tmp" extension.
|
||||
* Avoid Windows to go in automatic sleep mode when running.
|
||||
|
||||
1.9 2012/3
|
||||
==========
|
||||
* Implemented a more sophisticated recovering in case a harddisk
|
||||
failure happens during a 'sync' command.
|
||||
When using RAID6 it improves the chances of recovering data with
|
||||
partially computed parity, after an aborted 'sync'.
|
||||
* Fixed the count of new files.
|
||||
* Added a new 'autosave' configuration option to save the intermediate
|
||||
'sync' state.
|
||||
* Supported file-systems with read requests returning less data than
|
||||
requested.
|
||||
* In Windows ensures that the disk serial number is not zero.
|
||||
|
||||
1.8 2012/1
|
||||
==========
|
||||
* Added a new "dup" command to find all the duplicate files.
|
||||
* Added a new option "--filter-nohidden" to exclude hidden files.
|
||||
* Faster and parallel writing of content files.
|
||||
* The example configuration files now put the content files in the data
|
||||
disks instead than in the parity disks.
|
||||
* Added a checksum at the content file to ensure its integrity.
|
||||
* Using fallocate() instead posix_fallocate() to avoid the very slow
|
||||
posix_fallocate() fall back of writing the whole file.
|
||||
|
||||
1.7 2011/11
|
||||
===========
|
||||
* If a file is modified or removed during a sync, the sync process
|
||||
doesn't stop anymore, but it will simply skip the file, resulting in
|
||||
an incomplete sync. Note that the sync will terminate with an error.
|
||||
* If the content file is placed in a data disk, it's automatically
|
||||
excluded from the sync process.
|
||||
* Increased by one the minimum number of content files. Before it was
|
||||
only a suggestion, but now it's a requirement because you are allowed
|
||||
to put content files in data disks.
|
||||
* Added checks to ensure that data and parity disks are different, and
|
||||
to correctly count the number of copies of "content" files in
|
||||
different disks.
|
||||
* Removed the dependency of the "disk" order specification in the
|
||||
configuration file. The used order is now saved in the content file
|
||||
to avoid to damage the dual parity in case the order is changed by
|
||||
the user. It easily allows to remove or add disks from the array when
|
||||
using a dual parity.
|
||||
* Improved the "fix" performance when a lot of files or the parity have
|
||||
to be recreated from scratch.
|
||||
* When getting unrecoverable errors, the printed log line now starts
|
||||
with "unrecoverable:" instead of "error:" to allow an easier
|
||||
identification.
|
||||
* Added a new option "--find-by-name" to allow to sync using only the
|
||||
file path and not the inode. This is useful to avoid long sync when
|
||||
you replace one disk with another copying manually the files.
|
||||
* If "fix" cannot recover a file, it's renamed adding the
|
||||
".unrecoverable" extension.
|
||||
* Checking and fixing also empty files with size 0.
|
||||
|
||||
1.6 2011/9
|
||||
==========
|
||||
* The content file is now saved also at the start of the "sync"
|
||||
command. This avoids parity errors if the sync process is aborted
|
||||
without saving the content file and you made changes at the disk
|
||||
array before another "sync" command was done.
|
||||
More specifically, deletions or truncations of not yet synced files
|
||||
after the aborted sync, and before the next sync command, may have
|
||||
damaged the parity data. New file additions were instead safe.
|
||||
If these conditions may have happened to you a "check" command (also
|
||||
with older version of the program) is recommended to ensure the
|
||||
correctness of your parity data.
|
||||
* The "diff" command now recognizes the reuse of inodes.
|
||||
* Windows hidden files are now saved like any other files.
|
||||
* Symbolic links are now saved in *nix. Not supported in Windows.
|
||||
* The "fix" command restores also the original modification time.
|
||||
* The message asking to use the --force-empty option now lists all the
|
||||
empty disks.
|
||||
|
||||
1.5 2011/7
|
||||
==========
|
||||
* Ignores extra spaces in the configuration file.
|
||||
* Changed the output of check/fix to allow a more easy post-processing
|
||||
with other tools like awk and sort.
|
||||
* Added the hidden option -G/--gui to enable the output of progress
|
||||
information for a potential GUI for SnapRAID.
|
||||
* Added a new "diff" command to print the list of changes detected at
|
||||
file level.
|
||||
* Faster loading of content file. Approx three times faster.
|
||||
|
||||
1.4 2011/6
|
||||
==========
|
||||
* Ignoring in sync System and Hidden files in Windows.
|
||||
* Files without read permission are ignored in sync.
|
||||
* If a file is ignored a warning message is printed. You have to
|
||||
exclude it to remove the warning.
|
||||
* In fixing, if a file cannot be written for missing permission, an
|
||||
error is reported only if a write is effectively required.
|
||||
* Ignores any symbolic links. They are not saved.
|
||||
|
||||
1.3 2011/5
|
||||
==========
|
||||
* Fixed the restore of directory with unicode chars in Windows.
|
||||
* Fixed support of file names starting or ending with a space.
|
||||
* Removes files before inserting new ones to minimize the parity size.
|
||||
|
||||
1.2 2011/5
|
||||
==========
|
||||
* Fixed use of file names out of the codepage in Windows. All the names
|
||||
are now stored in UTF8 in the content file.
|
||||
|
||||
1.1 2011/5
|
||||
==========
|
||||
* Fixed a bug in the check command when detecting garbage data over the
|
||||
expected end of the file.
|
||||
The parity data was anyway computed correctly, and no special action
|
||||
is required to update.
|
||||
* Changed the default checksum to Murmur3 hash. It's a lot faster than
|
||||
MD5. You can check its speed with the "snapraid -T" command.
|
||||
MD5 is still supported for backward compatibility.
|
||||
To convert to the new Murmur3 hash, simply remove the 'content' file,
|
||||
and start a new complete 'sync'.
|
||||
* Added RAID6 support. It's used the very good RAID6 library made by H.
|
||||
Peter Anvin also used in the Linux Kernel. It contains optimized
|
||||
implementations for SSE2 and MMX.
|
||||
* Added support for multiple 'content' files. You can save extra copies
|
||||
to be able to verify the checksums also if you lose all the 'content'
|
||||
files in the parity disks.
|
||||
* Added a filtering include logic, where anything not explicitly
|
||||
included is excluded. For example, it allow to include only the files
|
||||
in a predefined set of directories.
|
||||
* The check command returns with an error code if any kind of error is
|
||||
present. Previously it was returning an error only if unrecoverable
|
||||
errors were present.
|
||||
* Opening the files in sequential mode in Windows. This should give a
|
||||
speedup in Windows.
|
||||
* In Windows you can use the backslash \ in the filter definitions
|
||||
instead of the forward slash /.
|
||||
|
||||
1.0 2011/4
|
||||
==========
|
||||
* No relevant change.
|
||||
|
||||
0.4 2011/4
|
||||
==========
|
||||
* Added hidden 'dry' command mainly for speed measurement.
|
||||
* As default, uses the OpenSSL crypto MD5 implementation.
|
||||
|
||||
0.3 2011/4
|
||||
==========
|
||||
* Added --filter option to select a subset of file in check and fix.
|
||||
* Better ETA estimation in all the commands.
|
||||
* Added support for OpenSSL crypto library to use its optimized MD5
|
||||
implementation.
|
||||
* Added test vectors and a speed test for MD5.
|
||||
|
||||
0.2 2011/3
|
||||
==========
|
||||
* Second public test release of SnapRAID.
|
||||
* Functionally complete in check and fix.
|
||||
* Files are identified by inode and not anymore by name.
|
||||
* Exclusion list of files and directories.
|
||||
* Precise error management.
|
||||
* More regression tests.
|
||||
|
||||
0.1 2011/3
|
||||
==========
|
||||
* First public test release of SnapRAID.
|
31
INSTALL
Normal file
31
INSTALL
Normal file
@ -0,0 +1,31 @@
|
||||
SnapRAID INSTALL
|
||||
================
|
||||
|
||||
To build and install SnapRAID you need to download the source
|
||||
code from http://www.snapraid.it and unpack it with:
|
||||
|
||||
tar xf snapraid-*.tar.gz
|
||||
cd snapraid-*
|
||||
|
||||
To configure and build run:
|
||||
|
||||
./configure
|
||||
make
|
||||
|
||||
To check for correctness of the application run:
|
||||
|
||||
make check
|
||||
|
||||
If it terminates with "Success", you can install the application and
|
||||
the documentation running as root:
|
||||
|
||||
sudo make install
|
||||
|
||||
To start using SnapRAID you have to change the example configuration
|
||||
file snapraid.conf.example to fit your needs and copy it in /etc/snapraid.conf
|
||||
|
||||
To get more help, see the "Getting Started" section in the snapraid manpage
|
||||
typing:
|
||||
|
||||
man snapraid
|
||||
|
9
INSTALL.windows
Normal file
9
INSTALL.windows
Normal file
@ -0,0 +1,9 @@
|
||||
SnapRAID INSTALL for Windows
|
||||
============================
|
||||
|
||||
To start using SnapRAID you have to change the example configuration
|
||||
file snapraid.conf.example to fit your needs and copy it with the
|
||||
name snapraid.conf in the directory where you run snapraid.exe.
|
||||
|
||||
To get more help, see the "Getting Started" section in snapraid.txt.
|
||||
|
1039
Makefile.am
Normal file
1039
Makefile.am
Normal file
File diff suppressed because it is too large
Load Diff
1934
Makefile.in
Normal file
1934
Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
32
README
Normal file
32
README
Normal file
@ -0,0 +1,32 @@
|
||||
SnapRAID
|
||||
========
|
||||
|
||||
SnapRAID is a backup program for disk arrays. It stores parity
|
||||
information of your data and it recovers from up to six disk
|
||||
failures.
|
||||
|
||||
SnapRAID is mainly targeted for a home media center, where you
|
||||
have a lot of big files that rarely change.
|
||||
|
||||
Beside the ability to recover from disk failures, the other
|
||||
features of SnapRAID are:
|
||||
|
||||
* All your data is hashed to ensure data integrity and to avoid
|
||||
silent corruption.
|
||||
* If the failed disks are too many to allow a recovery,
|
||||
you lose the data only on the failed disks.
|
||||
All the data in the other disks is safe.
|
||||
* If you accidentally delete some files in a disk, you can
|
||||
recover them.
|
||||
* You can start with already filled disks.
|
||||
* The disks can have different sizes.
|
||||
* You can add disks at any time.
|
||||
* It doesn't lock-in your data. You can stop using SnapRAID at any
|
||||
time without the need to reformat or move data.
|
||||
* To access a file, a single disk needs to spin, saving power and
|
||||
producing less noise.
|
||||
|
||||
The official site of SnapRAID is:
|
||||
|
||||
http://www.snapraid.it/
|
||||
|
360
TODO
Normal file
360
TODO
Normal file
@ -0,0 +1,360 @@
|
||||
SnapRAID TODO
|
||||
=============
|
||||
|
||||
This is the list of TODO items for SnapRAID.
|
||||
|
||||
- Next
|
||||
|
||||
- Minor
|
||||
|
||||
* Add a new -u, --filter-updated command that filters files
|
||||
with a different timestamp, to be able to restore only them to the previous state.
|
||||
See: https://sourceforge.net/p/snapraid/discussion/1677233/thread/e26e787d/
|
||||
|
||||
* Allow to filter in diff/list by disk name.
|
||||
Not checked disks should be allowed to be missing.
|
||||
|
||||
* Add an option to ignore subsecond timestamp.
|
||||
Like when you copy data to a filesystem with less timestamp precision.
|
||||
|
||||
* Extend haspdeep to support the SnapRAID hash :
|
||||
https://github.com/jessek/hashdeep/
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/90b0e9b2/?limit=25
|
||||
|
||||
* Add a "noaccessdenied" config option to exclude not readable files/dirs.
|
||||
Like the "nohidden".
|
||||
See: https://sourceforge.net/p/snapraid/discussion/1677233/thread/1409c26a/
|
||||
|
||||
* Don't insert new files if they are new opened by other applications.
|
||||
Not yet sure how to check if a file is open in a fast way.
|
||||
In case we can exclude files created too recently, like with a --min-age option.
|
||||
See: https://sourceforge.net/p/snapraid/discussion/1677233/thread/a1683dd9/?limit=25#1e16
|
||||
|
||||
* Add markdown support for output
|
||||
See: https://sourceforge.net/p/snapraid/discussion/1677233/thread/661cce8b/
|
||||
|
||||
* Add ZFS support for SMART and UUID.
|
||||
See latest messages at: https://sourceforge.net/p/snapraid/discussion/1677233/thread/42defa3b/
|
||||
|
||||
* Change all the path printed in the terminal as relative and not absolute.
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/648955ec/ (Leifi in diff)
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/5b6ef1b9/ (Miles in check + filter)
|
||||
Partially done. Now you can control it with --test-fmt
|
||||
|
||||
* Add ReFS support with 128 bits inode
|
||||
See: https://sourceforge.net/p/snapraid/discussion/1677233/thread/2be14f63/
|
||||
https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/miniFilter/avscan/filter/utility.h
|
||||
https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/miniFilter/avscan/filter/utility.c
|
||||
https://github.com/Microsoft/Windows-driver-samples/blob/master/filesys/miniFilter/delete/delete.c
|
||||
Partially done. Until the inodes are less than 64 bit, everything works.
|
||||
If a 128 bit inode is found, it aborts with "Invalid inode number! Is this ReFS?"
|
||||
|
||||
* When a disk is replaced, and SnapRAID detect this by a UUID change, we could clear the
|
||||
scrub information for that disk.
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/ee87901b/
|
||||
|
||||
* In fix, automatic --import excluded directory in the config file.
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/c80c42e5/?limit=25
|
||||
|
||||
* Allow to have "partial" parity disks, smaller than required ?
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/e924c663/
|
||||
|
||||
* How to handle corrupt copied/moved files ? At now pre-hash checks them,
|
||||
but if a corruption is found, it stops the sync process.
|
||||
This is not optimal, because the 'sync' command is stopped instead to continue.
|
||||
A possible solution could be:
|
||||
If a copied block is corrupt, we can recover the original one from parity (if moved),
|
||||
or read it directly from disk (if copied), and we can use this one to build the parity,
|
||||
working around the corruption, that can be later fixed with "fix".
|
||||
This requires to allocate blocks of moved files in parity positions *after* the
|
||||
currently used one.
|
||||
|
||||
* Some programs are misusing the FILE_ATTRIBUTE_TEMPORARY.
|
||||
In fact, it makes sense as it's a good way to control the cache on the file,
|
||||
so, despite the name, that usage could be common for not temporary files.
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/57d40108/
|
||||
|
||||
* Restore ownership and permissions, at least in Unix.
|
||||
|
||||
* Restore directory timestamps.
|
||||
|
||||
* Add an option for dup to list only duplicates with different name.
|
||||
This supposing that if a file has the same name, it's intentionally duplicated.
|
||||
|
||||
* In fix an existing symlink with the same name of a file to be recovered may stop
|
||||
the process making the create() operation to fail.
|
||||
The same for directories, when recreating the directory tree.
|
||||
|
||||
* If a directory exists with the same name of a parity/content file be more explicative
|
||||
on the error message. See: https://sourceforge.net/projects/snapraid/forums/forum/1677233/topic/4861034
|
||||
|
||||
* We don't try to do partial block recovering. A block is correct or not.
|
||||
But if only some bytes, or a sector, is wrong, it should be possible to recover all the
|
||||
rest of the block.
|
||||
The problem is that we don't have any hash to ensure that the block is partially recovered,
|
||||
or completely garbage. But it makes sense to anyway write the "most likely" correct one.
|
||||
|
||||
- Naming
|
||||
|
||||
* A new 'init' command to differentiate the first 'sync' operation.
|
||||
This 'init' will work also without a content file, and parity files.
|
||||
Instead 'sync' will require all of them.
|
||||
This will also help when running with the parity filesystem unmounted.
|
||||
|
||||
* Rename sync->backup and fix->restore. It seems to me a naming expressing
|
||||
better the meaning of the commands. But not yet sure.
|
||||
|
||||
- Pooling
|
||||
|
||||
* Add a new "commit" command to move changes from the pool to the array.
|
||||
It should:
|
||||
- Move files copied into the pool (that are no links) to the array.
|
||||
The files should be moved to the disk that contains most of the files
|
||||
in the directory. If no space, try with the disk with less files
|
||||
in the directory, and eventually the disk in the array with more free space.
|
||||
- Detect renames, and apply them in the array.
|
||||
The file will be renamed and moved to the new directory, if changed,
|
||||
but kept in the same disk of the array.
|
||||
- Detect deletes, and move file in the array to a "/trash/" directory
|
||||
of the same disk. For safety no real deletion is done.
|
||||
File with the same name will get an extra extension like ".1", ".2".
|
||||
|
||||
- Major
|
||||
|
||||
* Uses a separated file for storing hashes, to allow to use a memory
|
||||
mapped file to decrease memory utilization.
|
||||
The file can contains hashes stored in the same order they are accessed
|
||||
in sync/check/scrub.
|
||||
+ A lot less memory utilization
|
||||
- It will be slow in --pre-hash as the files are accessed in another order,
|
||||
but no much slow.
|
||||
- How to handle multiple .content file copy ? When working we can have
|
||||
only a single file. When storing the .content we'll have to copy it
|
||||
in all the places.
|
||||
* Can we mix the existing and new approach ? We can create this
|
||||
hash file at startup in a memory mapped "temporary" file.
|
||||
It may takes some time to create it, but then it will be fast.
|
||||
See: https://sourceforge.net/p/snapraid/discussion/1677233/thread/cdea773f/
|
||||
|
||||
* Allocate parity minimizing concurrent use of it
|
||||
Each parity allocation should check for a parity
|
||||
range with less utilization by other disks.
|
||||
We need to take care do disable this meachnism when the parity space
|
||||
is near to fillup the parity partition.
|
||||
See: https://sourceforge.net/p/snapraid/discussion/1677233/thread/1797bf7d/
|
||||
+ This increase the possibility of recovering with multiple failures with not
|
||||
enough parity, as the benefit of existing parity is maximized.
|
||||
- Possible increase of fragmentation of parity allocation
|
||||
- No real benefit when the array is filled
|
||||
|
||||
|
||||
Rejected TODO
|
||||
=============
|
||||
|
||||
This is a list of rejected TODO items.
|
||||
|
||||
* Allow multiple parity files and to coexist with data
|
||||
in the same disk.
|
||||
This is possible if the data in the same disk uses parity addresses not
|
||||
contained in the parity file present in the same disk.
|
||||
+ It's a nice trick. The disk containing parity, will have less space available,
|
||||
and then it will need less parity, resolving the problem of the parity disk being too small.
|
||||
+ We can also think at an automated parity files naming and creation, removing
|
||||
the need of the user to specify that. We can also completely remove the
|
||||
concept of parity drive, automatically allocating parity in the most free data drives.
|
||||
- It won't be not nice to have the program to automatically
|
||||
choose where to create the parity, because the choice cannot be optimal.
|
||||
With a dedicated disk manually chosen, it's instead optimal.
|
||||
+ We can limit this coexist possibility only to latest parity file,
|
||||
allowing the user to choose where to put it.
|
||||
- It won't work with disks of different size.
|
||||
Suppose to have all disks of size N, with only one of size M>N.
|
||||
To fully use the M space, you can allocate a full N parity in such disk,
|
||||
but the remaning space will also need additional parity in the other disks,
|
||||
in fact requiring a total of M parity for the array.
|
||||
In the end, we cannot avoid that the first biggest disk added is fully
|
||||
dedicated to parity, even if it means to leave some space unused.
|
||||
|
||||
* Directly access disks for parity skipping the filesystem layer
|
||||
- No real performance or space gain compared to a custom filesystem configuration like:
|
||||
mkfs.ext3 -i 16777216 -m0 -O ^dir_index,large_file,sparse_super /dev/sdX1
|
||||
See: https://sourceforge.net/p/snapraid/discussion/1677233/thread/9c0ef324/?limit=25
|
||||
|
||||
* Allow to specify more than one disk directories to cover the case of multi partitions.
|
||||
Different partitions have duplicate inode. The only way to support this is to
|
||||
add also a kind of device_id, increasing the memory required.
|
||||
But it should be only few bits for each file. So, it should be manageable.
|
||||
A lot of discussions about this feature :)
|
||||
https://sourceforge.net/p/snapraid/discussion/1677233/thread/b2cd9385/
|
||||
- The only benefit is to distribute better the data. This could help the recovery process,
|
||||
in case of multiple failures. But no real usability or funtionality benefit in the normal
|
||||
case.
|
||||
|
||||
* https://sourceforge.net/p/snapraid/discussion/1677233/thread/2cb97e8a/
|
||||
Have two hashes for each file. One for the first segment, that may use only a part of the first parity block.
|
||||
And a second hash that takes care of the final segment, also using only part of a parity block.
|
||||
Intermediate blocks can be handled like now.
|
||||
The first and last segment can use only a part of the parity block, sharing it with other files,
|
||||
and then allowing big parity blocks.
|
||||
+ Big parity block, like 1MB, and small file allocation, like 4KB.
|
||||
- It won't be possible to copy hash info from one disk to another, as copied files
|
||||
may have a different block splitting. Copied file should be allocated with the same exact
|
||||
splitting.
|
||||
- Dup detection can be handled with a dedicated hash covering the full file. But increasing
|
||||
the number of hash for each file to three.
|
||||
- No way to handle block import.
|
||||
|
||||
* Create a filesystem snapshot at every sync, and use it in all the other commands
|
||||
automatically.
|
||||
At the next sync, drop the old snapshot and create a new one.
|
||||
This should help recovering, because we'll have the exact copy used by sync.
|
||||
This feature can be enabled with a specific option, and available
|
||||
in Windows using Shadow Copy, and in Linux using Btrfs, and in a generic
|
||||
Unix using ZFS.
|
||||
See Jens's Windows script at: http://sourceforge.net/p/snapraid/discussion/1677233/thread/a1707211/
|
||||
Note that a different between Windows and Unix is that in Windows old snapshots
|
||||
are automatically deleted.
|
||||
|
||||
* Checks if splitting hash/parity computation in 4K pages
|
||||
can improve speed in sync. That should increase cache locality,
|
||||
because we read the data two times for hash and and parity,
|
||||
and if we manage to keep it in the cache, we should save time.
|
||||
- We now hash first the faster disks, and this could
|
||||
reduce performance as we'll have to wait for all disks.
|
||||
|
||||
* Use threads to scan all the disks at the same time.
|
||||
- After 7.0 Windows changes it seems fast enough even
|
||||
with a mono thread implementation.
|
||||
|
||||
* Enable storing of creation time NTFS, crtime/birth time EXT4.
|
||||
But see: http://unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4
|
||||
coreutils stat has an example, but it doesn't work in Linux (see lib/stat-time.h)
|
||||
- Not supported in Linux.
|
||||
|
||||
* In the content file save the timestamp of the parity files.
|
||||
If they do not match, stop the processing.
|
||||
This can be done to avoid to use not synchronized parity and content files,
|
||||
resulting in wrong data.
|
||||
But if the sync process is killed we need a way to resyncronize them.
|
||||
Or maybe we should allow parity newer than content, but not viceversa.
|
||||
- The corner cases are too many. A fixed parity may be never.
|
||||
A someway modified content may be never. So, the time is not really significant.
|
||||
|
||||
* Use Async IO for Linux (libaio).
|
||||
See thread: https://sourceforge.net/p/snapraid/discussion/1677233/thread/a300a10b/
|
||||
Docs at: http://www.fsl.cs.sunysb.edu/~vass/linux-aio.txt
|
||||
- Implemented for scrub in the "libaio" branch, but it's slower of
|
||||
about 20% in my machine.
|
||||
|
||||
* Allow to put parity directly into the underline block device without the need
|
||||
of any filesystem.
|
||||
That would allow to increase a lot the free space for parity.
|
||||
We can implement some kind of filesystem detection to avoid to overwrite an already
|
||||
existing filesystem.
|
||||
- Still risky if stuffs go wrong.
|
||||
- In Linux with largefile4 there is only a very small amount of space wasted.
|
||||
In the order of 0.01%. Not really worth to do it.
|
||||
- With NTFS the saving is also limited, because the "reserved" MFT of 12.5% is
|
||||
not really exclusively reserved, but can be used also for normal files,
|
||||
when all the remaining space is filled.
|
||||
|
||||
* The data could be compressed before processing, resulting in parity block of
|
||||
fixed size, but matching different data block sizes.
|
||||
The complexity is that a file blocks will have to be allocated at runtime,
|
||||
and you may run out of them in the middle of the processing.
|
||||
We need also a way to compress a stream until the compressed data reach the
|
||||
block size, but no more, and then start a new block.
|
||||
For each block, we'll have also to store. "size_uncompressed", "size_compressed",
|
||||
"hash".
|
||||
- It will be too slow.
|
||||
- Not addressing the problem of a lot of small files, as still one block will be
|
||||
allocated for each file.
|
||||
|
||||
* Uses different block size for parity and file allocation.
|
||||
We can use a big size, like 1MB for parity allocation and hash computation,
|
||||
and at the same time using a 4K blocks for files allocation.
|
||||
This means that a parity blocks may contain more than one file.
|
||||
- We'll have to drop the dup and import feature,
|
||||
because it won't be possible anymore to compare the hash of files,
|
||||
as it would depend also on the start address inside the parity block.
|
||||
- When a hash fail, it won't be possible to tell which file is really
|
||||
broken, because more file may share the same parity block.
|
||||
|
||||
* Have special parity blocks containing the last blocks of more files
|
||||
until it's filled up.
|
||||
For such parity blocks, we'll have more than one hash. One for each
|
||||
file contained.
|
||||
- Parity will be too fragmented, because we'll have parity blocks
|
||||
containing the last blocks of many files.
|
||||
|
||||
* In "pool" for Windows, and for unique directories a junction to the
|
||||
directory could be used, avoiding to use symlinks to files.
|
||||
This allows to overcome the problem of sharing symlinks.
|
||||
- It would work, in fact it would work to well. The problem is that
|
||||
Windows will treat the junction as the real directory, like *really*
|
||||
deleting its content from Explorer pressing "del" and also from the
|
||||
command line with "rd". Too dangerous.
|
||||
|
||||
* When fixing, before overwriting the present file, make a copy of it just in
|
||||
case that the original file cannot be completely recovered.
|
||||
We can always open files in read-only mode, if a write is required, we close it,
|
||||
rename it to with a .bak extension, and rewrite it up to the required size.
|
||||
The same for symlink if a file with the same name exist or viceversa.
|
||||
- The idea behind this is to avoid to leave untouched a file if we cannot
|
||||
restore it completely. But it's debatable what's better in this case.
|
||||
Anyway, considering the typical use, it's not really relevant.
|
||||
|
||||
* In the import list, uses also all the blocks in the array.
|
||||
But we must cover the case of bad blocks. Likely we can just check the
|
||||
hash after reading, and in case, skip it, and retry with another copy.
|
||||
- It will work only for duplicate files. Not really worth do to it.
|
||||
|
||||
* Save the content file in compressed .gz format to save space.
|
||||
- Compression is too slow. Even using the very fast lzo.
|
||||
$ time lzop -1 < content > content.lzo
|
||||
real 1m23.014s
|
||||
user 0m40.822s
|
||||
sys 0m3.389s
|
||||
|
||||
$ time ./gzip -1 < content > content.gz
|
||||
real 1m47.463s
|
||||
user 1m23.732s
|
||||
sys 0m3.290s
|
||||
|
||||
$ time ./gzip --huffonly < content > contentH.gz
|
||||
real 1m51.607s
|
||||
user 1m30.032s
|
||||
sys 0m3.245s
|
||||
|
||||
Similar command done with snapraid without compression, and involving also decoding
|
||||
and encoding takes less time.
|
||||
|
||||
$ time ./snapraid --test-skip-device --test-skip-self -v -c ./test.conf test-rewrite
|
||||
real 0m59.087s
|
||||
user 0m14.164s
|
||||
sys 0m4.398s
|
||||
|
||||
* Recognizes that a file is moved from one disk to another, and if the parity
|
||||
data doesn't overlap, do not recompute it.
|
||||
- It's going to work only in RAID5 mode and only in special cases.
|
||||
|
||||
* Implements a multithread sync command to share HASH and RAID computations
|
||||
to different CPUs.
|
||||
- At now it's questionable if it will result in a performance improvement.
|
||||
The murmur3 hash, and the RAID5/6 computations are so fast that even a single
|
||||
thread should be able to do them.
|
||||
Use the "snapraid -T" comment to see the speed.
|
||||
|
||||
* In the repair() function the heuristic to detect if we recovered after the sync,
|
||||
can be extended to all the previous blocks, because we always proceed in block
|
||||
order during a sync.
|
||||
So, if for a block we can detect that we recovered using updated parity data,
|
||||
also for all the previous blocks this is true.
|
||||
Anyway, the case where this information could be useful should be present
|
||||
only if changes are committed after an aborted sync.
|
||||
- No real advantage on that, beside some speed gain in fix.
|
||||
The risk would be instead to miss some recovery opportunity.
|
||||
So, makes sense to have it a little slower but trying any
|
||||
possible recovery strategy.
|
||||
|
||||
|
19
acinclude.m4
Normal file
19
acinclude.m4
Normal file
@ -0,0 +1,19 @@
|
||||
dnl @synopsis AC_CHECK_CC_OPT(flag, ifyes, ifno)
|
||||
dnl
|
||||
dnl Shows a message as like "checking wether gcc accepts flag ... no"
|
||||
dnl and executess ifyes or ifno.
|
||||
|
||||
AC_DEFUN([AC_CHECK_CC_OPT],
|
||||
[
|
||||
AC_MSG_CHECKING([whether ${CC-cc} accepts $1])
|
||||
echo 'void f(){}' > conftest.c
|
||||
if test -z "`${CC-cc} -c $1 conftest.c 2>&1`"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
$2
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
$3
|
||||
fi
|
||||
rm -f conftest*
|
||||
])
|
||||
|
838
aclocal.m4
vendored
Normal file
838
aclocal.m4
vendored
Normal file
@ -0,0 +1,838 @@
|
||||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
|
||||
[m4_warning([this file was generated for autoconf 2.69.
|
||||
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||
If you have problems, you may need to regenerate the build system entirely.
|
||||
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
|
||||
|
||||
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_AUTOMAKE_VERSION(VERSION)
|
||||
# ----------------------------
|
||||
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||
# generated from the m4 files accompanying Automake X.Y.
|
||||
# (This private macro should not be called outside this file.)
|
||||
AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.15'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.15], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
# _AM_AUTOCONF_VERSION(VERSION)
|
||||
# -----------------------------
|
||||
# aclocal traces this macro to find the Autoconf version.
|
||||
# This is a private macro too. Using m4_define simplifies
|
||||
# the logic in aclocal, which can simply ignore this definition.
|
||||
m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
|
||||
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||
# -------------------------------
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.15])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
|
||||
# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is '.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
|
||||
# Expand $ac_aux_dir to an absolute path.
|
||||
am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||
])
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ([2.52])dnl
|
||||
m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])dnl
|
||||
AC_SUBST([$1_FALSE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This macro actually does too much. Some checks are only needed if
|
||||
# your package does certain things. But this isn't really a big deal.
|
||||
|
||||
dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
|
||||
m4_define([AC_PROG_CC],
|
||||
m4_defn([AC_PROG_CC])
|
||||
[_AM_PROG_CC_C_O
|
||||
])
|
||||
|
||||
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
# -----------------------------------------------
|
||||
# The call with PACKAGE and VERSION arguments is the old style
|
||||
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||
# and VERSION should now be passed to AC_INIT and removed from
|
||||
# the call to AM_INIT_AUTOMAKE.
|
||||
# We support both call styles for the transition. After
|
||||
# the next Automake release, Autoconf can make the AC_INIT
|
||||
# arguments mandatory, and then we can depend on a new Autoconf
|
||||
# release and drop the old call support.
|
||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||
[AC_PREREQ([2.65])dnl
|
||||
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||
dnl the ones we care about.
|
||||
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`"; then
|
||||
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
|
||||
# is not polluted with repeated "-I."
|
||||
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
|
||||
# test to see if srcdir already configured
|
||||
if test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
fi
|
||||
|
||||
# test whether we have cygpath
|
||||
if test -z "$CYGPATH_W"; then
|
||||
if (cygpath --version) >/dev/null 2>/dev/null; then
|
||||
CYGPATH_W='cygpath -w'
|
||||
else
|
||||
CYGPATH_W=echo
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([CYGPATH_W])
|
||||
|
||||
# Define the identity of the package.
|
||||
dnl Distinguish between old-style and new-style calls.
|
||||
m4_ifval([$2],
|
||||
[AC_DIAGNOSE([obsolete],
|
||||
[$0: two- and three-arguments forms are deprecated.])
|
||||
m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||
AC_SUBST([PACKAGE], [$1])dnl
|
||||
AC_SUBST([VERSION], [$2])],
|
||||
[_AM_SET_OPTIONS([$1])dnl
|
||||
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||
m4_if(
|
||||
m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
|
||||
[ok:ok],,
|
||||
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
||||
|
||||
_AM_IF_OPTION([no-define],,
|
||||
[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
|
||||
AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
|
||||
|
||||
# Some tools Automake needs.
|
||||
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||
AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
|
||||
AM_MISSING_PROG([AUTOCONF], [autoconf])
|
||||
AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
|
||||
AM_MISSING_PROG([AUTOHEADER], [autoheader])
|
||||
AM_MISSING_PROG([MAKEINFO], [makeinfo])
|
||||
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
|
||||
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
|
||||
# For better backward compatibility. To be removed once Automake 1.9.x
|
||||
# dies out for good. For more background, see:
|
||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
|
||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
|
||||
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
|
||||
# We need awk for the "check" target (and possibly the TAP driver). The
|
||||
# system "awk" is bad on some platforms.
|
||||
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
||||
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
||||
[_AM_PROG_TAR([v7])])])
|
||||
_AM_IF_OPTION([no-dependencies],,
|
||||
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
||||
[_AM_DEPENDENCIES([CC])],
|
||||
[m4_define([AC_PROG_CC],
|
||||
m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
||||
[_AM_DEPENDENCIES([CXX])],
|
||||
[m4_define([AC_PROG_CXX],
|
||||
m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
|
||||
[_AM_DEPENDENCIES([OBJC])],
|
||||
[m4_define([AC_PROG_OBJC],
|
||||
m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
|
||||
[_AM_DEPENDENCIES([OBJCXX])],
|
||||
[m4_define([AC_PROG_OBJCXX],
|
||||
m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
|
||||
])
|
||||
AC_REQUIRE([AM_SILENT_RULES])dnl
|
||||
dnl The testsuite driver may need to know about EXEEXT, so add the
|
||||
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
|
||||
dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
|
||||
AC_CONFIG_COMMANDS_PRE(dnl
|
||||
[m4_provide_if([_AM_COMPILER_EXEEXT],
|
||||
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
|
||||
|
||||
# POSIX will say in a future version that running "rm -f" with no argument
|
||||
# is OK; and we want to be able to make that assumption in our Makefile
|
||||
# recipes. So use an aggressive probe to check that the usage we want is
|
||||
# actually supported "in the wild" to an acceptable degree.
|
||||
# See automake bug#10828.
|
||||
# To make any issue more visible, cause the running configure to be aborted
|
||||
# by default if the 'rm' program in use doesn't match our expectations; the
|
||||
# user can still override this though.
|
||||
if rm -f && rm -fr && rm -rf; then : OK; else
|
||||
cat >&2 <<'END'
|
||||
Oops!
|
||||
|
||||
Your 'rm' program seems unable to run without file operands specified
|
||||
on the command line, even when the '-f' option is present. This is contrary
|
||||
to the behaviour of most rm programs out there, and not conforming with
|
||||
the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
|
||||
|
||||
Please tell bug-automake@gnu.org about your system, including the value
|
||||
of your $PATH and any error possibly output before this message. This
|
||||
can help us improve future automake versions.
|
||||
|
||||
END
|
||||
if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
|
||||
echo 'Configuration will proceed anyway, since you have set the' >&2
|
||||
echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
|
||||
echo >&2
|
||||
else
|
||||
cat >&2 <<'END'
|
||||
Aborting the configuration process, to ensure you take notice of the issue.
|
||||
|
||||
You can download and install GNU coreutils to get an 'rm' implementation
|
||||
that behaves properly: <http://www.gnu.org/software/coreutils/>.
|
||||
|
||||
If you want to complete the configuration process using your problematic
|
||||
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
|
||||
to "yes", and re-run configure.
|
||||
|
||||
END
|
||||
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
|
||||
fi
|
||||
fi
|
||||
dnl The trailing newline in this macro's definition is deliberate, for
|
||||
dnl backward compatibility and to allow trailing 'dnl'-style comments
|
||||
dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
|
||||
])
|
||||
|
||||
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
|
||||
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
|
||||
dnl mangled by Autoconf and run in a shell conditional statement.
|
||||
m4_define([_AC_COMPILER_EXEEXT],
|
||||
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp files are numbered to have different names.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[# Compute $1's index in $config_headers.
|
||||
_am_arg=$1
|
||||
_am_stamp_count=1
|
||||
for _am_header in $config_headers :; do
|
||||
case $_am_header in
|
||||
$_am_arg | $_am_arg:* )
|
||||
break ;;
|
||||
* )
|
||||
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
||||
esac
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_SH
|
||||
# ------------------
|
||||
# Define $install_sh.
|
||||
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
if test x"${install_sh+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
|
||||
*)
|
||||
install_sh="\${SHELL} $am_aux_dir/install-sh"
|
||||
esac
|
||||
fi
|
||||
AC_SUBST([install_sh])])
|
||||
|
||||
# Copyright (C) 2003-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# Check whether the underlying file-system supports filenames
|
||||
# with a leading dot. For instance MS-DOS doesn't.
|
||||
AC_DEFUN([AM_SET_LEADING_DOT],
|
||||
[rm -rf .tst 2>/dev/null
|
||||
mkdir .tst 2>/dev/null
|
||||
if test -d .tst; then
|
||||
am__leading_dot=.
|
||||
else
|
||||
am__leading_dot=_
|
||||
fi
|
||||
rmdir .tst 2>/dev/null
|
||||
AC_SUBST([am__leading_dot])])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||
# ------------------------------
|
||||
AC_DEFUN([AM_MISSING_PROG],
|
||||
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||
$1=${$1-"${am_missing_run}$2"}
|
||||
AC_SUBST($1)])
|
||||
|
||||
# AM_MISSING_HAS_RUN
|
||||
# ------------------
|
||||
# Define MISSING if not defined so far and test if it is modern enough.
|
||||
# If it is, set am_missing_run to use it, otherwise, to nothing.
|
||||
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --is-lightweight"; then
|
||||
am_missing_run="$MISSING "
|
||||
else
|
||||
am_missing_run=
|
||||
AC_MSG_WARN(['missing' script is too old or missing])
|
||||
fi
|
||||
])
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_MANGLE_OPTION(NAME)
|
||||
# -----------------------
|
||||
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
# _AM_SET_OPTION(NAME)
|
||||
# --------------------
|
||||
# Set option NAME. Presently that only means defining a flag for this option.
|
||||
AC_DEFUN([_AM_SET_OPTION],
|
||||
[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
|
||||
|
||||
# _AM_SET_OPTIONS(OPTIONS)
|
||||
# ------------------------
|
||||
# OPTIONS is a space-separated list of Automake options.
|
||||
AC_DEFUN([_AM_SET_OPTIONS],
|
||||
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||
|
||||
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||
# -------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_PROG_CC_C_O
|
||||
# ---------------
|
||||
# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
|
||||
# to automatically call this.
|
||||
AC_DEFUN([_AM_PROG_CC_C_O],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([compile])dnl
|
||||
AC_LANG_PUSH([C])dnl
|
||||
AC_CACHE_CHECK(
|
||||
[whether $CC understands -c and -o together],
|
||||
[am_cv_prog_cc_c_o],
|
||||
[AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
|
||||
# Make sure it works both with $CC and with simple cc.
|
||||
# Following AC_PROG_CC_C_O, we do the test twice because some
|
||||
# compilers refuse to overwrite an existing .o file with -o,
|
||||
# though they will create one.
|
||||
am_cv_prog_cc_c_o=yes
|
||||
for am_i in 1 2; do
|
||||
if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
|
||||
&& test -f conftest2.$ac_objext; then
|
||||
: OK
|
||||
else
|
||||
am_cv_prog_cc_c_o=no
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -f core conftest*
|
||||
unset am_i])
|
||||
if test "$am_cv_prog_cc_c_o" != yes; then
|
||||
# Losing compiler, so override with the script.
|
||||
# FIXME: It is wrong to rewrite CC.
|
||||
# But if we don't then we get into trouble of one sort or another.
|
||||
# A longer-term fix would be to have automake use am__CC in this case,
|
||||
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||
CC="$am_aux_dir/compile $CC"
|
||||
fi
|
||||
AC_LANG_POP([C])])
|
||||
|
||||
# For backward compatibility.
|
||||
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_RUN_LOG(COMMAND)
|
||||
# -------------------
|
||||
# Run COMMAND, save the exit status in ac_status, and log it.
|
||||
# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
|
||||
AC_DEFUN([AM_RUN_LOG],
|
||||
[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
|
||||
($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
|
||||
(exit $ac_status); }])
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_SANITY_CHECK
|
||||
# ---------------
|
||||
AC_DEFUN([AM_SANITY_CHECK],
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Reject unsafe characters in $srcdir or the absolute working directory
|
||||
# name. Accept space and tab only in the latter.
|
||||
am_lf='
|
||||
'
|
||||
case `pwd` in
|
||||
*[[\\\"\#\$\&\'\`$am_lf]]*)
|
||||
AC_MSG_ERROR([unsafe absolute working directory name]);;
|
||||
esac
|
||||
case $srcdir in
|
||||
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
|
||||
AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
|
||||
esac
|
||||
|
||||
# Do 'set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
am_has_slept=no
|
||||
for am_try in 1 2; do
|
||||
echo "timestamp, slept: $am_has_slept" > conftest.file
|
||||
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
|
||||
if test "$[*]" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t "$srcdir/configure" conftest.file`
|
||||
fi
|
||||
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
if test "$[2]" = conftest.file || test $am_try -eq 2; then
|
||||
break
|
||||
fi
|
||||
# Just in case.
|
||||
sleep 1
|
||||
am_has_slept=yes
|
||||
done
|
||||
test "$[2]" = conftest.file
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
AC_MSG_RESULT([yes])
|
||||
# If we didn't sleep, we still need to ensure time stamps of config.status and
|
||||
# generated files are strictly newer.
|
||||
am_sleep_pid=
|
||||
if grep 'slept: no' conftest.file >/dev/null 2>&1; then
|
||||
( sleep 1 ) &
|
||||
am_sleep_pid=$!
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[AC_MSG_CHECKING([that generated files are newer than configure])
|
||||
if test -n "$am_sleep_pid"; then
|
||||
# Hide warnings about reused PIDs.
|
||||
wait $am_sleep_pid 2>/dev/null
|
||||
fi
|
||||
AC_MSG_RESULT([done])])
|
||||
rm -f conftest.file
|
||||
])
|
||||
|
||||
# Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_SILENT_RULES([DEFAULT])
|
||||
# --------------------------
|
||||
# Enable less verbose build rules; with the default set to DEFAULT
|
||||
# ("yes" being less verbose, "no" or empty being verbose).
|
||||
AC_DEFUN([AM_SILENT_RULES],
|
||||
[AC_ARG_ENABLE([silent-rules], [dnl
|
||||
AS_HELP_STRING(
|
||||
[--enable-silent-rules],
|
||||
[less verbose build output (undo: "make V=1")])
|
||||
AS_HELP_STRING(
|
||||
[--disable-silent-rules],
|
||||
[verbose build output (undo: "make V=0")])dnl
|
||||
])
|
||||
case $enable_silent_rules in @%:@ (((
|
||||
yes) AM_DEFAULT_VERBOSITY=0;;
|
||||
no) AM_DEFAULT_VERBOSITY=1;;
|
||||
*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
|
||||
esac
|
||||
dnl
|
||||
dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
|
||||
dnl do not support nested variable expansions.
|
||||
dnl See automake bug#9928 and bug#10237.
|
||||
am_make=${MAKE-make}
|
||||
AC_CACHE_CHECK([whether $am_make supports nested variables],
|
||||
[am_cv_make_support_nested_variables],
|
||||
[if AS_ECHO([['TRUE=$(BAR$(V))
|
||||
BAR0=false
|
||||
BAR1=true
|
||||
V=1
|
||||
am__doit:
|
||||
@$(TRUE)
|
||||
.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
|
||||
am_cv_make_support_nested_variables=yes
|
||||
else
|
||||
am_cv_make_support_nested_variables=no
|
||||
fi])
|
||||
if test $am_cv_make_support_nested_variables = yes; then
|
||||
dnl Using '$V' instead of '$(V)' breaks IRIX make.
|
||||
AM_V='$(V)'
|
||||
AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
|
||||
else
|
||||
AM_V=$AM_DEFAULT_VERBOSITY
|
||||
AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
|
||||
fi
|
||||
AC_SUBST([AM_V])dnl
|
||||
AM_SUBST_NOTMAKE([AM_V])dnl
|
||||
AC_SUBST([AM_DEFAULT_V])dnl
|
||||
AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
|
||||
AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
|
||||
AM_BACKSLASH='\'
|
||||
AC_SUBST([AM_BACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_STRIP
|
||||
# ---------------------
|
||||
# One issue with vendor 'install' (even GNU) is that you can't
|
||||
# specify the program used to strip binaries. This is especially
|
||||
# annoying in cross-compiling environments, where the build's strip
|
||||
# is unlikely to handle the host's binaries.
|
||||
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||
# always use install-sh in "make install-strip", and initialize
|
||||
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
# Installed binaries are usually stripped using 'strip' when the user
|
||||
# run "make install-strip". However 'strip' might not be the right
|
||||
# tool to use in cross-compilation environments, therefore Automake
|
||||
# will honor the 'STRIP' environment variable to overrule this program.
|
||||
dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
|
||||
if test "$cross_compiling" != no; then
|
||||
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||
fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||
# This macro is traced by Automake.
|
||||
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||
|
||||
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# --------------------------
|
||||
# Public sister of _AM_SUBST_NOTMAKE.
|
||||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004-2014 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_PROG_TAR(FORMAT)
|
||||
# --------------------
|
||||
# Check how to create a tarball in format FORMAT.
|
||||
# FORMAT should be one of 'v7', 'ustar', or 'pax'.
|
||||
#
|
||||
# Substitute a variable $(am__tar) that is a command
|
||||
# writing to stdout a FORMAT-tarball containing the directory
|
||||
# $tardir.
|
||||
# tardir=directory && $(am__tar) > result.tar
|
||||
#
|
||||
# Substitute a variable $(am__untar) that extract such
|
||||
# a tarball read from stdin.
|
||||
# $(am__untar) < result.tar
|
||||
#
|
||||
AC_DEFUN([_AM_PROG_TAR],
|
||||
[# Always define AMTAR for backward compatibility. Yes, it's still used
|
||||
# in the wild :-( We should find a proper way to deprecate it ...
|
||||
AC_SUBST([AMTAR], ['$${TAR-tar}'])
|
||||
|
||||
# We'll loop over all known methods to create a tar archive until one works.
|
||||
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
||||
|
||||
m4_if([$1], [v7],
|
||||
[am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
|
||||
|
||||
[m4_case([$1],
|
||||
[ustar],
|
||||
[# The POSIX 1988 'ustar' format is defined with fixed-size fields.
|
||||
# There is notably a 21 bits limit for the UID and the GID. In fact,
|
||||
# the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
|
||||
# and bug#13588).
|
||||
am_max_uid=2097151 # 2^21 - 1
|
||||
am_max_gid=$am_max_uid
|
||||
# The $UID and $GID variables are not portable, so we need to resort
|
||||
# to the POSIX-mandated id(1) utility. Errors in the 'id' calls
|
||||
# below are definitely unexpected, so allow the users to see them
|
||||
# (that is, avoid stderr redirection).
|
||||
am_uid=`id -u || echo unknown`
|
||||
am_gid=`id -g || echo unknown`
|
||||
AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
|
||||
if test $am_uid -le $am_max_uid; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
_am_tools=none
|
||||
fi
|
||||
AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
|
||||
if test $am_gid -le $am_max_gid; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
_am_tools=none
|
||||
fi],
|
||||
|
||||
[pax],
|
||||
[],
|
||||
|
||||
[m4_fatal([Unknown tar format])])
|
||||
|
||||
AC_MSG_CHECKING([how to create a $1 tar archive])
|
||||
|
||||
# Go ahead even if we have the value already cached. We do so because we
|
||||
# need to set the values for the 'am__tar' and 'am__untar' variables.
|
||||
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
||||
|
||||
for _am_tool in $_am_tools; do
|
||||
case $_am_tool in
|
||||
gnutar)
|
||||
for _am_tar in tar gnutar gtar; do
|
||||
AM_RUN_LOG([$_am_tar --version]) && break
|
||||
done
|
||||
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
||||
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
||||
am__untar="$_am_tar -xf -"
|
||||
;;
|
||||
plaintar)
|
||||
# Must skip GNU tar: if it does not support --format= it doesn't create
|
||||
# ustar tarball either.
|
||||
(tar --version) >/dev/null 2>&1 && continue
|
||||
am__tar='tar chf - "$$tardir"'
|
||||
am__tar_='tar chf - "$tardir"'
|
||||
am__untar='tar xf -'
|
||||
;;
|
||||
pax)
|
||||
am__tar='pax -L -x $1 -w "$$tardir"'
|
||||
am__tar_='pax -L -x $1 -w "$tardir"'
|
||||
am__untar='pax -r'
|
||||
;;
|
||||
cpio)
|
||||
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
||||
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
||||
am__untar='cpio -i -H $1 -d'
|
||||
;;
|
||||
none)
|
||||
am__tar=false
|
||||
am__tar_=false
|
||||
am__untar=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# If the value was cached, stop now. We just wanted to have am__tar
|
||||
# and am__untar set.
|
||||
test -n "${am_cv_prog_tar_$1}" && break
|
||||
|
||||
# tar/untar a dummy directory, and stop if the command works.
|
||||
rm -rf conftest.dir
|
||||
mkdir conftest.dir
|
||||
echo GrepMe > conftest.dir/file
|
||||
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
||||
rm -rf conftest.dir
|
||||
if test -s conftest.tar; then
|
||||
AM_RUN_LOG([$am__untar <conftest.tar])
|
||||
AM_RUN_LOG([cat conftest.dir/file])
|
||||
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
||||
fi
|
||||
done
|
||||
rm -rf conftest.dir
|
||||
|
||||
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
||||
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
||||
|
||||
AC_SUBST([am__tar])
|
||||
AC_SUBST([am__untar])
|
||||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([acinclude.m4])
|
10
autogen.sh
Executable file
10
autogen.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
echo "Generating build information using autoreconf"
|
||||
|
||||
# All is done by autoreconf
|
||||
autoreconf -f -i
|
||||
|
||||
# Run configure for this platform
|
||||
echo "Now you are ready to run ./configure"
|
||||
|
19
autover.sh
Executable file
19
autover.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
|
||||
if [ -d .git ]; then
|
||||
# Get version from git tags, removing the 'v' prefix
|
||||
VERSION=`git describe --match 'v*' 2>/dev/null | sed 's/^v//'`
|
||||
fi
|
||||
|
||||
if [ -f .version ]; then
|
||||
# Get version from the .version file
|
||||
VERSION=`cat .version`
|
||||
fi
|
||||
|
||||
if [ -z $VERSION ]; then
|
||||
VERSION="none"
|
||||
fi
|
||||
|
||||
printf '%s' "$VERSION"
|
||||
|
2049
cmdline/check.c
Normal file
2049
cmdline/check.c
Normal file
File diff suppressed because it is too large
Load Diff
1001
cmdline/device.c
Normal file
1001
cmdline/device.c
Normal file
File diff suppressed because it is too large
Load Diff
470
cmdline/dry.c
Normal file
470
cmdline/dry.c
Normal file
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "parity.h"
|
||||
#include "handle.h"
|
||||
#include "io.h"
|
||||
#include "raid/raid.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* dry */
|
||||
|
||||
/**
|
||||
* Check if we have to process the specified block index ::i.
|
||||
*/
|
||||
static int block_is_enabled(void* void_plan, block_off_t i)
|
||||
{
|
||||
(void)void_plan;
|
||||
(void)i;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
|
||||
{
|
||||
struct snapraid_io* io = worker->io;
|
||||
struct snapraid_state* state = io->state;
|
||||
struct snapraid_handle* handle = worker->handle;
|
||||
struct snapraid_disk* disk = handle->disk;
|
||||
block_off_t blockcur = task->position;
|
||||
unsigned char* buffer = task->buffer;
|
||||
int ret;
|
||||
char esc_buffer[ESC_MAX];
|
||||
|
||||
/* if the disk position is not used */
|
||||
if (!disk) {
|
||||
/* use an empty block */
|
||||
memset(buffer, 0, state->block_size);
|
||||
task->state = TASK_STATE_DONE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the block */
|
||||
task->block = fs_par2block_find(disk, blockcur);
|
||||
|
||||
/* if the block is not used */
|
||||
if (!block_has_file(task->block)) {
|
||||
/* use an empty block */
|
||||
memset(buffer, 0, state->block_size);
|
||||
task->state = TASK_STATE_DONE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the file of this block */
|
||||
task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
|
||||
|
||||
/* if the file is different than the current one, close it */
|
||||
if (handle->file != 0 && handle->file != task->file) {
|
||||
/* keep a pointer at the file we are going to close for error reporting */
|
||||
struct snapraid_file* report = handle->file;
|
||||
ret = handle_close(handle);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
/* This one is really an unexpected error, because we are only reading */
|
||||
/* and closing a descriptor should never fail */
|
||||
if (errno == EIO) {
|
||||
log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc_tag(report->sub, esc_buffer), strerror(errno));
|
||||
log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to dry.\n");
|
||||
log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path);
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
task->state = TASK_STATE_IOERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(report->sub, esc_buffer), strerror(errno));
|
||||
log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to dry.\n");
|
||||
log_fatal("Ensure that file '%s' can be accessed.\n", handle->path);
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
task->state = TASK_STATE_ERROR;
|
||||
return;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
ret = handle_open(handle, task->file, state->file_mode, log_error, 0);
|
||||
if (ret == -1) {
|
||||
if (errno == EIO) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno));
|
||||
log_fatal("DANGER! Unexpected input/output open error in a data disk, it isn't possible to dry.\n");
|
||||
log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path);
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
task->state = TASK_STATE_IOERROR;
|
||||
return;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno));
|
||||
task->state = TASK_STATE_ERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
|
||||
if (task->read_size == -1) {
|
||||
if (errno == EIO) {
|
||||
log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno));
|
||||
log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos);
|
||||
task->state = TASK_STATE_IOERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno));
|
||||
task->state = TASK_STATE_ERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the path of the opened file */
|
||||
pathcpy(task->path, sizeof(task->path), handle->path);
|
||||
|
||||
task->state = TASK_STATE_DONE;
|
||||
}
|
||||
|
||||
static void dry_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task)
|
||||
{
|
||||
struct snapraid_io* io = worker->io;
|
||||
struct snapraid_state* state = io->state;
|
||||
struct snapraid_parity_handle* parity_handle = worker->parity_handle;
|
||||
unsigned level = parity_handle->level;
|
||||
block_off_t blockcur = task->position;
|
||||
unsigned char* buffer = task->buffer;
|
||||
int ret;
|
||||
|
||||
/* read the parity */
|
||||
ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error);
|
||||
if (ret == -1) {
|
||||
if (errno == EIO) {
|
||||
log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(level), strerror(errno));
|
||||
log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(level), blockcur);
|
||||
task->state = TASK_STATE_IOERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
log_tag("parity_error:%u:%s: Read error. %s\n", blockcur, lev_config_name(level), strerror(errno));
|
||||
task->state = TASK_STATE_ERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
task->state = TASK_STATE_DONE;
|
||||
}
|
||||
|
||||
static int state_dry_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax)
|
||||
{
|
||||
struct snapraid_io io;
|
||||
struct snapraid_handle* handle;
|
||||
unsigned diskmax;
|
||||
block_off_t blockcur;
|
||||
unsigned j;
|
||||
unsigned buffermax;
|
||||
int ret;
|
||||
data_off_t countsize;
|
||||
block_off_t countpos;
|
||||
block_off_t countmax;
|
||||
unsigned error;
|
||||
unsigned io_error;
|
||||
unsigned l;
|
||||
unsigned* waiting_map;
|
||||
unsigned waiting_mac;
|
||||
char esc_buffer[ESC_MAX];
|
||||
|
||||
handle = handle_mapping(state, &diskmax);
|
||||
|
||||
/* we need 1 * data + 2 * parity */
|
||||
buffermax = diskmax + 2 * state->level;
|
||||
|
||||
/* initialize the io threads */
|
||||
io_init(&io, state, state->opt.io_cache, buffermax, dry_data_reader, handle, diskmax, dry_parity_reader, 0, parity_handle, state->level);
|
||||
|
||||
/* possibly waiting disks */
|
||||
waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX;
|
||||
waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned));
|
||||
|
||||
error = 0;
|
||||
io_error = 0;
|
||||
|
||||
/* drop until now */
|
||||
state_usage_waste(state);
|
||||
|
||||
countmax = blockmax - blockstart;
|
||||
countsize = 0;
|
||||
countpos = 0;
|
||||
|
||||
/* start all the worker threads */
|
||||
io_start(&io, blockstart, blockmax, &block_is_enabled, 0);
|
||||
|
||||
state_progress_begin(state, blockstart, blockmax, countmax);
|
||||
while (1) {
|
||||
void** buffer;
|
||||
|
||||
/* go to the next block */
|
||||
blockcur = io_read_next(&io, &buffer);
|
||||
if (blockcur >= blockmax)
|
||||
break;
|
||||
|
||||
/* until now is scheduling */
|
||||
state_usage_sched(state);
|
||||
|
||||
/* for each disk, process the block */
|
||||
for (j = 0; j < diskmax; ++j) {
|
||||
struct snapraid_task* task;
|
||||
int read_size;
|
||||
struct snapraid_block* block;
|
||||
struct snapraid_disk* disk;
|
||||
unsigned diskcur;
|
||||
|
||||
/* until now is misc */
|
||||
state_usage_misc(state);
|
||||
|
||||
/* get the next task */
|
||||
task = io_data_read(&io, &diskcur, waiting_map, &waiting_mac);
|
||||
|
||||
/* until now is disk */
|
||||
state_usage_disk(state, handle, waiting_map, waiting_mac);
|
||||
|
||||
/* get the task results */
|
||||
disk = task->disk;
|
||||
block = task->block;
|
||||
read_size = task->read_size;
|
||||
|
||||
/* if the disk position is not used */
|
||||
if (!disk)
|
||||
continue;
|
||||
|
||||
state_usage_file(state, disk, task->file);
|
||||
|
||||
/* if the block is not used */
|
||||
if (!block_has_file(block))
|
||||
continue;
|
||||
|
||||
/* handle error conditions */
|
||||
if (task->state == TASK_STATE_IOERROR) {
|
||||
/* LCOV_EXCL_START */
|
||||
++io_error;
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (task->state == TASK_STATE_ERROR) {
|
||||
/* LCOV_EXCL_START */
|
||||
++error;
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (task->state == TASK_STATE_ERROR_CONTINUE) {
|
||||
++error;
|
||||
continue;
|
||||
}
|
||||
if (task->state == TASK_STATE_IOERROR_CONTINUE) {
|
||||
++io_error;
|
||||
if (io_error >= state->opt.io_error_limit) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n");
|
||||
log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path);
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* otherwise continue */
|
||||
continue;
|
||||
}
|
||||
if (task->state != TASK_STATE_DONE) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in task state\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
countsize += read_size;
|
||||
}
|
||||
|
||||
/* until now is misc */
|
||||
state_usage_misc(state);
|
||||
|
||||
/* read the parity */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
struct snapraid_task* task;
|
||||
unsigned levcur;
|
||||
|
||||
task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac);
|
||||
|
||||
/* until now is parity */
|
||||
state_usage_parity(state, waiting_map, waiting_mac);
|
||||
|
||||
/* handle error conditions */
|
||||
if (task->state == TASK_STATE_IOERROR) {
|
||||
/* LCOV_EXCL_START */
|
||||
++io_error;
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (task->state == TASK_STATE_ERROR) {
|
||||
/* LCOV_EXCL_START */
|
||||
++error;
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (task->state == TASK_STATE_ERROR_CONTINUE) {
|
||||
++error;
|
||||
continue;
|
||||
}
|
||||
if (task->state == TASK_STATE_IOERROR_CONTINUE) {
|
||||
++io_error;
|
||||
if (io_error >= state->opt.io_error_limit) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur));
|
||||
log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur));
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (task->state != TASK_STATE_DONE) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in task state\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* count the number of processed block */
|
||||
++countpos;
|
||||
|
||||
/* progress */
|
||||
if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
|
||||
/* LCOV_EXCL_START */
|
||||
break;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
state_progress_end(state, countpos, countmax, countsize);
|
||||
|
||||
state_usage_print(state);
|
||||
|
||||
bail:
|
||||
/* stop all the worker threads */
|
||||
io_stop(&io);
|
||||
|
||||
for (j = 0; j < diskmax; ++j) {
|
||||
struct snapraid_file* file = handle[j].file;
|
||||
struct snapraid_disk* disk = handle[j].disk;
|
||||
ret = handle_close(&handle[j]);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
|
||||
log_fatal("DANGER! Unexpected close error in a data disk.\n");
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
if (error || io_error) {
|
||||
msg_status("\n");
|
||||
msg_status("%8u file errors\n", error);
|
||||
msg_status("%8u io errors\n", io_error);
|
||||
} else {
|
||||
msg_status("Everything OK\n");
|
||||
}
|
||||
|
||||
if (error)
|
||||
log_fatal("DANGER! Unexpected errors!\n");
|
||||
if (io_error)
|
||||
log_fatal("DANGER! Unexpected input/output errors!\n");
|
||||
|
||||
free(handle);
|
||||
free(waiting_map);
|
||||
io_done(&io);
|
||||
|
||||
if (error + io_error != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)
|
||||
{
|
||||
block_off_t blockmax;
|
||||
int ret;
|
||||
struct snapraid_parity_handle parity_handle[LEV_MAX];
|
||||
unsigned error;
|
||||
unsigned l;
|
||||
|
||||
msg_progress("Drying...\n");
|
||||
|
||||
blockmax = parity_allocated_size(state);
|
||||
|
||||
if (blockstart > blockmax) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in the specified starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* adjust the number of block to process */
|
||||
if (blockcount != 0 && blockstart + blockcount < blockmax) {
|
||||
blockmax = blockstart + blockcount;
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
/* it may fail if the file doesn't exist, in this case we continue to dry the files */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("WARNING! Without an accessible %s file, it isn't possible to dry.\n", lev_name(l));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
/* skip degenerated cases of empty parity, or skipping all */
|
||||
if (blockstart < blockmax) {
|
||||
ret = state_dry_process(state, parity_handle, blockstart, blockmax);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* try to close only if opened */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
ret = parity_close(&parity_handle[l]);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* abort if required */
|
||||
if (error != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
160
cmdline/dup.c
Normal file
160
cmdline/dup.c
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "util.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "parity.h"
|
||||
#include "handle.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* dup */
|
||||
|
||||
struct snapraid_hash {
|
||||
struct snapraid_disk* disk; /**< Disk. */
|
||||
struct snapraid_file* file; /**< File. */
|
||||
unsigned char hash[HASH_MAX]; /**< Hash of the whole file. */
|
||||
|
||||
/* nodes for data structures */
|
||||
tommy_hashdyn_node node;
|
||||
};
|
||||
|
||||
struct snapraid_hash* hash_alloc(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file)
|
||||
{
|
||||
struct snapraid_hash* hash;
|
||||
block_off_t i;
|
||||
unsigned char* buf;
|
||||
|
||||
hash = malloc_nofail(sizeof(struct snapraid_hash));
|
||||
hash->disk = disk;
|
||||
hash->file = file;
|
||||
|
||||
buf = malloc_nofail(file->blockmax * BLOCK_HASH_SIZE);
|
||||
|
||||
/* set the back pointer */
|
||||
for (i = 0; i < file->blockmax; ++i) {
|
||||
struct snapraid_block* block = fs_file2block_get(file, i);
|
||||
|
||||
memcpy(buf + i * BLOCK_HASH_SIZE, block->hash, BLOCK_HASH_SIZE);
|
||||
|
||||
if (!block_has_updated_hash(block)) {
|
||||
free(buf);
|
||||
free(hash);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
memhash(state->besthash, state->hashseed, hash->hash, buf, file->blockmax * BLOCK_HASH_SIZE);
|
||||
|
||||
free(buf);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static inline tommy_uint32_t hash_hash(struct snapraid_hash* hash)
|
||||
{
|
||||
return tommy_hash_u32(0, hash->hash, HASH_MAX);
|
||||
}
|
||||
|
||||
void hash_free(struct snapraid_hash* hash)
|
||||
{
|
||||
free(hash);
|
||||
}
|
||||
|
||||
int hash_compare(const void* void_arg, const void* void_data)
|
||||
{
|
||||
const char* arg = void_arg;
|
||||
const struct snapraid_hash* hash = void_data;
|
||||
|
||||
return memcmp(arg, hash->hash, HASH_MAX);
|
||||
}
|
||||
|
||||
void state_dup(struct snapraid_state* state)
|
||||
{
|
||||
tommy_hashdyn hashset;
|
||||
tommy_node* i;
|
||||
unsigned count;
|
||||
data_off_t size;
|
||||
char esc_buffer[ESC_MAX];
|
||||
char esc_buffer_alt[ESC_MAX];
|
||||
|
||||
tommy_hashdyn_init(&hashset);
|
||||
|
||||
count = 0;
|
||||
size = 0;
|
||||
|
||||
msg_progress("Comparing...\n");
|
||||
|
||||
/* for each disk */
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
tommy_node* j;
|
||||
struct snapraid_disk* disk = i->data;
|
||||
|
||||
/* for each file */
|
||||
for (j = disk->filelist; j != 0; j = j->next) {
|
||||
struct snapraid_file* file = j->data;
|
||||
struct snapraid_hash* hash;
|
||||
tommy_hash_t hash32;
|
||||
|
||||
/* if empty, skip it */
|
||||
if (file->size == 0)
|
||||
continue;
|
||||
|
||||
hash = hash_alloc(state, disk, file);
|
||||
|
||||
/* if no hash, skip it */
|
||||
if (!hash)
|
||||
continue;
|
||||
|
||||
hash32 = hash_hash(hash);
|
||||
|
||||
struct snapraid_hash* found = tommy_hashdyn_search(&hashset, hash_compare, hash->hash, hash32);
|
||||
if (found) {
|
||||
++count;
|
||||
size += found->file->size;
|
||||
log_tag("dup:%s:%s:%s:%s:%" PRIu64 ": dup\n", disk->name, esc_tag(file->sub, esc_buffer), found->disk->name, esc_tag(found->file->sub, esc_buffer_alt), found->file->size);
|
||||
printf("%12" PRIu64 " %s = %s\n", file->size, fmt_term(disk, file->sub, esc_buffer), fmt_term(found->disk, found->file->sub, esc_buffer_alt));
|
||||
hash_free(hash);
|
||||
} else {
|
||||
tommy_hashdyn_insert(&hashset, &hash->node, hash, hash32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tommy_hashdyn_foreach(&hashset, (tommy_foreach_func*)hash_free);
|
||||
tommy_hashdyn_done(&hashset);
|
||||
|
||||
msg_status("\n");
|
||||
msg_status("%8u duplicates, for %" PRIu64 " GB\n", count, size / GIGA);
|
||||
if (count)
|
||||
msg_status("There are duplicates!\n");
|
||||
else
|
||||
msg_status("No duplicates\n");
|
||||
|
||||
log_tag("summary:dup_count:%u\n", count);
|
||||
log_tag("summary:dup_size:%" PRIu64 "\n", size);
|
||||
if (count == 0) {
|
||||
log_tag("summary:exit:unique\n");
|
||||
} else {
|
||||
log_tag("summary:exit:dup\n");
|
||||
}
|
||||
log_flush();
|
||||
}
|
||||
|
1461
cmdline/elem.c
Normal file
1461
cmdline/elem.c
Normal file
File diff suppressed because it is too large
Load Diff
1234
cmdline/elem.h
Normal file
1234
cmdline/elem.h
Normal file
File diff suppressed because it is too large
Load Diff
500
cmdline/fnmatch.c
Normal file
500
cmdline/fnmatch.c
Normal file
@ -0,0 +1,500 @@
|
||||
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if !HAVE_FNMATCH
|
||||
|
||||
/* Enable GNU extensions in fnmatch.h. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#if HAVE_FNMATCH_H
|
||||
#include <fnmatch.h>
|
||||
#else
|
||||
#include "fnmatch.h"
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
|
||||
#if HAVE_STRING_H || defined _LIBC
|
||||
# include <string.h>
|
||||
#else
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#if defined STDC_HEADERS || defined _LIBC
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* For platforms which support the ISO C amendment 1 functionality we
|
||||
support user defined character classes. */
|
||||
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
#endif
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined _LIBC || !defined __GNU_LIBRARY__
|
||||
|
||||
|
||||
# if defined STDC_HEADERS || !defined isascii
|
||||
# define ISASCII(c) 1
|
||||
# else
|
||||
# define ISASCII(c) isascii(c)
|
||||
# endif
|
||||
|
||||
# ifdef isblank
|
||||
# define ISBLANK(c) (ISASCII (c) && isblank (c))
|
||||
# else
|
||||
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
|
||||
# endif
|
||||
# ifdef isgraph
|
||||
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
|
||||
# else
|
||||
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
|
||||
# endif
|
||||
|
||||
# define ISPRINT(c) (ISASCII (c) && isprint (c))
|
||||
# define ISDIGIT(c) (ISASCII (c) && isdigit (c))
|
||||
# define ISALNUM(c) (ISASCII (c) && isalnum (c))
|
||||
# define ISALPHA(c) (ISASCII (c) && isalpha (c))
|
||||
# define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
|
||||
# define ISLOWER(c) (ISASCII (c) && islower (c))
|
||||
# define ISPUNCT(c) (ISASCII (c) && ispunct (c))
|
||||
# define ISSPACE(c) (ISASCII (c) && isspace (c))
|
||||
# define ISUPPER(c) (ISASCII (c) && isupper (c))
|
||||
# define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
|
||||
|
||||
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
/* The GNU C library provides support for user-defined character classes
|
||||
and the functions from ISO C amendment 1. */
|
||||
# ifdef CHARCLASS_NAME_MAX
|
||||
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
|
||||
# else
|
||||
/* This shouldn't happen but some implementation might still have this
|
||||
problem. Use a reasonable default value. */
|
||||
# define CHAR_CLASS_MAX_LENGTH 256
|
||||
# endif
|
||||
|
||||
# ifdef _LIBC
|
||||
# define IS_CHAR_CLASS(string) __wctype (string)
|
||||
# else
|
||||
# define IS_CHAR_CLASS(string) wctype (string)
|
||||
# endif
|
||||
# else
|
||||
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
|
||||
|
||||
# define IS_CHAR_CLASS(string) \
|
||||
(STREQ (string, "alpha") || STREQ (string, "upper") \
|
||||
|| STREQ (string, "lower") || STREQ (string, "digit") \
|
||||
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|
||||
|| STREQ (string, "space") || STREQ (string, "print") \
|
||||
|| STREQ (string, "punct") || STREQ (string, "graph") \
|
||||
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
|
||||
# endif
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
# if !defined _LIBC && !defined getenv
|
||||
extern char *getenv ();
|
||||
# endif
|
||||
|
||||
# ifndef errno
|
||||
extern int errno;
|
||||
# endif
|
||||
|
||||
/* This function doesn't exist on most systems. */
|
||||
|
||||
# if !defined HAVE___STRCHRNUL && !defined _LIBC
|
||||
static char *
|
||||
__strchrnul (s, c)
|
||||
const char *s;
|
||||
int c;
|
||||
{
|
||||
char *result = strchr (s, c);
|
||||
if (result == NULL)
|
||||
result = strchr (s, '\0');
|
||||
return result;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifndef internal_function
|
||||
/* Inside GNU libc we mark some function in a special way. In other
|
||||
environments simply ignore the marking. */
|
||||
# define internal_function
|
||||
# endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
static int internal_fnmatch __P ((const char *pattern, const char *string,
|
||||
int no_leading_period, int flags))
|
||||
internal_function;
|
||||
static int
|
||||
internal_function
|
||||
internal_fnmatch (pattern, string, no_leading_period, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int no_leading_period;
|
||||
int flags;
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register unsigned char c;
|
||||
|
||||
/* Note that this evaluates C many times. */
|
||||
# ifdef _LIBC
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
|
||||
# else
|
||||
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
|
||||
# endif
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
return FNM_NOMATCH;
|
||||
else if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
if (c == '\0')
|
||||
/* Trailing \ loses. */
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD ((unsigned char) *n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if (*n == '.' && no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++)
|
||||
{
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* A slash does not match a wildcard under FNM_FILE_NAME. */
|
||||
return FNM_NOMATCH;
|
||||
else if (c == '?')
|
||||
{
|
||||
/* A ? needs to match one character. */
|
||||
if (*n == '\0')
|
||||
/* There isn't another character; no match. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
/* One character of the string is consumed in matching
|
||||
this ? wildcard, so *??? won't match if there are
|
||||
less than three characters. */
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\0')
|
||||
/* The wildcard(s) is/are the last element of the pattern.
|
||||
If the name is a file name and contains another slash
|
||||
this does mean it cannot match. */
|
||||
return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
|
||||
? FNM_NOMATCH : 0);
|
||||
else
|
||||
{
|
||||
const char *endp;
|
||||
|
||||
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
|
||||
|
||||
if (c == '[')
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
for (--p; n < endp; ++n)
|
||||
if (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2)
|
||||
== 0)
|
||||
return 0;
|
||||
}
|
||||
else if (c == '/' && (flags & FNM_FILE_NAME))
|
||||
{
|
||||
while (*n != '\0' && *n != '/')
|
||||
++n;
|
||||
if (*n == '/'
|
||||
&& (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
|
||||
flags) == 0))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int flags2 = ((flags & FNM_FILE_NAME)
|
||||
? flags : (flags & ~FNM_PERIOD));
|
||||
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c = *p;
|
||||
c = FOLD (c);
|
||||
for (--p; n < endp; ++n)
|
||||
if (FOLD ((unsigned char) *n) == c
|
||||
&& (internal_fnmatch (p, n,
|
||||
(no_leading_period
|
||||
&& (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME)))),
|
||||
flags2) == 0))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we come here no match is possible with the wildcard. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
static int posixly_correct;
|
||||
register int not;
|
||||
char cold;
|
||||
|
||||
if (posixly_correct == 0)
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '.' && no_leading_period && (n == string
|
||||
|| (n[-1] == '/'
|
||||
&& (flags
|
||||
& FNM_FILE_NAME))))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (*n == '/' && (flags & FNM_FILE_NAME))
|
||||
/* `/' cannot be matched. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
unsigned char fn = FOLD ((unsigned char) *n);
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD ((unsigned char) *p);
|
||||
++p;
|
||||
|
||||
if (c == fn)
|
||||
goto matched;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
/* Leave room for the null. */
|
||||
char str[CHAR_CLASS_MAX_LENGTH + 1];
|
||||
size_t c1 = 0;
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wctype_t wt;
|
||||
# endif
|
||||
const char *startp = p;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (c1 == CHAR_CLASS_MAX_LENGTH)
|
||||
/* The name is too long and therefore the pattern
|
||||
is ill-formed. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *++p;
|
||||
if (c == ':' && p[1] == ']')
|
||||
{
|
||||
p += 2;
|
||||
break;
|
||||
}
|
||||
if (c < 'a' || c >= 'z')
|
||||
{
|
||||
/* This cannot possibly be a character class name.
|
||||
Match it as a normal range. */
|
||||
p = startp;
|
||||
c = '[';
|
||||
goto normal_bracket;
|
||||
}
|
||||
str[c1++] = c;
|
||||
}
|
||||
str[c1] = '\0';
|
||||
|
||||
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
|
||||
wt = IS_CHAR_CLASS (str);
|
||||
if (wt == 0)
|
||||
/* Invalid character class name. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (__iswctype (__btowc ((unsigned char) *n), wt))
|
||||
goto matched;
|
||||
# else
|
||||
if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
|
||||
|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
|
||||
|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
|
||||
|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
|
||||
|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
|
||||
|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
|
||||
|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
|
||||
|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
|
||||
|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
|
||||
|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
|
||||
|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
|
||||
|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
|
||||
goto matched;
|
||||
# endif
|
||||
}
|
||||
else if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
else
|
||||
{
|
||||
normal_bracket:
|
||||
if (FOLD (c) == fn)
|
||||
goto matched;
|
||||
|
||||
cold = c;
|
||||
c = *p++;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
/* It is a range. */
|
||||
unsigned char cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (cold <= fn && fn <= FOLD (cend))
|
||||
goto matched;
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == ']')
|
||||
break;
|
||||
}
|
||||
|
||||
if (!not)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
matched:
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
while (c != ']')
|
||||
{
|
||||
if (c == '\0')
|
||||
/* [... (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
{
|
||||
if (*p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
else if (c == '[' && *p == ':')
|
||||
{
|
||||
do
|
||||
if (*++p == '\0')
|
||||
return FNM_NOMATCH;
|
||||
while (*p != ':' || p[1] == ']');
|
||||
p += 2;
|
||||
c = *p;
|
||||
}
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD ((unsigned char) *n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
|
||||
# undef FOLD
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
{
|
||||
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#else
|
||||
|
||||
/* avoid the warning: ISO C forbids an empty translation unit */
|
||||
extern int make_iso_compilers_happy;
|
||||
|
||||
#endif
|
||||
|
82
cmdline/fnmatch.h
Normal file
82
cmdline/fnmatch.h
Normal file
@ -0,0 +1,82 @@
|
||||
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
#define _FNMATCH_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
|
||||
# if !defined __GLIBC__ || !defined __P
|
||||
# undef __P
|
||||
# define __P(protos) protos
|
||||
# endif
|
||||
#else /* Not C++ or ANSI C. */
|
||||
# undef __P
|
||||
# define __P(protos) ()
|
||||
/* We can get away without defining `const' here only because in this file
|
||||
it is used only inside the prototype for `fnmatch', which is elided in
|
||||
non-ANSI C where `const' is problematical. */
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
#ifndef const
|
||||
# if (defined __STDC__ && __STDC__) || defined __cplusplus
|
||||
# define __const const
|
||||
# else
|
||||
# define __const
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* We #undef these before defining them because some losing systems
|
||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
|
||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
||||
|
||||
#if !defined _POSIX_C_SOURCE || _POSIX_C_SOURCE < 2 || defined _GNU_SOURCE
|
||||
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
||||
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
||||
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
/* This value is returned if the implementation does not support
|
||||
`fnmatch'. Since this is not the case here it will never be
|
||||
returned but the conformance test suites still require the symbol
|
||||
to be defined. */
|
||||
#ifdef _XOPEN_SOURCE
|
||||
# define FNM_NOSYS (-1)
|
||||
#endif
|
||||
|
||||
/* Match NAME against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int fnmatch __P ((__const char *__pattern, __const char *__name,
|
||||
int __flags));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* fnmatch.h */
|
403
cmdline/handle.c
Normal file
403
cmdline/handle.c
Normal file
@ -0,0 +1,403 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "elem.h"
|
||||
#include "support.h"
|
||||
#include "handle.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* handle */
|
||||
|
||||
int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode)
|
||||
{
|
||||
int ret;
|
||||
int flags;
|
||||
|
||||
/* if it's the same file, and already opened, nothing to do */
|
||||
if (handle->file == file && handle->f != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
advise_init(&handle->advise, mode);
|
||||
pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
|
||||
|
||||
ret = mkancestor(handle->path);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* initial values, changed later if required */
|
||||
handle->created = 0;
|
||||
|
||||
/* flags for opening */
|
||||
/* O_BINARY: open as binary file (Windows only) */
|
||||
/* O_NOFOLLOW: do not follow links to ensure to open the real file */
|
||||
flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
|
||||
|
||||
/* open for read write */
|
||||
handle->f = open(handle->path, flags | O_RDWR);
|
||||
|
||||
/* if failed for missing write permission */
|
||||
if (handle->f == -1 && (errno == EACCES || errno == EROFS)) {
|
||||
/* open for real-only */
|
||||
handle->f = open(handle->path, flags | O_RDONLY);
|
||||
}
|
||||
|
||||
/* if failed for missing file */
|
||||
if (handle->f == -1 && errno == ENOENT) {
|
||||
char path_from[PATH_MAX];
|
||||
|
||||
/* check if exists a .unrecoverable copy, and rename to the real one */
|
||||
pathprint(path_from, sizeof(path_from), "%s.unrecoverable", handle->path);
|
||||
|
||||
if (rename(path_from, handle->path) == 0) {
|
||||
/* open for read write */
|
||||
handle->f = open(handle->path, flags | O_RDWR);
|
||||
} else {
|
||||
/* create it */
|
||||
handle->f = open(handle->path, flags | O_RDWR | O_CREAT, 0600);
|
||||
if (handle->f != -1) {
|
||||
/* mark it as created if really done */
|
||||
handle->created = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (handle->f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
/* invalidate for error */
|
||||
handle->file = 0;
|
||||
handle->f = -1;
|
||||
handle->valid_size = 0;
|
||||
|
||||
log_fatal("Error opening file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* just opened */
|
||||
handle->file = file;
|
||||
|
||||
/* get the stat info */
|
||||
ret = fstat(handle->f, &handle->st);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* get the size of the existing data */
|
||||
handle->valid_size = handle->st.st_size;
|
||||
|
||||
ret = advise_open(&handle->advise, handle->f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error advising file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ftruncate(handle->f, file->size);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
if (errno == EACCES) {
|
||||
log_fatal("Failed to truncate file '%s' for missing write permission.\n", handle->path);
|
||||
} else {
|
||||
log_fatal("Error truncating file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
}
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* adjust the size to the truncated size */
|
||||
handle->valid_size = file->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing)
|
||||
{
|
||||
int ret;
|
||||
int flags;
|
||||
|
||||
if (!out_missing)
|
||||
out_missing = out;
|
||||
|
||||
/* if already opened, nothing to do */
|
||||
if (handle->file == file && handle->file != 0 && handle->f != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
advise_init(&handle->advise, mode);
|
||||
pathprint(handle->path, sizeof(handle->path), "%s%s", handle->disk->dir, file->sub);
|
||||
|
||||
/* for sure not created */
|
||||
handle->created = 0;
|
||||
|
||||
/* flags for opening */
|
||||
/* O_BINARY: open as binary file (Windows only) */
|
||||
/* O_NOFOLLOW: do not follow links to ensure to open the real file */
|
||||
flags = O_BINARY | O_NOFOLLOW | advise_flags(&handle->advise);
|
||||
|
||||
/* open for read */
|
||||
handle->f = open_noatime(handle->path, flags | O_RDONLY);
|
||||
if (handle->f == -1) {
|
||||
/* invalidate for error */
|
||||
handle->file = 0;
|
||||
handle->f = -1;
|
||||
handle->valid_size = 0;
|
||||
|
||||
if (errno == ENOENT)
|
||||
out_missing("Missing file '%s'.\n", handle->path);
|
||||
else
|
||||
out("Error opening file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* just opened */
|
||||
handle->file = file;
|
||||
|
||||
/* get the stat info */
|
||||
ret = fstat(handle->f, &handle->st);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Error accessing file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* get the size of the existing data */
|
||||
handle->valid_size = handle->st.st_size;
|
||||
|
||||
ret = advise_open(&handle->advise, handle->f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Error advising file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_close(struct snapraid_handle* handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* close if open */
|
||||
if (handle->f != -1) {
|
||||
ret = close(handle->f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file '%s'. %s.\n", handle->file->sub, strerror(errno));
|
||||
|
||||
/* invalidate for error */
|
||||
handle->file = 0;
|
||||
handle->f = -1;
|
||||
handle->valid_size = 0;
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* reset the descriptor */
|
||||
handle->file = 0;
|
||||
handle->f = -1;
|
||||
handle->valid_size = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing)
|
||||
{
|
||||
ssize_t read_ret;
|
||||
data_off_t offset;
|
||||
unsigned read_size;
|
||||
unsigned count;
|
||||
int ret;
|
||||
|
||||
offset = file_pos * (data_off_t)block_size;
|
||||
|
||||
if (!out_missing)
|
||||
out_missing = out;
|
||||
|
||||
/* check if we are going to read only not initialized data */
|
||||
if (offset >= handle->valid_size) {
|
||||
/* if the file is missing, it's at 0 size, or it's rebuilt while reading */
|
||||
if (offset == handle->valid_size || handle->valid_size == 0)
|
||||
out_missing("Reading data from missing file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
|
||||
else
|
||||
out("Reading missing data from file '%s' at offset %" PRIu64 ".\n", handle->path, offset);
|
||||
return -1;
|
||||
}
|
||||
|
||||
read_size = file_block_size(handle->file, file_pos, block_size);
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
/* read the full block to support O_DIRECT */
|
||||
read_ret = pread(handle->f, block_buffer + count, block_size - count, offset + count);
|
||||
if (read_ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", handle->path, offset + count, block_size - count, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (read_ret == 0) {
|
||||
out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", handle->path, offset, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
count += read_ret;
|
||||
} while (count < read_size);
|
||||
|
||||
/* pad with 0 */
|
||||
if (read_size < block_size) {
|
||||
memset(block_buffer + read_size, 0, block_size - read_size);
|
||||
}
|
||||
|
||||
ret = advise_read(&handle->advise, handle->f, offset, block_size);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Error advising file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return read_size;
|
||||
}
|
||||
|
||||
int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size)
|
||||
{
|
||||
ssize_t write_ret;
|
||||
data_off_t offset;
|
||||
unsigned write_size;
|
||||
int ret;
|
||||
|
||||
offset = file_pos * (data_off_t)block_size;
|
||||
|
||||
write_size = file_block_size(handle->file, file_pos, block_size);
|
||||
|
||||
write_ret = pwrite(handle->f, block_buffer, write_size, offset);
|
||||
if (write_ret != (ssize_t)write_size) { /* conversion is safe because block_size is always small */
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* adjust the size of the valid data */
|
||||
if (handle->valid_size < offset + write_size) {
|
||||
handle->valid_size = offset + write_size;
|
||||
}
|
||||
|
||||
ret = advise_write(&handle->advise, handle->f, offset, block_size);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error advising file '%s'. %s.\n", handle->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_utime(struct snapraid_handle* handle)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* do nothing if not opened */
|
||||
if (handle->f == -1)
|
||||
return 0;
|
||||
|
||||
ret = fmtime(handle->f, handle->file->mtime_sec, handle->file->mtime_nsec);
|
||||
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error timing file '%s'. %s.\n", handle->file->sub, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct snapraid_handle* handle_mapping(struct snapraid_state* state, unsigned* handlemax)
|
||||
{
|
||||
tommy_node* i;
|
||||
unsigned j;
|
||||
unsigned size = 0;
|
||||
struct snapraid_handle* handle;
|
||||
|
||||
/* get the size of the mapping */
|
||||
size = 0;
|
||||
for (i = state->maplist; i != 0; i = i->next) {
|
||||
struct snapraid_map* map = i->data;
|
||||
if (map->position > size)
|
||||
size = map->position;
|
||||
}
|
||||
++size; /* size is one more than the max */
|
||||
|
||||
handle = malloc_nofail(size * sizeof(struct snapraid_handle));
|
||||
|
||||
for (j = 0; j < size; ++j) {
|
||||
/* default for empty position */
|
||||
handle[j].disk = 0;
|
||||
handle[j].file = 0;
|
||||
handle[j].f = -1;
|
||||
handle[j].valid_size = 0;
|
||||
}
|
||||
|
||||
/* set the vector */
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
struct snapraid_map* map;
|
||||
struct snapraid_disk* disk = i->data;
|
||||
tommy_node* k;
|
||||
|
||||
/* search the mapping for this disk */
|
||||
map = 0;
|
||||
for (k = state->maplist; k != 0; k = k->next) {
|
||||
map = k->data;
|
||||
if (strcmp(disk->name, map->name) == 0)
|
||||
break;
|
||||
}
|
||||
if (!map) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal error for inconsistent disk mapping.\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
handle[map->position].disk = disk;
|
||||
}
|
||||
|
||||
*handlemax = size;
|
||||
return handle;
|
||||
}
|
||||
|
88
cmdline/handle.h
Normal file
88
cmdline/handle.h
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __HANDLE_H
|
||||
#define __HANDLE_H
|
||||
|
||||
#include "state.h"
|
||||
#include "support.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* handle */
|
||||
|
||||
struct snapraid_handle {
|
||||
char path[PATH_MAX]; /**< Path of the file. */
|
||||
struct snapraid_disk* disk; /**< Disk of the file. */
|
||||
struct snapraid_file* file; /**< File opened. When the file is closed, it's set to 0. */
|
||||
int f; /**< Handle of the file. */
|
||||
struct stat st; /**< Stat info of the opened file. */
|
||||
struct advise_struct advise; /**< Advise information. */
|
||||
data_off_t valid_size; /**< Size of the valid data. */
|
||||
int created; /**< If the file was created, otherwise it was already existing. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a file.
|
||||
* The file is created if missing, and opened with write access.
|
||||
* If the file is created, the handle->created is set.
|
||||
* The initial size of the file is stored in the file->st struct.
|
||||
* If the file cannot be opened for write access, it's opened with read-only access.
|
||||
* The read-only access works only if the file has already the correct size and doesn't need to be modified.
|
||||
*/
|
||||
int handle_create(struct snapraid_handle* handle, struct snapraid_file* file, int mode);
|
||||
|
||||
/**
|
||||
* Truncate a file if required.
|
||||
*/
|
||||
int handle_truncate(struct snapraid_handle* handle, struct snapraid_file* file);
|
||||
|
||||
/**
|
||||
* Open a file.
|
||||
* The file is opened for reading.
|
||||
*/
|
||||
int handle_open(struct snapraid_handle* handle, struct snapraid_file* file, int mode, fptr* out, fptr* out_missing);
|
||||
|
||||
/**
|
||||
* Close a file.
|
||||
*/
|
||||
int handle_close(struct snapraid_handle* handle);
|
||||
|
||||
/**
|
||||
* Read a block from a file.
|
||||
* If the read block is shorter, it's padded with 0.
|
||||
*/
|
||||
int handle_read(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size, fptr* out, fptr* out_missing);
|
||||
|
||||
/**
|
||||
* Write a block to a file.
|
||||
*/
|
||||
int handle_write(struct snapraid_handle* handle, block_off_t file_pos, unsigned char* block_buffer, unsigned block_size);
|
||||
|
||||
/**
|
||||
* Change the modification time of the file to the saved value.
|
||||
*/
|
||||
int handle_utime(struct snapraid_handle* handle);
|
||||
|
||||
/**
|
||||
* Map the unsorted list of disk to an ordered vector.
|
||||
* \param diskmax The size of the vector.
|
||||
* \return The allocated vector of pointers.
|
||||
*/
|
||||
struct snapraid_handle* handle_mapping(struct snapraid_state* state, unsigned* diskmax);
|
||||
|
||||
#endif
|
||||
|
322
cmdline/import.c
Normal file
322
cmdline/import.c
Normal file
@ -0,0 +1,322 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "import.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* import */
|
||||
|
||||
/**
|
||||
* Compare the hash of two import blocks.
|
||||
*/
|
||||
int import_block_hash_compare(const void* void_arg, const void* void_data)
|
||||
{
|
||||
const unsigned char* arg = void_arg;
|
||||
const struct snapraid_import_block* block = void_data;
|
||||
|
||||
return memcmp(arg, block->hash, BLOCK_HASH_SIZE);
|
||||
}
|
||||
|
||||
int import_block_prevhash_compare(const void* void_arg, const void* void_data)
|
||||
{
|
||||
const unsigned char* arg = void_arg;
|
||||
const struct snapraid_import_block* block = void_data;
|
||||
|
||||
return memcmp(arg, block->prevhash, BLOCK_HASH_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the hash of the hash for an import block.
|
||||
* We just use the first 32 bit of the hash itself.
|
||||
*/
|
||||
static inline tommy_uint32_t import_block_hash(const unsigned char* hash)
|
||||
{
|
||||
/* the hash data is not aligned, and we cannot access it with a direct cast */
|
||||
return hash[0] | ((uint32_t)hash[1] << 8) | ((uint32_t)hash[2] << 16) | ((uint32_t)hash[3] << 24);
|
||||
}
|
||||
|
||||
static void import_file(struct snapraid_state* state, const char* path, uint64_t size)
|
||||
{
|
||||
struct snapraid_import_file* file;
|
||||
block_off_t i;
|
||||
data_off_t offset;
|
||||
void* buffer;
|
||||
int ret;
|
||||
int f;
|
||||
int flags;
|
||||
unsigned block_size = state->block_size;
|
||||
struct advise_struct advise;
|
||||
|
||||
file = malloc_nofail(sizeof(struct snapraid_import_file));
|
||||
file->path = strdup_nofail(path);
|
||||
file->size = size;
|
||||
file->blockmax = (size + block_size - 1) / block_size;
|
||||
file->blockimp = malloc_nofail(file->blockmax * sizeof(struct snapraid_import_block));
|
||||
|
||||
buffer = malloc_nofail(block_size);
|
||||
|
||||
advise_init(&advise, state->file_mode);
|
||||
|
||||
/* open for read */
|
||||
flags = O_RDONLY | O_BINARY | advise_flags(&advise);
|
||||
f = open(path, flags);
|
||||
if (f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = advise_open(&advise, f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error advising file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
for (i = 0; i < file->blockmax; ++i) {
|
||||
struct snapraid_import_block* block = &file->blockimp[i];
|
||||
unsigned read_size = block_size;
|
||||
if (read_size > size)
|
||||
read_size = size;
|
||||
|
||||
ret = read(f, buffer, read_size);
|
||||
if (ret < 0 || (unsigned)ret != read_size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reading file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
block->file = file;
|
||||
block->offset = offset;
|
||||
block->size = read_size;
|
||||
|
||||
memhash(state->hash, state->hashseed, block->hash, buffer, read_size);
|
||||
tommy_hashdyn_insert(&state->importset, &block->nodeset, block, import_block_hash(block->hash));
|
||||
|
||||
/* if we are in a rehash state */
|
||||
if (state->prevhash != HASH_UNDEFINED) {
|
||||
/* compute also the previous hash */
|
||||
memhash(state->prevhash, state->prevhashseed, block->prevhash, buffer, read_size);
|
||||
tommy_hashdyn_insert(&state->previmportset, &block->prevnodeset, block, import_block_hash(block->prevhash));
|
||||
}
|
||||
|
||||
offset += read_size;
|
||||
size -= read_size;
|
||||
}
|
||||
|
||||
ret = close(f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
tommy_list_insert_tail(&state->importlist, &file->nodelist, file);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void import_file_free(struct snapraid_import_file* file)
|
||||
{
|
||||
free(file->path);
|
||||
free(file->blockimp);
|
||||
free(file);
|
||||
}
|
||||
|
||||
int state_import_fetch(struct snapraid_state* state, int rehash, struct snapraid_block* missing_block, unsigned char* buffer)
|
||||
{
|
||||
struct snapraid_import_block* block;
|
||||
int ret;
|
||||
int f;
|
||||
const unsigned char* hash = missing_block->hash;
|
||||
unsigned block_size = state->block_size;
|
||||
unsigned read_size;
|
||||
unsigned char buffer_hash[HASH_MAX];
|
||||
const char* path;
|
||||
|
||||
if (rehash) {
|
||||
block = tommy_hashdyn_search(&state->previmportset, import_block_prevhash_compare, hash, import_block_hash(hash));
|
||||
} else {
|
||||
block = tommy_hashdyn_search(&state->importset, import_block_hash_compare, hash, import_block_hash(hash));
|
||||
}
|
||||
if (!block)
|
||||
return -1;
|
||||
|
||||
path = block->file->path;
|
||||
read_size = block->size;
|
||||
|
||||
f = open(path, O_RDONLY | O_BINARY);
|
||||
if (f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
if (errno == ENOENT) {
|
||||
log_fatal("DANGER! file '%s' disappeared.\n", path);
|
||||
log_fatal("If you moved it, please rerun the same command.\n");
|
||||
} else {
|
||||
log_fatal("Error opening file '%s'. %s.\n", path, strerror(errno));
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = pread(f, buffer, read_size, block->offset);
|
||||
if (ret < 0 || (unsigned)ret != read_size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reading file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = close(f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (read_size != block_size) {
|
||||
/* fill the remaining with 0 */
|
||||
memset(buffer + read_size, 0, block_size - read_size);
|
||||
}
|
||||
|
||||
/* recheck the hash */
|
||||
if (rehash)
|
||||
memhash(state->prevhash, state->prevhashseed, buffer_hash, buffer, read_size);
|
||||
else
|
||||
memhash(state->hash, state->hashseed, buffer_hash, buffer, read_size);
|
||||
|
||||
if (memcmp(buffer_hash, hash, BLOCK_HASH_SIZE) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in data reading file '%s'.\n", path);
|
||||
log_fatal("Please don't change imported files while running.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void import_dir(struct snapraid_state* state, const char* dir)
|
||||
{
|
||||
DIR* d;
|
||||
|
||||
d = opendir(dir);
|
||||
if (!d) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
while (1) {
|
||||
char path_next[PATH_MAX];
|
||||
struct stat st;
|
||||
const char* name;
|
||||
struct dirent* dd;
|
||||
|
||||
/* clear errno to detect erroneous conditions */
|
||||
errno = 0;
|
||||
dd = readdir(d);
|
||||
if (dd == 0 && errno != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (dd == 0) {
|
||||
break; /* finished */
|
||||
}
|
||||
|
||||
/* skip "." and ".." files */
|
||||
name = dd->d_name;
|
||||
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
|
||||
continue;
|
||||
|
||||
pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
|
||||
|
||||
#if HAVE_STRUCT_DIRENT_D_STAT
|
||||
/* convert dirent to lstat result */
|
||||
dirent_lstat(dd, &st);
|
||||
|
||||
/* if the st_mode field is missing, takes care to fill it using normal lstat() */
|
||||
/* at now this can happen only in Windows (with HAVE_STRUCT_DIRENT_D_STAT defined), */
|
||||
/* because we use a directory reading method that doesn't read info about ReparsePoint. */
|
||||
/* Note that here we cannot call here lstat_sync(), because we don't know what kind */
|
||||
/* of file is it, and lstat_sync() doesn't always work */
|
||||
if (st.st_mode == 0) {
|
||||
if (lstat(path_next, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* get lstat info about the file */
|
||||
if (lstat(path_next, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
import_file(state, path_next, st.st_size);
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
pathslash(path_next, sizeof(path_next));
|
||||
import_dir(state, path_next);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(d) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
void state_import(struct snapraid_state* state, const char* dir)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
msg_progress("Importing...\n");
|
||||
|
||||
/* if the hash is not full */
|
||||
if (BLOCK_HASH_SIZE != HASH_MAX) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You cannot import files when using a reduced hash.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* add the final slash */
|
||||
pathimport(path, sizeof(path), dir);
|
||||
pathslash(path, sizeof(path));
|
||||
|
||||
import_dir(state, path);
|
||||
}
|
||||
|
74
cmdline/import.h
Normal file
74
cmdline/import.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __IMPORT_H
|
||||
#define __IMPORT_H
|
||||
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* import */
|
||||
|
||||
/**
|
||||
* Import block.
|
||||
* Block used to import data external when recovering by hash.
|
||||
*/
|
||||
struct snapraid_import_block {
|
||||
struct snapraid_import_file* file; /**< Back pointer to the file owning this block. */
|
||||
unsigned size; /**< Size of the block. */
|
||||
data_off_t offset; /**< Position of the block in the file. */
|
||||
unsigned char hash[HASH_MAX]; /**< Hash of the block. */
|
||||
unsigned char prevhash[HASH_MAX]; /**< Previous hash of the block. Valid only if we are in rehash state. */
|
||||
|
||||
/* nodes for data structures */
|
||||
tommy_hashdyn_node nodeset;
|
||||
tommy_hashdyn_node prevnodeset;
|
||||
};
|
||||
|
||||
/**
|
||||
* Import file.
|
||||
* File used to import data external when recovering by hash.
|
||||
*/
|
||||
struct snapraid_import_file {
|
||||
data_off_t size; /**< Size of the file. */
|
||||
struct snapraid_import_block* blockimp; /**< All the blocks of the file. */
|
||||
block_off_t blockmax; /**< Number of blocks. */
|
||||
char* path; /**< Full path of the file. */
|
||||
|
||||
/* nodes for data structures */
|
||||
tommy_node nodelist;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deallocate an import file.
|
||||
*/
|
||||
void import_file_free(struct snapraid_import_file* file);
|
||||
|
||||
/**
|
||||
* Fetch a block from the specified hash.
|
||||
* Return ==0 if the block is found, and copied into buffer.
|
||||
*/
|
||||
int state_import_fetch(struct snapraid_state* state, int prevhash, struct snapraid_block* missing_block, unsigned char* buffer);
|
||||
|
||||
/**
|
||||
* Import files from the specified directory.
|
||||
*/
|
||||
void state_import(struct snapraid_state* state, const char* dir);
|
||||
|
||||
#endif
|
||||
|
1006
cmdline/io.c
Normal file
1006
cmdline/io.c
Normal file
File diff suppressed because it is too large
Load Diff
400
cmdline/io.h
Normal file
400
cmdline/io.h
Normal file
@ -0,0 +1,400 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __IO_H
|
||||
#define __IO_H
|
||||
|
||||
#include "state.h"
|
||||
#include "support.h"
|
||||
#include "handle.h"
|
||||
#include "parity.h"
|
||||
|
||||
/**
|
||||
* Number of read-ahead buffers.
|
||||
*
|
||||
* More buffers always result in better performance.
|
||||
*
|
||||
* This is the scrub performance on my machine with different buffers:
|
||||
*
|
||||
* 1 - 380 MB/s, CPU 26%, speed 100% [SnapRAID 9.2]
|
||||
* 2 - 426 MB/s, CPU 46%, speed 112%
|
||||
* 4 - 452 MB/s, CPU 54%, speed 118%
|
||||
* 8 - 487 MB/s, CPU 60%, speed 128%
|
||||
* 16 - 505 MB/s, CPU 63%, speed 132%
|
||||
* 32 - 520 MB/s, CPU 64%, speed 136%
|
||||
* 64 - 524 MB/s, CPU 65%, speed 137%
|
||||
* 128 - 525 MB/s, CPU 66%, speed 138%
|
||||
*/
|
||||
#define IO_MIN 3 /* required by writers, readers can work also with 2 */
|
||||
#define IO_MAX 128
|
||||
|
||||
/**
|
||||
* State of the task.
|
||||
*/
|
||||
#define TASK_STATE_IOERROR_CONTINUE -4 /**< IO error. Continuation requested. */
|
||||
#define TASK_STATE_ERROR_CONTINUE -3 /**< Generic error. Continuation requested. */
|
||||
#define TASK_STATE_IOERROR -2 /**< IO error. Failure requested. */
|
||||
#define TASK_STATE_ERROR -1 /**< Generic error. Failure requested. */
|
||||
#define TASK_STATE_EMPTY 0 /**< Nothing to do. */
|
||||
#define TASK_STATE_READY 1 /**< Ready to start. */
|
||||
#define TASK_STATE_DONE 2 /**< Task completed. */
|
||||
|
||||
/**
|
||||
* Task of work.
|
||||
*
|
||||
* This represents the minimal element of work that worker threads are
|
||||
* going to be asked to do.
|
||||
*
|
||||
* It consists in reading a block of data from a disk.
|
||||
*
|
||||
* Note that the disk to use is defined implicitly in the worker thread.
|
||||
*/
|
||||
struct snapraid_task {
|
||||
int state; /**< State of the task. One of the TASK_STATE_*. */
|
||||
char path[PATH_MAX]; /**< Path of the file. */
|
||||
struct snapraid_disk* disk; /**< Disk of the file. */
|
||||
unsigned char* buffer; /**< Where to read the data. */
|
||||
block_off_t position; /**< Parity position to read. */
|
||||
|
||||
/**
|
||||
* Result of the task.
|
||||
*/
|
||||
struct snapraid_block* block;
|
||||
struct snapraid_file* file;
|
||||
block_off_t file_pos;
|
||||
int read_size; /**< Size of the data read. */
|
||||
int is_timestamp_different; /**< Report if file has a changed timestamp. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Worker for tasks.
|
||||
*
|
||||
* This represents a worker thread designated to read data
|
||||
* from a specific disk.
|
||||
*/
|
||||
struct snapraid_worker {
|
||||
#if HAVE_PTHREAD
|
||||
pthread_t thread; /**< Thread context for the worker. */
|
||||
#endif
|
||||
|
||||
struct snapraid_io* io; /**< Parent pointer. */
|
||||
|
||||
void (*func)(struct snapraid_worker*, struct snapraid_task*);
|
||||
|
||||
/**
|
||||
* Handle to data or parity.
|
||||
*
|
||||
* Only one of the two is valid, the other is 0.
|
||||
*/
|
||||
struct snapraid_handle* handle; /**< Handle at the file on the disk. */
|
||||
struct snapraid_parity_handle* parity_handle; /**< Handle at the parity on the disk. */
|
||||
|
||||
/**
|
||||
* Vector of tasks.
|
||||
*
|
||||
* It's a ring of tasks reused cycle after cycle.
|
||||
*/
|
||||
struct snapraid_task task_map[IO_MAX];
|
||||
|
||||
/**
|
||||
* The task in progress by the worker thread.
|
||||
*
|
||||
* It's an index inside in the ::task_map vector.
|
||||
*/
|
||||
unsigned index;
|
||||
|
||||
/**
|
||||
* Which buffer base index should be used for destination.
|
||||
*/
|
||||
unsigned buffer_skew;
|
||||
};
|
||||
|
||||
/**
|
||||
* Number of error kind for writers.
|
||||
*/
|
||||
#define IO_WRITER_ERROR_BASE TASK_STATE_IOERROR_CONTINUE
|
||||
#define IO_WRITER_ERROR_MAX (-IO_WRITER_ERROR_BASE)
|
||||
|
||||
/**
|
||||
* Reader.
|
||||
*
|
||||
* This represents the pool of worker threads dedicated to read
|
||||
* data from the disks.
|
||||
*/
|
||||
struct snapraid_io {
|
||||
struct snapraid_state* state;
|
||||
|
||||
/**
|
||||
* Number of read-ahead buffers to use.
|
||||
*
|
||||
* Between IO_MIN and IO_MAX for thread use.
|
||||
*
|
||||
* If equal to 1, it means to work without any thread.
|
||||
*/
|
||||
unsigned io_max;
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
/**
|
||||
* Mutex used to protect the synchronization
|
||||
* between the io and the workers.
|
||||
*/
|
||||
pthread_mutex_t io_mutex;
|
||||
|
||||
/**
|
||||
* Condition for a new read is completed.
|
||||
*
|
||||
* The workers signal this condition when a new read is completed.
|
||||
* The IO waits on this condition when it's waiting for
|
||||
* a new read to be completed.
|
||||
*/
|
||||
pthread_cond_t read_done;
|
||||
|
||||
/**
|
||||
* Condition for a new read scheduled.
|
||||
*
|
||||
* The workers wait on this condition when they are waiting for a new
|
||||
* read to process.
|
||||
* The IO signals this condition when new reads are scheduled.
|
||||
*/
|
||||
pthread_cond_t read_sched;
|
||||
|
||||
/**
|
||||
* Condition for a new write is completed.
|
||||
*
|
||||
* The workers signal this condition when a new write is completed.
|
||||
* The IO waits on this condition when it's waiting for
|
||||
* a new write to be completed.
|
||||
*/
|
||||
pthread_cond_t write_done;
|
||||
|
||||
/**
|
||||
* Condition for a new write scheduled.
|
||||
*
|
||||
* The workers wait on this condition when they are waiting for a new
|
||||
* write to process.
|
||||
* The IO signals this condition when new writes are scheduled.
|
||||
*/
|
||||
pthread_cond_t write_sched;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Base position for workers.
|
||||
*
|
||||
* It's the index in the ::worker_map[].
|
||||
*/
|
||||
unsigned data_base;
|
||||
unsigned data_count;
|
||||
unsigned parity_base;
|
||||
unsigned parity_count;
|
||||
|
||||
/**
|
||||
* Callbacks for workers.
|
||||
*/
|
||||
void (*data_reader)(struct snapraid_worker*, struct snapraid_task*);
|
||||
void (*parity_reader)(struct snapraid_worker*, struct snapraid_task*);
|
||||
void (*parity_writer)(struct snapraid_worker*, struct snapraid_task*);
|
||||
|
||||
/**
|
||||
* Blocks mapping.
|
||||
*
|
||||
* This info is used to obtain the sequence of block
|
||||
* positions to process.
|
||||
*/
|
||||
block_off_t block_start;
|
||||
block_off_t block_max;
|
||||
block_off_t block_next;
|
||||
int (*block_is_enabled)(void* arg, block_off_t);
|
||||
void* block_arg;
|
||||
|
||||
/**
|
||||
* Buffers for data.
|
||||
*
|
||||
* A pool of buffers used to store the data read.
|
||||
*/
|
||||
unsigned buffer_max; /**< Number of buffers. */
|
||||
void* buffer_alloc_map[IO_MAX]; /**< Allocation map for buffers. */
|
||||
void** buffer_map[IO_MAX]; /**< Buffers for data. */
|
||||
|
||||
/**
|
||||
* Workers.
|
||||
*
|
||||
* A vector of readers, each one representing a different thread.
|
||||
*/
|
||||
unsigned reader_max; /**< Number of workers. */
|
||||
struct snapraid_worker* reader_map; /**< Vector of workers. */
|
||||
unsigned writer_max; /**< Number of workers. */
|
||||
struct snapraid_worker* writer_map; /**< Vector of workers. */
|
||||
|
||||
/**
|
||||
* List of not yet processed workers.
|
||||
*
|
||||
* The list has ::reader_max + 1 elements. Each element contains
|
||||
* the number of the reader to process.
|
||||
*
|
||||
* At initialization the list is filled with [0..reader_max].
|
||||
* To get the next element to process we use i = list[i + 1].
|
||||
* The end is when i == reader_max.
|
||||
*/
|
||||
unsigned char* reader_list;
|
||||
unsigned char* writer_list;
|
||||
|
||||
/**
|
||||
* Exit condition for all threads.
|
||||
*/
|
||||
int done;
|
||||
|
||||
/**
|
||||
* The task currently used by the caller.
|
||||
*
|
||||
* It's a rolling counter, when reaching ::io_max
|
||||
* it goes again to 0.
|
||||
*
|
||||
* When the caller finish with the current index,
|
||||
* it's incremented, and a read_sched() signal is sent.
|
||||
*
|
||||
* In monothread mode it isn't the task index,
|
||||
* but the worker index.
|
||||
*/
|
||||
unsigned reader_index;
|
||||
|
||||
/**
|
||||
* The task currently used by the caller.
|
||||
*
|
||||
* It's a rolling counter, when reaching ::io_max
|
||||
* it goes again to 0.
|
||||
*
|
||||
* When the caller finish with the current index,
|
||||
* it's incremented, and a write_sched() signal is sent.
|
||||
*
|
||||
* In monothread mode it isn't the task index,
|
||||
* but the worker index.
|
||||
*/
|
||||
unsigned writer_index;
|
||||
|
||||
/**
|
||||
* Counts the error happening in the writers.
|
||||
*/
|
||||
int writer_error[IO_WRITER_ERROR_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the InputOutput workers.
|
||||
*
|
||||
* \param io_cache The number of IO buffers for read-ahead and write-behind. 0 for default.
|
||||
* \param buffer_max The number of data/parity buffers to allocate.
|
||||
*/
|
||||
void io_init(struct snapraid_io* io, struct snapraid_state* state,
|
||||
unsigned io_cache, unsigned buffer_max,
|
||||
void (*data_reader)(struct snapraid_worker*, struct snapraid_task*),
|
||||
struct snapraid_handle* handle_map, unsigned handle_max,
|
||||
void (*parity_reader)(struct snapraid_worker*, struct snapraid_task*),
|
||||
void (*parity_writer)(struct snapraid_worker*, struct snapraid_task*),
|
||||
struct snapraid_parity_handle* parity_handle_map, unsigned parity_handle_max);
|
||||
|
||||
/**
|
||||
* Deinitialize te InputOutput workers.
|
||||
*/
|
||||
void io_done(struct snapraid_io* io);
|
||||
|
||||
/**
|
||||
* Start all the worker threads.
|
||||
*/
|
||||
void (*io_start)(struct snapraid_io* io,
|
||||
block_off_t blockstart, block_off_t blockmax,
|
||||
int (*block_is_enabled)(void* arg, block_off_t), void* blockarg);
|
||||
|
||||
/**
|
||||
* Stop all the worker threads.
|
||||
*/
|
||||
void (*io_stop)(struct snapraid_io* io);
|
||||
|
||||
/**
|
||||
* Next read position.
|
||||
*
|
||||
* This call starts the reading process.
|
||||
* It must be called before io_data_read() and io_parity_read().
|
||||
*
|
||||
* \param io InputOutput context.
|
||||
* \param buffer The data buffers to use for this position.
|
||||
* \return The parity position.
|
||||
*/
|
||||
block_off_t (*io_read_next)(struct snapraid_io* io, void*** buffer);
|
||||
|
||||
/**
|
||||
* Read a data block.
|
||||
*
|
||||
* It must be called exactly ::handle_max times.
|
||||
*
|
||||
* \param io InputOutput context.
|
||||
* \param diskcur The position of the data block in the ::handle_map vector.
|
||||
* \return The completed task.
|
||||
*/
|
||||
struct snapraid_task* (*io_data_read)(struct snapraid_io* io, unsigned* diskcur, unsigned* waiting_map, unsigned* waiting_mac);
|
||||
|
||||
/**
|
||||
* Read a parity block.
|
||||
*
|
||||
* It must be called exactly ::parity_handle_max times.
|
||||
*
|
||||
* \param io InputOutput context.
|
||||
* \param levcur The position of the parity block in the ::parity_handle_map vector.
|
||||
* \return The completed task.
|
||||
*/
|
||||
struct snapraid_task* (*io_parity_read)(struct snapraid_io* io, unsigned* levcur, unsigned* waiting_map, unsigned* waiting_mac);
|
||||
|
||||
/**
|
||||
* Write of a parity block.
|
||||
*
|
||||
* It must be called exactly ::parity_handle_max times.
|
||||
*
|
||||
* \param io InputOutput context.
|
||||
* \param levcur The position of the parity block in the ::parity_handle_map vector.
|
||||
*/
|
||||
void (*io_parity_write)(struct snapraid_io* io, unsigned* levcur, unsigned* waiting_map, unsigned* waiting_mac);
|
||||
|
||||
/**
|
||||
* Preset the write position.
|
||||
*
|
||||
* This call starts the write process.
|
||||
* It must be called before io_parity_write().
|
||||
*
|
||||
* \param io InputOutput context.
|
||||
* \param blockcur The parity position to write.
|
||||
* \param skip Skip the writes, in case parity doesn't need to be updated.
|
||||
*/
|
||||
void (*io_write_preset)(struct snapraid_io* io, block_off_t blockcur, int skip);
|
||||
|
||||
/**
|
||||
* Next write position.
|
||||
*
|
||||
* This call ends the write process.
|
||||
* It must be called after io_parity_write().
|
||||
*
|
||||
* \param io InputOutput context.
|
||||
* \param blockcur The parity position to write.
|
||||
* \param skip Skip the writes, in case parity doesn't need to be updated.
|
||||
* \param writer_error Return the number of errors. Vector of IO_WRITER_ERROR_MAX elements.
|
||||
*/
|
||||
void (*io_write_next)(struct snapraid_io* io, block_off_t blockcur, int skip, int* writer_error);
|
||||
|
||||
/**
|
||||
* Refresh the number of cached blocks for all data and parity disks.
|
||||
*/
|
||||
void (*io_refresh)(struct snapraid_io* io);
|
||||
|
||||
#endif
|
||||
|
123
cmdline/list.c
Normal file
123
cmdline/list.c
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "parity.h"
|
||||
#include "handle.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* list */
|
||||
|
||||
void state_list(struct snapraid_state* state)
|
||||
{
|
||||
tommy_node* i;
|
||||
unsigned file_count;
|
||||
data_off_t file_size;
|
||||
unsigned link_count;
|
||||
char esc_buffer[ESC_MAX];
|
||||
char esc_buffer_alt[ESC_MAX];
|
||||
|
||||
file_count = 0;
|
||||
file_size = 0;
|
||||
link_count = 0;
|
||||
|
||||
msg_progress("Listing...\n");
|
||||
|
||||
/* for each disk */
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
tommy_node* j;
|
||||
struct snapraid_disk* disk = i->data;
|
||||
|
||||
/* sort by name */
|
||||
tommy_list_sort(&disk->filelist, file_path_compare);
|
||||
|
||||
/* for each file */
|
||||
for (j = disk->filelist; j != 0; j = j->next) {
|
||||
struct snapraid_file* file = j->data;
|
||||
#if HAVE_LOCALTIME_R
|
||||
struct tm tm_res;
|
||||
#endif
|
||||
struct tm* tm;
|
||||
time_t t;
|
||||
|
||||
++file_count;
|
||||
file_size += file->size;
|
||||
|
||||
log_tag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc_tag(file->sub, esc_buffer), file->size, file->mtime_sec, file->mtime_nsec, file->inode);
|
||||
|
||||
t = file->mtime_sec;
|
||||
#if HAVE_LOCALTIME_R
|
||||
tm = localtime_r(&t, &tm_res);
|
||||
#else
|
||||
tm = localtime(&t);
|
||||
#endif
|
||||
|
||||
printf("%12" PRIu64 " ", file->size);
|
||||
if (tm) {
|
||||
printf("%04u/%02u/%02u %02u:%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
|
||||
if (msg_level >= MSG_VERBOSE)
|
||||
printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000);
|
||||
printf(" ");
|
||||
}
|
||||
printf("%s\n", fmt_term(disk, file->sub, esc_buffer));
|
||||
}
|
||||
|
||||
/* sort by name */
|
||||
tommy_list_sort(&disk->linklist, link_alpha_compare);
|
||||
|
||||
/* for each link */
|
||||
for (j = disk->linklist; j != 0; j = j->next) {
|
||||
struct snapraid_link* slink = j->data;
|
||||
const char* type;
|
||||
|
||||
switch (slink->flag & FILE_IS_LINK_MASK) {
|
||||
case FILE_IS_HARDLINK : type = "hardlink"; break;
|
||||
case FILE_IS_SYMLINK : type = "symlink"; break;
|
||||
case FILE_IS_SYMDIR : type = "symdir"; break;
|
||||
case FILE_IS_JUNCTION : type = "junction"; break;
|
||||
/* LCOV_EXCL_START */
|
||||
default : type = "unknown"; break;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
++link_count;
|
||||
|
||||
log_tag("link_%s:%s:%s:%s\n", type, disk->name, esc_tag(slink->sub, esc_buffer), esc_tag(slink->linkto, esc_buffer_alt));
|
||||
|
||||
printf("%12s ", type);
|
||||
printf(" ");
|
||||
if (msg_level >= MSG_VERBOSE)
|
||||
printf(" ");
|
||||
printf("%s -> %s\n", fmt_term(disk, slink->sub, esc_buffer), fmt_term(disk, slink->linkto, esc_buffer_alt));
|
||||
}
|
||||
}
|
||||
|
||||
msg_status("\n");
|
||||
msg_status("%8u files, for %" PRIu64 " GB\n", file_count, file_size / GIGA);
|
||||
msg_status("%8u links\n", link_count);
|
||||
|
||||
log_tag("summary:file_count:%u\n", file_count);
|
||||
log_tag("summary:file_size:%" PRIu64 "\n", file_size);
|
||||
log_tag("summary:link_count:%u\n", link_count);
|
||||
log_tag("summary:exit:ok\n");
|
||||
log_flush();
|
||||
}
|
||||
|
2797
cmdline/mingw.c
Normal file
2797
cmdline/mingw.c
Normal file
File diff suppressed because it is too large
Load Diff
418
cmdline/mingw.h
Normal file
418
cmdline/mingw.h
Normal file
@ -0,0 +1,418 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __PORTABLE_MINGW_H
|
||||
#define __PORTABLE_MINGW_H
|
||||
|
||||
#ifdef __MINGW32__ /* Only for MingW */
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
/**
|
||||
* Always assume that the assembler supports SSE2, SSSE3, SSE42 and AVX2 instructions in x86
|
||||
*/
|
||||
#ifdef CONFIG_X86
|
||||
#define HAVE_SSE2 1
|
||||
#define HAVE_SSSE3 1
|
||||
#define HAVE_SSE42 1
|
||||
#define HAVE_AVX2 1
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/* file */
|
||||
|
||||
/**
|
||||
* Redefines PATH_MAX to allow very long paths.
|
||||
*/
|
||||
#undef PATH_MAX
|
||||
#define PATH_MAX 1024
|
||||
|
||||
/* Remap functions and types */
|
||||
#undef fopen
|
||||
#define fopen windows_fopen
|
||||
#undef open
|
||||
#define open windows_open
|
||||
#define open_noatime windows_open
|
||||
#undef stat
|
||||
#define stat windows_stat
|
||||
#undef lstat
|
||||
#define lstat windows_lstat
|
||||
#undef off_t
|
||||
#define off_t off64_t
|
||||
#undef fstat
|
||||
#define fstat windows_fstat
|
||||
#define HAVE_FTRUNCATE 1
|
||||
#undef ftruncate
|
||||
#define ftruncate windows_ftruncate
|
||||
#define HAVE_FALLOCATE 1
|
||||
#undef fallocate
|
||||
#define fallocate windows_fallocate
|
||||
#define HAVE_FSYNC 1
|
||||
#undef fsync
|
||||
#define fsync windows_fsync
|
||||
#undef rename
|
||||
#define rename windows_rename
|
||||
#undef remove
|
||||
#define remove windows_remove
|
||||
#undef mkdir
|
||||
#define mkdir(a, b) windows_mkdir(a)
|
||||
#undef rmdir
|
||||
#define rmdir windows_rmdir
|
||||
#undef dirent
|
||||
#define dirent windows_dirent
|
||||
#undef DIR
|
||||
#define DIR windows_dir
|
||||
#undef opendir
|
||||
#define opendir windows_opendir
|
||||
#undef readdir
|
||||
#define readdir windows_readdir
|
||||
#undef closedir
|
||||
#define closedir windows_closedir
|
||||
#define HAVE_FUTIMENS 1
|
||||
#undef futimens
|
||||
#define futimens windows_futimens
|
||||
#define HAVE_UTIMENSAT 1
|
||||
#define AT_FDCWD -1
|
||||
#define AT_SYMLINK_NOFOLLOW 1
|
||||
#undef utimensat
|
||||
#define utimensat windows_utimensat
|
||||
#define O_NOFOLLOW 0
|
||||
#define dirent_hidden windows_dirent_hidden
|
||||
#define HAVE_STRUCT_DIRENT_D_STAT 1
|
||||
#undef HAVE_STRUCT_DIRENT_D_INO
|
||||
#define HAVE_STRUCT_STAT_ST_NLINK 1
|
||||
#define dirent_lstat windows_dirent_lstat
|
||||
#define stat_desc windows_stat_desc
|
||||
#undef sleep
|
||||
#define sleep windows_sleep
|
||||
/* 4==DIR, 5,6,7=free, 8==REG */
|
||||
#define S_IFLNK 0x5000 /* Symbolic link to file */
|
||||
#define S_ISLNK(m) (((m) & _S_IFMT) == S_IFLNK)
|
||||
#define S_IFLNKDIR 0x6000 /* Symbolic link to directory */
|
||||
#define S_ISLNKDIR(m) (((m) & _S_IFMT) == S_IFLNKDIR)
|
||||
#define S_IFJUN 0x7000 /* Junction */
|
||||
#define S_ISJUN(m) (((m) & _S_IFMT) == S_IFJUN)
|
||||
#undef readlink
|
||||
#define readlink windows_readlink
|
||||
#undef symlink
|
||||
#define symlink windows_symlink
|
||||
#undef link
|
||||
#define link windows_link
|
||||
#undef strerror
|
||||
#define strerror windows_strerror
|
||||
#undef read
|
||||
#define read windows_read
|
||||
#undef write
|
||||
#define write windows_write
|
||||
#undef lseek
|
||||
#define lseek windows_lseek
|
||||
#undef pread
|
||||
#define pread windows_pread
|
||||
#undef pwrite
|
||||
#define pwrite windows_pwrite
|
||||
#define direct_size windows_direct_size
|
||||
#define HAVE_DIRECT_IO 1
|
||||
#define O_DIRECT 0x10000000
|
||||
#define O_DSYNC 0x20000000
|
||||
|
||||
/**
|
||||
* If nanoseconds are not supported, we report the special STAT_NSEC_INVALID value,
|
||||
* to mark that it's undefined.
|
||||
*/
|
||||
#define STAT_NSEC_INVALID -1
|
||||
|
||||
/* We have nano second support */
|
||||
#define STAT_NSEC(st) ((int)(st)->st_mtimensec)
|
||||
|
||||
/**
|
||||
* Generic stat information.
|
||||
*/
|
||||
struct windows_stat {
|
||||
uint64_t st_ino;
|
||||
int64_t st_size;
|
||||
int64_t st_mtime;
|
||||
int32_t st_mtimensec;
|
||||
uint32_t st_mode;
|
||||
uint32_t st_dev;
|
||||
uint32_t st_nlink;
|
||||
int st_hidden;
|
||||
const char* st_desc;
|
||||
int st_sync; /**< If the information are in sync with the file-system. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Like the C fstat().
|
||||
*/
|
||||
int windows_fstat(int fd, struct windows_stat* st);
|
||||
|
||||
/**
|
||||
* Like the C lstat(), but with some limitations.
|
||||
*
|
||||
* The st_ino field may be 0 if it's not possible to read it in a fast way.
|
||||
* Specifically this always happens.
|
||||
*
|
||||
* In case of hardlinks, the size and the attributes of the file can
|
||||
* be completely bogus, because changes made by other hardlinks are reported
|
||||
* in the directory entry only when the file is opened.
|
||||
*
|
||||
* MSDN CreateHardLinks
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa363860%28v=vs.85%29.aspx
|
||||
* 'When you create a hard link on the NTFS file system, the file attribute information'
|
||||
* 'in the directory entry is refreshed only when the file is opened, or when'
|
||||
* 'GetFileInformationByHandle is called with the handle of a specific file.'
|
||||
*
|
||||
* MSDN HardLinks and Junctions
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa365006%28v=vs.85%29.aspx
|
||||
* 'However, the directory entry size and attribute information is updated only'
|
||||
* 'for the link through which the change was made.'
|
||||
*
|
||||
* Use lstat_sync() to override these limitations.
|
||||
*/
|
||||
int windows_lstat(const char* file, struct windows_stat* st);
|
||||
|
||||
/**
|
||||
* Like the C stat().
|
||||
*/
|
||||
int windows_stat(const char* file, struct windows_stat* st);
|
||||
|
||||
/**
|
||||
* Like the C mkdir().
|
||||
*/
|
||||
int windows_mkdir(const char* file);
|
||||
|
||||
/**
|
||||
* Like rmdir().
|
||||
*/
|
||||
int windows_rmdir(const char* file);
|
||||
|
||||
/**
|
||||
* Like the C lstat(), but with some limitations.
|
||||
*
|
||||
* This call fills all the st_* fields of the stat struct,
|
||||
* and if provided the pointer, also the physical offset.
|
||||
*
|
||||
* It doesn't work for all kinds of files and directories.
|
||||
* You must call it only for regular files.
|
||||
* For example, "C:\System Volume Information" cannot be accessed
|
||||
* with error ERROR_ACCESS_DENIED.
|
||||
*
|
||||
* Note that instead lstat() works for all the files.
|
||||
*/
|
||||
#define HAVE_LSTAT_SYNC 1
|
||||
int lstat_sync(const char* file, struct windows_stat* st, uint64_t* physical);
|
||||
|
||||
/**
|
||||
* Like the C ftruncate().
|
||||
*/
|
||||
int windows_ftruncate(int fd, off64_t off);
|
||||
|
||||
/**
|
||||
* Like the C fallocate().
|
||||
*/
|
||||
int windows_fallocate(int fd, int mode, off64_t off, off64_t len);
|
||||
|
||||
/**
|
||||
* Like the C fsync().
|
||||
*/
|
||||
int windows_fsync(int fd);
|
||||
|
||||
/**
|
||||
* Like the C futimes().
|
||||
*/
|
||||
int windows_futimes(int fd, struct timeval tv[2]);
|
||||
|
||||
struct windows_timespec {
|
||||
int64_t tv_sec;
|
||||
int tv_nsec;
|
||||
};
|
||||
|
||||
#define timespec windows_timespec
|
||||
|
||||
/**
|
||||
* Like the C futimens().
|
||||
*/
|
||||
int windows_futimens(int fd, struct windows_timespec tv[2]);
|
||||
|
||||
/**
|
||||
* Like the C utimensat().
|
||||
*/
|
||||
int windows_utimensat(int fd, const char* file, struct windows_timespec tv[2], int flags);
|
||||
|
||||
/**
|
||||
* Like the C rename().
|
||||
*/
|
||||
int windows_rename(const char* a, const char* b);
|
||||
|
||||
/**
|
||||
* Like the C remove().
|
||||
*/
|
||||
int windows_remove(const char* a);
|
||||
|
||||
/**
|
||||
* Like the C fopen().
|
||||
*/
|
||||
FILE* windows_fopen(const char* file, const char* mode);
|
||||
|
||||
/**
|
||||
* Like the C open().
|
||||
*/
|
||||
int windows_open(const char* file, int flags, ...);
|
||||
|
||||
/**
|
||||
* Like the C dirent.
|
||||
*/
|
||||
struct windows_dirent {
|
||||
char d_name[PATH_MAX];
|
||||
struct windows_stat d_stat;
|
||||
};
|
||||
|
||||
/**
|
||||
* Like the C DIR.
|
||||
*/
|
||||
struct windows_dir_struct;
|
||||
typedef struct windows_dir_struct windows_dir;
|
||||
|
||||
/**
|
||||
* Like the C opendir().
|
||||
*/
|
||||
windows_dir* windows_opendir(const char* dir);
|
||||
|
||||
/**
|
||||
* Like the C readdir().
|
||||
*/
|
||||
struct windows_dirent* windows_readdir(windows_dir* dirstream);
|
||||
|
||||
/**
|
||||
* Like the C closedir().
|
||||
*/
|
||||
int windows_closedir(windows_dir* dirstream);
|
||||
|
||||
/**
|
||||
* Convert a dirent record to a lstat record, but with some limitations.
|
||||
*
|
||||
* The st_mode field may be 0 if the file is a reparse point.
|
||||
* Specifically this happens if we are using GetFileInformationByHandleEx()
|
||||
* to read the directory stream.
|
||||
*
|
||||
* The st_ino field may be 0 if it's not possible to read it in a fast way.
|
||||
* Specifically this happens if we are using FindFirst/FindNext to enumerate
|
||||
* the directory.
|
||||
*
|
||||
* In such cases, call lstat_sync() to fill the missing fields.
|
||||
*/
|
||||
void windows_dirent_lstat(const struct windows_dirent* dd, struct windows_stat* st);
|
||||
|
||||
/**
|
||||
* Like dirent_hidden().
|
||||
*/
|
||||
int windows_dirent_hidden(struct dirent* dd);
|
||||
|
||||
/**
|
||||
* Like stat_desc().
|
||||
*/
|
||||
const char* windows_stat_desc(struct stat* st);
|
||||
|
||||
/**
|
||||
* Like sleep().
|
||||
*/
|
||||
void windows_sleep(unsigned seconds);
|
||||
|
||||
/**
|
||||
* Like readlink().
|
||||
*/
|
||||
int windows_readlink(const char* file, char* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Like symlink().
|
||||
* Return ENOSYS if symlinks are not supported.
|
||||
*/
|
||||
int windows_symlink(const char* existing, const char* file);
|
||||
|
||||
/**
|
||||
* Like link().
|
||||
*/
|
||||
int windows_link(const char* existing, const char* file);
|
||||
|
||||
/**
|
||||
* Like strerror().
|
||||
*/
|
||||
const char* windows_strerror(int err);
|
||||
|
||||
/**
|
||||
* Like read().
|
||||
*/
|
||||
ssize_t windows_read(int f, void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Like write().
|
||||
*/
|
||||
ssize_t windows_write(int f, const void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Like lseek().
|
||||
*/
|
||||
off_t windows_lseek(int f, off_t offset, int whence);
|
||||
|
||||
/**
|
||||
* Like pread().
|
||||
*/
|
||||
ssize_t windows_pread(int f, void* buffer, size_t size, off_t offset);
|
||||
|
||||
/**
|
||||
* Like pwrite().
|
||||
*/
|
||||
ssize_t windows_pwrite(int f, const void* buffer, size_t size, off_t offset);
|
||||
|
||||
/**
|
||||
* List direct_size().
|
||||
*/
|
||||
size_t windows_direct_size(void);
|
||||
|
||||
/****************************************************************************/
|
||||
/* thread */
|
||||
|
||||
#define pthread_mutex_t windows_mutex_t
|
||||
#define pthread_cond_t windows_cond_t
|
||||
#define pthread_mutex_init windows_mutex_init
|
||||
#define pthread_mutex_destroy windows_mutex_destroy
|
||||
#define pthread_mutex_lock windows_mutex_lock
|
||||
#define pthread_mutex_unlock windows_mutex_unlock
|
||||
#define pthread_cond_init windows_cond_init
|
||||
#define pthread_cond_destroy windows_cond_destroy
|
||||
#define pthread_cond_signal windows_cond_signal
|
||||
#define pthread_cond_broadcast windows_cond_broadcast
|
||||
#define pthread_cond_wait windows_cond_wait
|
||||
|
||||
typedef void* windows_mutex_t;
|
||||
typedef void* windows_cond_t;
|
||||
|
||||
/**
|
||||
* Like pthread_* equivalent.
|
||||
*/
|
||||
int windows_mutex_init(windows_mutex_t* mutex, void* attr);
|
||||
int windows_mutex_destroy(windows_mutex_t* mutex);
|
||||
int windows_mutex_lock(windows_mutex_t* mutex);
|
||||
int windows_mutex_unlock(windows_mutex_t* mutex);
|
||||
int windows_cond_init(windows_cond_t* cond, void* attr);
|
||||
int windows_cond_destroy(windows_cond_t* cond);
|
||||
int windows_cond_signal(windows_cond_t* cond);
|
||||
int windows_cond_broadcast(windows_cond_t* cond);
|
||||
int windows_cond_wait(windows_cond_t* cond, windows_mutex_t* mutex);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
269
cmdline/mkstream.c
Normal file
269
cmdline/mkstream.c
Normal file
@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "stream.h"
|
||||
#include "support.h"
|
||||
|
||||
#define STREAM_MAX 8
|
||||
#define BUFFER_MAX 64
|
||||
#define STR_MAX 128
|
||||
|
||||
void test(void)
|
||||
{
|
||||
struct stream* s;
|
||||
char file[32];
|
||||
unsigned char buffer[BUFFER_MAX];
|
||||
char str[STR_MAX];
|
||||
unsigned i, j;
|
||||
uint32_t u32 = -1L;
|
||||
uint64_t u64 = -1LL;
|
||||
uint32_t put_crc_stored;
|
||||
uint32_t put_crc_computed;
|
||||
|
||||
crc32c_init();
|
||||
|
||||
s = sopen_multi_write(STREAM_MAX);
|
||||
for (i = 0; i < STREAM_MAX; ++i) {
|
||||
snprintf(file, sizeof(file), "stream%u.bin", i);
|
||||
if (sopen_multi_file(s, i, file) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 256; ++j) {
|
||||
if (sputc(j, s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 32; ++j) {
|
||||
if (sputb32(u32 >> j, s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 64; ++j) {
|
||||
if (sputb64(u64 >> j, s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < BUFFER_MAX; ++j) {
|
||||
memset(buffer, j, j);
|
||||
if (swrite(buffer, j, s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 1; j < STR_MAX; ++j) {
|
||||
memset(str, ' ' + j, j - 1);
|
||||
str[j - 1] = 0;
|
||||
if (sputbs(str, s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
put_crc_stored = scrc(s);
|
||||
put_crc_computed = scrc_stream(s);
|
||||
|
||||
if (put_crc_stored != put_crc_computed) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (sputble32(put_crc_stored, s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (sclose(s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
for (i = 0; i < STREAM_MAX; ++i) {
|
||||
uint32_t get_crc_stored;
|
||||
uint32_t get_crc_computed;
|
||||
snprintf(file, sizeof(file), "stream%u.bin", i);
|
||||
|
||||
s = sopen_read(file);
|
||||
if (s == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
for (j = 0; j < 256; ++j) {
|
||||
int c = sgetc(s);
|
||||
if (c == EOF || (unsigned char)c != j) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 32; ++j) {
|
||||
uint32_t v32;
|
||||
if (sgetb32(s, &v32) != 0 || v32 != (u32 >> j)) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < 64; ++j) {
|
||||
uint64_t v64;
|
||||
if (sgetb64(s, &v64) != 0 || v64 != (u64 >> j)) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 1; j < BUFFER_MAX; ++j) {
|
||||
char copy[BUFFER_MAX];
|
||||
memset(buffer, j, j);
|
||||
if (sread(s, copy, j) != 0 || memcmp(copy, buffer, j) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 1; j < STR_MAX; ++j) {
|
||||
char copy[STR_MAX];
|
||||
memset(str, ' ' + j, j - 1);
|
||||
str[j - 1] = 0;
|
||||
if (sgetbs(s, copy, sizeof(copy)) != 0 || strcmp(copy, str) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* get the computed CRC *before* reading the stored one */
|
||||
get_crc_computed = scrc(s);
|
||||
|
||||
if (sgetble32(s, &get_crc_stored) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (get_crc_stored != put_crc_stored) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (get_crc_stored != get_crc_computed) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (sclose(s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < STREAM_MAX; ++i) {
|
||||
uint32_t get_crc_stored;
|
||||
uint32_t get_crc_computed;
|
||||
unsigned char buf[4];
|
||||
snprintf(file, sizeof(file), "stream%u.bin", i);
|
||||
|
||||
s = sopen_read(file);
|
||||
if (s == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (sdeplete(s, buf) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* get the stored crc from the last four bytes */
|
||||
get_crc_stored = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
|
||||
|
||||
if (get_crc_stored != put_crc_stored) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* get the computed CRC *after* reading the stored one */
|
||||
get_crc_computed = scrc(s);
|
||||
|
||||
/* adjust the stored crc to include itself */
|
||||
get_crc_stored = crc32c(get_crc_stored, buf, 4);
|
||||
|
||||
if (get_crc_stored != get_crc_computed) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (sclose(s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
lock_init();
|
||||
|
||||
for (i = 1; i <= 16; ++i) {
|
||||
|
||||
/* test with different stream buffer size */
|
||||
STREAM_SIZE = i;
|
||||
|
||||
printf("Test stream buffer size %u\n", i);
|
||||
|
||||
test();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
794
cmdline/mktest.c
Normal file
794
cmdline/mktest.c
Normal file
@ -0,0 +1,794 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* random */
|
||||
|
||||
/**
|
||||
* Pseudo random number generator.
|
||||
*/
|
||||
unsigned long long seed = 0;
|
||||
|
||||
unsigned rnd(unsigned max)
|
||||
{
|
||||
seed = seed * 6364136223846793005LL + 1442695040888963407LL;
|
||||
|
||||
return (seed >> 32) % max;
|
||||
}
|
||||
|
||||
unsigned rndnz(unsigned max)
|
||||
{
|
||||
if (max <= 1)
|
||||
return 1;
|
||||
else
|
||||
return rnd(max - 1) + 1;
|
||||
}
|
||||
|
||||
void rndnz_range(unsigned char* data, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; ++i)
|
||||
data[i] = rndnz(256);
|
||||
}
|
||||
|
||||
void rndnz_damage(unsigned char* data, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* corrupt ensuring always different data */
|
||||
for (i = 0; i < size; ++i) {
|
||||
unsigned char c;
|
||||
|
||||
do {
|
||||
c = rndnz(256);
|
||||
} while (c == data[i]);
|
||||
|
||||
data[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+";
|
||||
#define CHARSET_LEN (sizeof(CHARSET) - 1)
|
||||
|
||||
void rnd_name(char* file)
|
||||
{
|
||||
int l = 1 + rnd(20);
|
||||
|
||||
while (l) {
|
||||
*file++ = CHARSET[rnd(CHARSET_LEN)];
|
||||
--l;
|
||||
}
|
||||
*file = 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* file */
|
||||
|
||||
int file_cmp(const void* a, const void* b)
|
||||
{
|
||||
return strcmp(a, b);
|
||||
}
|
||||
|
||||
int fallback(int f, struct stat* st)
|
||||
{
|
||||
#if HAVE_FUTIMENS
|
||||
struct timespec tv[2];
|
||||
#else
|
||||
struct timeval tv[2];
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
#if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
|
||||
tv[0].tv_sec = st->st_mtime;
|
||||
if (STAT_NSEC(st) != STAT_NSEC_INVALID)
|
||||
tv[0].tv_nsec = STAT_NSEC(st);
|
||||
else
|
||||
tv[0].tv_nsec = 0;
|
||||
tv[1].tv_sec = tv[0].tv_sec;
|
||||
tv[1].tv_nsec = tv[0].tv_nsec;
|
||||
|
||||
ret = futimens(f, tv);
|
||||
#elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
|
||||
tv[0].tv_sec = st->st_mtime;
|
||||
if (STAT_NSEC(st) != STAT_NSEC_INVALID)
|
||||
tv[0].tv_usec = STAT_NSEC(st) / 1000;
|
||||
else
|
||||
tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = tv[0].tv_sec;
|
||||
tv[1].tv_usec = tv[0].tv_usec;
|
||||
|
||||
ret = futimes(f, tv);
|
||||
#elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
|
||||
tv[0].tv_sec = st->st_mtime;
|
||||
if (STAT_NSEC(st) != STAT_NSEC_INVALID)
|
||||
tv[0].tv_usec = STAT_NSEC(st) / 1000;
|
||||
else
|
||||
tv[0].tv_usec = 0;
|
||||
tv[1].tv_sec = tv[0].tv_sec;
|
||||
tv[1].tv_usec = tv[0].tv_usec;
|
||||
|
||||
ret = futimesat(f, 0, tv);
|
||||
#else
|
||||
#error No function available to set file timestamps
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* cmd */
|
||||
|
||||
/**
|
||||
* Create a file with random content.
|
||||
* - If the file exists it's rewritten, but avoiding to truncating it to 0.
|
||||
*/
|
||||
void cmd_generate_file(const char* path, int size)
|
||||
{
|
||||
unsigned char* data;
|
||||
int f;
|
||||
|
||||
/* remove the existing file/symlink if any */
|
||||
if (remove(path) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
} else {
|
||||
/* don't truncate files to 0 size to avoid ZERO file size protection */
|
||||
++size;
|
||||
}
|
||||
|
||||
data = malloc(size);
|
||||
|
||||
/* We don't write zero bytes because we want to test */
|
||||
/* the recovering of new files, after an aborted sync */
|
||||
/* If the files contains full blocks at zero */
|
||||
/* this is an impossible condition to recover */
|
||||
/* because we cannot differentiate between an unused block */
|
||||
/* and a file filled with 0 */
|
||||
rndnz_range(data, size);
|
||||
|
||||
f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
|
||||
if (f < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error creating file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (write(f, data, size) != size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (close(f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a symlink.
|
||||
* - If the file already exists, it's removed.
|
||||
*/
|
||||
void cmd_generate_symlink(const char* path, const char* linkto)
|
||||
{
|
||||
/* remove the existing file/symlink if any */
|
||||
if (remove(path) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
if (symlink(linkto, path) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing symlink %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a file or a symlink with a random name.
|
||||
*/
|
||||
void cmd_generate(int disk, int size)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char* file;
|
||||
|
||||
snprintf(path, sizeof(path), "bench/disk%d/", disk);
|
||||
file = path + strlen(path);
|
||||
|
||||
/* add a directory */
|
||||
*file++ = 'a' + rnd(2);
|
||||
*file = 0;
|
||||
|
||||
/* create it */
|
||||
if (mkdir(path, 0777) != 0) {
|
||||
if (errno != EEXIST) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error creating directory %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
*file++ = '/';
|
||||
|
||||
while (1) {
|
||||
/* add a random file */
|
||||
rnd_name(file);
|
||||
|
||||
/* skip some invalid file name, see http://en.wikipedia.org/wiki/Filename */
|
||||
if (strcmp(file, ".") == 0
|
||||
|| strcmp(file, "..") == 0
|
||||
|| strcmp(file, "prn") == 0
|
||||
|| strcmp(file, "con") == 0
|
||||
|| strcmp(file, "nul") == 0
|
||||
|| strcmp(file, "aux") == 0
|
||||
|| file[0] == ' '
|
||||
|| file[strlen(file) - 1] == ' '
|
||||
|| file[strlen(file) - 1] == '.'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef WIN32 /* Windows XP doesn't support symlinks */
|
||||
if (rnd(32) == 0) {
|
||||
/* symlink */
|
||||
char linkto[PATH_MAX];
|
||||
|
||||
rnd_name(linkto);
|
||||
|
||||
cmd_generate_symlink(path, linkto);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* file */
|
||||
cmd_generate_file(path, size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a partially a file.
|
||||
* - The file must exist.
|
||||
* - The file size is not changed.
|
||||
* - The written data may be equal or not at the already existing one.
|
||||
* - If it's a symlink nothing is done.
|
||||
*/
|
||||
void cmd_write(const char* path, int size)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (lstat(path, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
unsigned char* data;
|
||||
off_t off;
|
||||
int f;
|
||||
|
||||
/* not over the end */
|
||||
if (size > st.st_size)
|
||||
size = st.st_size;
|
||||
|
||||
/* start at random position inside the file */
|
||||
if (size < st.st_size)
|
||||
off = rnd(st.st_size - size);
|
||||
else
|
||||
off = 0;
|
||||
|
||||
data = malloc(size);
|
||||
|
||||
rndnz_range(data, size);
|
||||
|
||||
f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
|
||||
if (f < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error creating file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (lseek(f, off, SEEK_SET) != off) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error seeking file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (write(f, data, size) != size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (close(f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Damage a file.
|
||||
* - The file must exist.
|
||||
* - The file size is not changed.
|
||||
* - The written data is SURELY different than the already existing one.
|
||||
* - The file timestamp is NOT modified.
|
||||
* - If it's a symlink nothing is done.
|
||||
*/
|
||||
void cmd_damage(const char* path, int size)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
/* here a 0 size means to change nothing */
|
||||
/* as also the timestamp should not be changed */
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
if (lstat(path, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (st.st_size == 0)
|
||||
return;
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
off_t off;
|
||||
unsigned char* data;
|
||||
int f;
|
||||
|
||||
/* not over the end */
|
||||
if (size > st.st_size)
|
||||
size = st.st_size;
|
||||
|
||||
/* start at random position inside the file */
|
||||
if (size < st.st_size)
|
||||
off = rnd(st.st_size - size);
|
||||
else
|
||||
off = 0;
|
||||
|
||||
data = malloc(size);
|
||||
|
||||
f = open(path, O_RDWR | O_BINARY | O_NOFOLLOW);
|
||||
if (f < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error creating file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (lseek(f, off, SEEK_SET) != off) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error seeking file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (read(f, data, size) != size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
rndnz_damage(data, size);
|
||||
|
||||
if (lseek(f, off, SEEK_SET) != off) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error seeking file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (write(f, data, size) != size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (fallback(f, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error setting time for file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (close(f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append to a file.
|
||||
* - The file must exist.
|
||||
* - If it's a symlink nothing is done.
|
||||
*/
|
||||
void cmd_append(const char* path, int size)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (lstat(path, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
unsigned char* data;
|
||||
int f;
|
||||
|
||||
data = malloc(size);
|
||||
|
||||
rndnz_range(data, size);
|
||||
|
||||
f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
|
||||
if (f < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (write(f, data, size) != size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (close(f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Truncate a file.
|
||||
* - The file must exist.
|
||||
* - The file is NEVER truncated to 0.
|
||||
* - If it's a symlink nothing is done.
|
||||
*/
|
||||
void cmd_truncate(const char* path, int size)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (lstat(path, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
off_t off;
|
||||
int f;
|
||||
|
||||
/* if file is empty, just rewrite it */
|
||||
if (st.st_size == 0) {
|
||||
size = 0;
|
||||
} else {
|
||||
/* don't truncate files to 0 size to avoid ZERO file size protection */
|
||||
if (size >= st.st_size)
|
||||
size = st.st_size - 1;
|
||||
}
|
||||
|
||||
off = st.st_size - size;
|
||||
|
||||
f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
|
||||
if (f < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (ftruncate(f, off) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error truncating file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (close(f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a file.
|
||||
* - The file must exist.
|
||||
*/
|
||||
void cmd_delete(const char* path)
|
||||
{
|
||||
if (remove(path) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change a file. Or deleted/truncated/append/created.
|
||||
* - The file must exist.
|
||||
*/
|
||||
void cmd_change(const char* path, int size)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
if (lstat(path, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
/* symlink */
|
||||
if (rnd(2) == 0) {
|
||||
/* delete */
|
||||
if (remove(path) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
} else {
|
||||
/* recreate */
|
||||
char linkto[PATH_MAX];
|
||||
|
||||
if (remove(path) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing %s\n", path);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
rnd_name(linkto);
|
||||
|
||||
cmd_generate_symlink(path, linkto);
|
||||
}
|
||||
} else if (S_ISREG(st.st_mode)) {
|
||||
int r;
|
||||
|
||||
r = rnd(4);
|
||||
|
||||
if (r == 0) {
|
||||
cmd_write(path, size);
|
||||
} else if (r == 1) {
|
||||
cmd_append(path, size);
|
||||
} else if (r == 2) {
|
||||
cmd_truncate(path, size);
|
||||
} else {
|
||||
cmd_delete(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void help(void)
|
||||
{
|
||||
printf("Test for " PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
|
||||
printf("Usage:\n");
|
||||
printf("\tmktest generate SEED DISK_NUM FILE_NUM FILE_SIZE\n");
|
||||
printf("\tmktest damage SEED NUM SIZE FILE\n");
|
||||
printf("\tmktest write SEED NUM SIZE FILE\n");
|
||||
printf("\tmktest change SEED SIZE FILE\n");
|
||||
printf("\tmktest append SEED SIZE FILE\n");
|
||||
printf("\tmktest truncate SEED SIZE FILE\n");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int i, j, b;
|
||||
|
||||
lock_init();
|
||||
|
||||
if (argc < 2) {
|
||||
help();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "generate") == 0) {
|
||||
int disk, file, size;
|
||||
|
||||
if (argc != 6) {
|
||||
/* LCOV_EXCL_START */
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
seed = atoi(argv[2]);
|
||||
disk = atoi(argv[3]);
|
||||
file = atoi(argv[4]);
|
||||
size = atoi(argv[5]);
|
||||
|
||||
for (i = 0; i < disk; ++i) {
|
||||
for (j = 0; j < file; ++j) {
|
||||
if (j == 0)
|
||||
/* create at least a big one */
|
||||
cmd_generate(i + 1, size);
|
||||
else if (j == 1)
|
||||
/* create at least an empty one */
|
||||
cmd_generate(i + 1, 0);
|
||||
else
|
||||
cmd_generate(i + 1, rnd(size));
|
||||
}
|
||||
}
|
||||
} else if (strcmp(argv[1], "write") == 0) {
|
||||
int fail, size;
|
||||
|
||||
if (argc < 6) {
|
||||
/* LCOV_EXCL_START */
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
seed = atoi(argv[2]);
|
||||
fail = atoi(argv[3]);
|
||||
size = atoi(argv[4]);
|
||||
b = 5;
|
||||
|
||||
/* sort the file names */
|
||||
qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
|
||||
|
||||
for (i = b; i < argc; ++i)
|
||||
for (j = 0; j < fail; ++j)
|
||||
cmd_write(argv[i], rndnz(size));
|
||||
} else if (strcmp(argv[1], "damage") == 0) {
|
||||
int fail, size;
|
||||
|
||||
if (argc < 6) {
|
||||
/* LCOV_EXCL_START */
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
seed = atoi(argv[2]);
|
||||
fail = atoi(argv[3]);
|
||||
size = atoi(argv[4]);
|
||||
b = 5;
|
||||
|
||||
/* sort the file names */
|
||||
qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
|
||||
|
||||
for (i = b; i < argc; ++i)
|
||||
for (j = 0; j < fail; ++j)
|
||||
cmd_damage(argv[i], rndnz(size)); /* at least one byte */
|
||||
} else if (strcmp(argv[1], "append") == 0) {
|
||||
int size;
|
||||
|
||||
if (argc < 5) {
|
||||
/* LCOV_EXCL_START */
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
seed = atoi(argv[2]);
|
||||
size = atoi(argv[3]);
|
||||
b = 4;
|
||||
|
||||
/* sort the file names */
|
||||
qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
|
||||
|
||||
for (i = b; i < argc; ++i)
|
||||
cmd_append(argv[i], rndnz(size)); /* at least one byte */
|
||||
} else if (strcmp(argv[1], "truncate") == 0) {
|
||||
int size;
|
||||
|
||||
if (argc < 5) {
|
||||
/* LCOV_EXCL_START */
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
seed = atoi(argv[2]);
|
||||
size = atoi(argv[3]);
|
||||
b = 4;
|
||||
|
||||
/* sort the file names */
|
||||
qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
|
||||
|
||||
for (i = b; i < argc; ++i)
|
||||
cmd_truncate(argv[i], rnd(size));
|
||||
} else if (strcmp(argv[1], "change") == 0) {
|
||||
int size;
|
||||
|
||||
if (argc < 5) {
|
||||
/* LCOV_EXCL_START */
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
seed = atoi(argv[2]);
|
||||
size = atoi(argv[3]);
|
||||
b = 4;
|
||||
|
||||
/* sort the file names */
|
||||
qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
|
||||
|
||||
for (i = b; i < argc; ++i)
|
||||
cmd_change(argv[i], rnd(size));
|
||||
} else {
|
||||
/* LCOV_EXCL_START */
|
||||
help();
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
lock_done();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
180
cmdline/murmur3.c
Normal file
180
cmdline/murmur3.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Derivative work from MurmorHash3.cpp revision r136
|
||||
*
|
||||
* SMHasher & MurmurHash
|
||||
* http://code.google.com/p/smhasher/
|
||||
*
|
||||
* Exact source used as reference:
|
||||
* http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp?spec=svn136&r=136
|
||||
*/
|
||||
|
||||
// MurmurHash3 was written by Austin Appleby, and is placed in the public
|
||||
// domain. The author hereby disclaims copyright to this source code.
|
||||
|
||||
/* Finalization mix - force all bits of a hash block to avalanche */
|
||||
static inline uint32_t fmix32(uint32_t h)
|
||||
{
|
||||
h ^= h >> 16;
|
||||
h *= 0x85ebca6b;
|
||||
h ^= h >> 13;
|
||||
h *= 0xc2b2ae35;
|
||||
h ^= h >> 16;
|
||||
return h;
|
||||
}
|
||||
|
||||
/*
|
||||
* Warning!
|
||||
* Don't declare these variables static, otherwise the gcc optimizer
|
||||
* may generate very slow code for multiplication with these constants,
|
||||
* like:
|
||||
|
||||
-> .cpp
|
||||
k1 *= c1;
|
||||
-> .asm
|
||||
152: 8d 14 80 lea (%eax,%eax,4),%edx
|
||||
155: 8d 14 90 lea (%eax,%edx,4),%edx
|
||||
158: c1 e2 03 shl $0x3,%edx
|
||||
15b: 29 c2 sub %eax,%edx
|
||||
15d: 8d 14 d2 lea (%edx,%edx,8),%edx
|
||||
160: 8d 14 90 lea (%eax,%edx,4),%edx
|
||||
163: 8d 14 d0 lea (%eax,%edx,8),%edx
|
||||
166: 8d 14 90 lea (%eax,%edx,4),%edx
|
||||
169: 8d 14 50 lea (%eax,%edx,2),%edx
|
||||
16c: 8d 14 90 lea (%eax,%edx,4),%edx
|
||||
16f: 8d 14 92 lea (%edx,%edx,4),%edx
|
||||
172: 8d 14 50 lea (%eax,%edx,2),%edx
|
||||
175: 8d 04 d0 lea (%eax,%edx,8),%eax
|
||||
178: 8d 14 c5 00 00 00 00 lea 0x0(,%eax,8),%edx
|
||||
17f: 29 d0 sub %edx,%eax
|
||||
|
||||
* resulting in speeds of 500 MB/s instead of 3000 MB/s.
|
||||
*
|
||||
* Verified with gcc 4.4.4 compiling with :
|
||||
*
|
||||
* g++ -g -c -O2 MurmurHash3.cpp -o MurmurHash3.o
|
||||
*/
|
||||
uint32_t c1 = 0x239b961b;
|
||||
uint32_t c2 = 0xab0e9789;
|
||||
uint32_t c3 = 0x38b34ae5;
|
||||
uint32_t c4 = 0xa1e38b93;
|
||||
|
||||
void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, void* digest)
|
||||
{
|
||||
size_t nblocks;
|
||||
const uint32_t* blocks;
|
||||
const uint32_t* end;
|
||||
size_t size_remainder;
|
||||
uint32_t h1, h2, h3, h4;
|
||||
|
||||
h1 = util_read32(seed + 0);
|
||||
h2 = util_read32(seed + 4);
|
||||
h3 = util_read32(seed + 8);
|
||||
h4 = util_read32(seed + 12);
|
||||
|
||||
nblocks = size / 16;
|
||||
blocks = data;
|
||||
end = blocks + nblocks * 4;
|
||||
|
||||
/* body */
|
||||
while (blocks < end) {
|
||||
uint32_t k1 = blocks[0];
|
||||
uint32_t k2 = blocks[1];
|
||||
uint32_t k3 = blocks[2];
|
||||
uint32_t k4 = blocks[3];
|
||||
|
||||
#if WORDS_BIGENDIAN
|
||||
k1 = util_swap32(k1);
|
||||
k2 = util_swap32(k2);
|
||||
k3 = util_swap32(k3);
|
||||
k4 = util_swap32(k4);
|
||||
#endif
|
||||
|
||||
k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
|
||||
|
||||
h1 = util_rotl32(h1, 19); h1 += h2; h1 = h1 * 5 + 0x561ccd1b;
|
||||
|
||||
k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
|
||||
|
||||
h2 = util_rotl32(h2, 17); h2 += h3; h2 = h2 * 5 + 0x0bcaa747;
|
||||
|
||||
k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
|
||||
|
||||
h3 = util_rotl32(h3, 15); h3 += h4; h3 = h3 * 5 + 0x96cd1c35;
|
||||
|
||||
k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
|
||||
|
||||
h4 = util_rotl32(h4, 13); h4 += h1; h4 = h4 * 5 + 0x32ac3b17;
|
||||
|
||||
blocks += 4;
|
||||
}
|
||||
|
||||
/* tail */
|
||||
size_remainder = size & 15;
|
||||
if (size_remainder != 0) {
|
||||
const uint8_t* tail = (const uint8_t*)blocks;
|
||||
|
||||
uint32_t k1 = 0;
|
||||
uint32_t k2 = 0;
|
||||
uint32_t k3 = 0;
|
||||
uint32_t k4 = 0;
|
||||
|
||||
switch (size_remainder) {
|
||||
case 15 : k4 ^= (uint32_t)tail[14] << 16;
|
||||
case 14 : k4 ^= (uint32_t)tail[13] << 8;
|
||||
case 13 : k4 ^= (uint32_t)tail[12] << 0;
|
||||
k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
|
||||
case 12 : k3 ^= (uint32_t)tail[11] << 24;
|
||||
case 11 : k3 ^= (uint32_t)tail[10] << 16;
|
||||
case 10 : k3 ^= (uint32_t)tail[ 9] << 8;
|
||||
case 9 : k3 ^= (uint32_t)tail[ 8] << 0;
|
||||
k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
|
||||
case 8 : k2 ^= (uint32_t)tail[ 7] << 24;
|
||||
case 7 : k2 ^= (uint32_t)tail[ 6] << 16;
|
||||
case 6 : k2 ^= (uint32_t)tail[ 5] << 8;
|
||||
case 5 : k2 ^= (uint32_t)tail[ 4] << 0;
|
||||
k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
|
||||
case 4 : k1 ^= (uint32_t)tail[ 3] << 24;
|
||||
case 3 : k1 ^= (uint32_t)tail[ 2] << 16;
|
||||
case 2 : k1 ^= (uint32_t)tail[ 1] << 8;
|
||||
case 1 : k1 ^= (uint32_t)tail[ 0] << 0;
|
||||
k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
|
||||
}
|
||||
}
|
||||
|
||||
/* finalization */
|
||||
h1 ^= size; h2 ^= size; h3 ^= size; h4 ^= size;
|
||||
|
||||
h1 += h2; h1 += h3; h1 += h4;
|
||||
h2 += h1; h3 += h1; h4 += h1;
|
||||
|
||||
h1 = fmix32(h1);
|
||||
h2 = fmix32(h2);
|
||||
h3 = fmix32(h3);
|
||||
h4 = fmix32(h4);
|
||||
|
||||
h1 += h2; h1 += h3; h1 += h4;
|
||||
h2 += h1; h3 += h1; h4 += h1;
|
||||
|
||||
util_write32(digest + 0, h1);
|
||||
util_write32(digest + 4, h2);
|
||||
util_write32(digest + 8, h3);
|
||||
util_write32(digest + 12, h4);
|
||||
}
|
||||
|
264
cmdline/murmur3test.c
Normal file
264
cmdline/murmur3test.c
Normal file
@ -0,0 +1,264 @@
|
||||
{ "", 0, { 0x6d, 0xc8, 0xcf, 0x99, 0x79, 0xda, 0x82, 0x0b, 0x9d, 0xd0, 0x02, 0x56, 0x0e, 0x6a, 0x28, 0x0a } },
|
||||
{ "a", 1, { 0x83, 0xa4, 0xc1, 0x6e, 0x1f, 0xcb, 0x8b, 0x30, 0x26, 0x59, 0x53, 0x64, 0x3b, 0x3f, 0xc1, 0xda } },
|
||||
{ "abc", 3, { 0xb3, 0xfc, 0x85, 0x98, 0x5b, 0xe6, 0x5a, 0xa2, 0x4b, 0xe9, 0x91, 0xee, 0x71, 0x9f, 0x9f, 0x8d } },
|
||||
{ "message digest", 14, { 0x20, 0xa2, 0x19, 0x39, 0xec, 0x22, 0x47, 0x6d, 0xe2, 0xec, 0x49, 0x9d, 0xc0, 0xd9, 0x9a, 0x3e } },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 26, { 0xde, 0x14, 0xd1, 0x23, 0x69, 0xa3, 0x51, 0x40, 0xc2, 0x05, 0x6c, 0x02, 0xb1, 0xa5, 0x57, 0xf7 } },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, { 0xc9, 0x76, 0x9b, 0xc1, 0xaf, 0x21, 0x57, 0xbc, 0x1a, 0x37, 0xa3, 0xd0, 0xc5, 0x3e, 0x0c, 0xa7 } },
|
||||
{ "The quick brown fox jumps over the lazy dog", 43, { 0x50, 0x2a, 0xbe, 0xaf, 0x34, 0xa9, 0x5a, 0x3d, 0x23, 0x32, 0x5f, 0x35, 0xf4, 0xbb, 0xae, 0xb6 } },
|
||||
{ "\x00", 1, { 0xe6, 0x32, 0x4f, 0xfc, 0x34, 0xec, 0x2e, 0xa6, 0xd2, 0x78, 0x69, 0x5d, 0x02, 0x5a, 0x13, 0xf2 } },
|
||||
{ "\x16\x27", 2, { 0x6f, 0xa3, 0xa2, 0x16, 0xbf, 0x09, 0x0c, 0x4c, 0xc7, 0xca, 0xc2, 0xbc, 0xd7, 0xb4, 0xed, 0xd4 } },
|
||||
{ "\xe2\x56\xb4", 3, { 0xc1, 0x5f, 0x9c, 0x8d, 0x8b, 0xeb, 0x7a, 0x1e, 0xc3, 0xd2, 0x30, 0xb6, 0xc1, 0x45, 0x4b, 0xee } },
|
||||
{ "\xc9\x4d\x9c\xda", 4, { 0x00, 0x7b, 0x90, 0x9a, 0x99, 0xbd, 0xc8, 0x6b, 0x70, 0x54, 0x3b, 0x17, 0xfa, 0xae, 0x7c, 0xca } },
|
||||
{ "\x79\xf1\x29\x69\x5d", 5, { 0xb3, 0x8c, 0x03, 0x90, 0x92, 0x18, 0x1d, 0x76, 0xfe, 0x37, 0xb2, 0xb2, 0x49, 0x8f, 0x84, 0x5e } },
|
||||
{ "\x00\x7e\xdf\x1e\x31\x1c", 6, { 0x0b, 0x4f, 0x0a, 0xa5, 0x2b, 0xaf, 0x0c, 0x3b, 0x6f, 0x80, 0xaa, 0xd8, 0xfb, 0x25, 0x09, 0xbf } },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 7, { 0xb6, 0xf1, 0x94, 0x8a, 0x57, 0x87, 0xfa, 0xe4, 0x18, 0x79, 0xab, 0x38, 0x5c, 0x4b, 0xc8, 0x5d } },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 8, { 0x9a, 0x13, 0x04, 0x08, 0x73, 0xb3, 0xe7, 0xd8, 0x22, 0xcb, 0x09, 0x11, 0xda, 0xce, 0xc2, 0x8b } },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 9, { 0x01, 0xd2, 0x9a, 0x1a, 0x6f, 0x81, 0x70, 0x76, 0xac, 0x74, 0xe9, 0xbc, 0x5e, 0x70, 0x76, 0xcb } },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 10, { 0x06, 0xd3, 0x6f, 0x5a, 0x8f, 0x86, 0x3b, 0xdd, 0x46, 0xa1, 0xa1, 0x5f, 0x75, 0xf0, 0x8f, 0xa3 } },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\x00\xb7\xae", 11, { 0x16, 0x2f, 0xc0, 0x17, 0x48, 0x37, 0xdc, 0xe0, 0x06, 0xa1, 0x78, 0xd5, 0xa8, 0xb7, 0xae, 0x2f } },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 12, { 0xc0, 0xa5, 0x2e, 0xda, 0x4e, 0x6c, 0xed, 0x9f, 0x3e, 0x36, 0x79, 0xac, 0x5d, 0x65, 0xb6, 0x88 } },
|
||||
{ "\x87\xd8\x61\x61\x4c\x89\x17\x4e\xa1\xa4\xef\x13\xa9", 13, { 0xda, 0xa3, 0x53, 0xaa, 0x70, 0xb5, 0xa2, 0xcc, 0x01, 0x60, 0xbf, 0x90, 0x60, 0x76, 0x42, 0x15 } },
|
||||
{ "\xfe\xa6\x5b\xc2\xda\xe8\x95\xd4\x64\xab\x4c\x39\x58\x29", 14, { 0xa9, 0x13, 0x46, 0x19, 0xc6, 0x8f, 0xed, 0x22, 0xde, 0xbf, 0x77, 0xbd, 0xfb, 0x61, 0xa4, 0x0d } },
|
||||
{ "\x94\x49\xc0\x78\xa0\x80\xda\xc7\x71\x4e\x17\x37\xa9\x7c\x40", 15, { 0xe3, 0x99, 0xd9, 0x33, 0xc9, 0xc6, 0xf5, 0x16, 0xdf, 0x60, 0x39, 0x1a, 0xe7, 0x56, 0x3e, 0x30 } },
|
||||
{ "\x53\x7e\x36\xb4\x2e\xc9\xb9\xcc\x18\x3e\x9a\x5f\xfc\xb7\xb0\x61", 16, { 0x92, 0x65, 0x17, 0x2d, 0xa5, 0xfb, 0x6d, 0x60, 0xdc, 0xd0, 0xce, 0x45, 0x52, 0x63, 0xad, 0x13 } },
|
||||
{ "\x59\xa9\x9f\xa6\xdb\xb7\x02\xc5\x95\x65\x34\x17\xde\xe5\xbb\xdf\xc5", 17, { 0x6d, 0xae, 0x56, 0xbf, 0xa2, 0x8b, 0x0a, 0x62, 0x3c, 0xf7, 0x12, 0x95, 0xe0, 0x3d, 0x9e, 0xa4 } },
|
||||
{ "\x0d\x52\x83\x32\x6a\x92\xf9\x9a\x6e\x3c\x3d\x5e\xc4\x25\xfe\xc1\xc4\xbe", 18, { 0xf2, 0x00, 0xea, 0x7b, 0x07, 0xe8, 0xf4, 0xf7, 0xbc, 0x36, 0xd5, 0x3b, 0x4a, 0x35, 0x01, 0x66 } },
|
||||
{ "\x59\x84\x02\x3f\xbc\x20\x01\x70\xed\xa0\x05\x14\x23\x18\x06\xf2\x52\xc5\xc1", 19, { 0xfc, 0x1c, 0x08, 0x2b, 0x38, 0x0b, 0x86, 0xf9, 0x62, 0x01, 0x50, 0x17, 0x13, 0x70, 0x86, 0xe8 } },
|
||||
{ "\x81\x84\xc3\xe8\x2f\x63\x65\x79\x4e\xd3\x34\x2c\x9c\xbc\x87\x05\x6d\xe5\xbc\x0a", 20, { 0xfb, 0xb8, 0x1e, 0xc4, 0x33, 0x0c, 0x81, 0x8b, 0x9f, 0x93, 0xf7, 0x33, 0xe4, 0xdf, 0x12, 0x0c } },
|
||||
{ "\x77\xfc\x10\x0f\x3a\xb2\x20\xad\x0a\x03\xfd\x51\xba\x93\xe6\x70\xe7\x34\xa4\xd8\xde", 21, { 0x09, 0x77, 0x2c, 0xd4, 0xc8, 0x21, 0xce, 0xf3, 0x15, 0xee, 0x0a, 0xef, 0x1b, 0xdf, 0x79, 0x31 } },
|
||||
{ "\x84\x87\x22\x2b\xb3\xf8\x44\xbf\x63\xbb\x43\xbd\xa8\xc4\x05\xe1\x2f\xb2\x44\x8d\x7a\xec", 22, { 0xc7, 0xb8, 0x65, 0x7e, 0xbc, 0x87, 0x1f, 0xbb, 0x56, 0x47, 0xde, 0x82, 0x6d, 0x23, 0xdc, 0x23 } },
|
||||
{ "\x9f\x72\x49\x57\xca\xd7\x15\xb1\xe6\x89\xb5\x8d\xec\x5f\x24\xeb\x42\x69\x5a\x73\x70\xb5\x56", 23, { 0xc0, 0x92, 0x04, 0xcb, 0x56, 0x1c, 0x82, 0x54, 0x66, 0xff, 0x4d, 0x02, 0xa4, 0x75, 0xfb, 0xab } },
|
||||
{ "\x4e\xec\xbd\x3d\xa2\x11\x70\x9c\xa8\x2e\xdb\xca\x6b\xbb\x74\x69\x1e\xa7\x03\x0b\x1b\xcd\x2e\xf0", 24, { 0x96, 0x49, 0x0a, 0x9c, 0xef, 0x7d, 0xe0, 0x15, 0x4d, 0x76, 0x7a, 0x39, 0x7e, 0x2d, 0xe8, 0x58 } },
|
||||
{ "\x74\x84\x9f\xed\x38\x55\xd4\x69\x44\xc8\x82\x82\xc2\x57\xa7\x4d\x43\x84\x2b\x3a\x75\x06\x32\x95\x81", 25, { 0x7f, 0xaa, 0x9d, 0xbf, 0xa5, 0xb8, 0xad, 0xe4, 0xaa, 0x1e, 0x11, 0xb3, 0x83, 0x59, 0xec, 0x8f } },
|
||||
{ "\x1e\x01\x28\x03\x09\x8a\xfe\xa7\x8e\x95\x42\x5d\xb7\x8d\x46\x38\x9c\xe5\xa1\xe8\x5a\x25\x70\xd2\x23\x95", 26, { 0xb2, 0x19, 0xf5, 0x35, 0xe2, 0x17, 0x94, 0xd8, 0x0c, 0x5c, 0x03, 0x78, 0x66, 0xd3, 0xe8, 0x94 } },
|
||||
{ "\xbc\xc9\x70\x84\xfc\x6c\x51\x35\xb1\x1c\xe4\x67\x2f\x97\xe4\x80\x7c\x36\x59\x55\x51\xbf\x6d\x98\x3d\xe8\x5f", 27, { 0x79, 0xca, 0xd3, 0xb3, 0x5d, 0xee, 0x4d, 0xa4, 0x00, 0xa9, 0x5c, 0x20, 0x3b, 0x19, 0x7d, 0x16 } },
|
||||
{ "\xdf\xe9\x69\x90\x4d\x76\xbc\xbb\xdf\x03\x74\x42\x55\x4a\x37\xa3\xba\x6a\x5a\x09\x92\xbf\x17\xff\xa0\xed\x6d\x3f", 28, { 0x7c, 0xca, 0x53, 0x89, 0xcd, 0x37, 0x11, 0x06, 0xf9, 0xd0, 0x8e, 0x41, 0x17, 0xd7, 0x42, 0xe4 } },
|
||||
{ "\x51\xfc\x95\xa9\xc8\x9d\x1c\x4f\x87\x8b\xa2\xad\xb7\x0d\x2d\xf6\x14\x98\x2b\x89\x77\x91\x02\x83\x01\x2f\x56\x6e\xe1", 29, { 0xdb, 0x92, 0x9e, 0xe8, 0x1e, 0xf7, 0x3a, 0xc6, 0xfc, 0x66, 0x8b, 0x7f, 0x3b, 0x77, 0x56, 0x64 } },
|
||||
{ "\x7f\xd6\x16\xc3\x81\xc3\x7c\xd6\x70\xff\xe4\x77\x1f\xcd\x09\x7f\x7f\x2b\x71\x26\x3d\xc9\xdb\x92\x88\xa5\xd4\x00\xf0\x44", 30, { 0x6d, 0x2e, 0x0a, 0x81, 0xbc, 0x6a, 0xd7, 0x2d, 0x04, 0xba, 0x4a, 0xcc, 0x0b, 0x3b, 0xc9, 0xf8 } },
|
||||
{ "\x68\x8e\x6a\x8e\xf6\xa2\x70\x47\x1d\xfb\x45\x26\xd2\x52\x56\x94\x94\xac\xbc\x02\xb6\x3f\xde\xe7\xdb\xfe\x34\x55\x81\xc3\x26", 31, { 0xe3, 0xc8, 0xa6, 0x56, 0x3f, 0x8c, 0x6e, 0x64, 0x11, 0xb3, 0x8a, 0x09, 0x95, 0xcf, 0xa0, 0xe1 } },
|
||||
{ "\x37\xb3\x18\x13\x29\xe2\xa2\x6d\xf4\xce\x2b\x01\xa5\x9f\x4b\x54\x48\x10\xb1\x29\x46\xcb\x13\x20\x58\xcf\xb0\x78\x27\x0d\x7e\xf5", 32, { 0xe0, 0x0a, 0x19, 0xff, 0x6e, 0xee, 0x06, 0x88, 0xea, 0x38, 0x6b, 0xc8, 0x68, 0x6a, 0x94, 0xa2 } },
|
||||
{ "\x82\x13\xf6\xdd\x3b\xdf\x78\x1c\x9e\xd6\x5b\x87\x8f\xcd\x95\x3d\x3f\x43\x04\x2a\x8b\xb2\x57\xa5\xf1\xfa\x9c\x39\x2f\xfe\x66\x81\x7a", 33, { 0x2b, 0xba, 0x42, 0x8d, 0xb0, 0x96, 0xcd, 0x0c, 0xc3, 0x6a, 0x05, 0x7c, 0x81, 0x42, 0x6f, 0x4c } },
|
||||
{ "\x4a\x9a\x2c\x58\xf1\xd6\x21\x1a\x76\x7f\xbc\xfa\xe0\x66\x35\xcd\xf1\x17\x22\x64\x6f\xbd\x13\x85\xa1\xb5\x5b\x81\xd6\xad\xee\x72\x1e\x79", 34, { 0x20, 0xdf, 0x47, 0x95, 0xc3, 0x0d, 0x81, 0x29, 0xdc, 0xd2, 0xf7, 0x28, 0x7c, 0xf8, 0xef, 0xa9 } },
|
||||
{ "\x66\x13\x1c\x72\x20\x3c\xf3\x8b\x83\xf8\x5e\xf2\x60\x44\xdc\x5e\x75\x67\x08\xfb\x0c\xe9\x07\xf0\xc1\x31\x1a\x89\x60\xbf\x53\x06\xed\x02\x64", 35, { 0xe9, 0x2a, 0x0c, 0x85, 0xe6, 0xaa, 0x86, 0x00, 0xdd, 0xb1, 0x3e, 0x0f, 0xa4, 0xd2, 0x5d, 0xa1 } },
|
||||
{ "\xff\xbd\xd6\x92\x72\xc1\x9e\xc9\x6b\xe3\xfb\xca\x4e\x88\x26\x7f\xc4\x36\xf0\x70\x40\x4f\x53\x4d\x2d\xfc\xb3\xab\xb6\x25\xb7\xcc\x31\x9c\xbf\x97", 36, { 0x90, 0x40, 0x16, 0xeb, 0xb9, 0x97, 0x22, 0xd2, 0x28, 0x99, 0xd8, 0x87, 0x57, 0x71, 0x58, 0x9c } },
|
||||
{ "\x29\x59\x01\xa6\x06\xe0\x43\x7e\x5b\xbf\x37\xda\xcc\x33\x6e\x20\x9a\xeb\xfa\xf5\xcd\xe4\xa5\xec\xfd\x73\xc7\x59\xbc\x61\xc8\x44\xa3\x30\x33\x79\xf8", 37, { 0xf4, 0x09, 0x5a, 0x82, 0x2b, 0x32, 0x80, 0x9a, 0x0a, 0x71, 0x32, 0x74, 0x57, 0x18, 0xc5, 0x40 } },
|
||||
{ "\x7c\x72\xbd\xf9\x7d\x2c\x1b\xc8\xa9\x38\x5c\xf2\x76\x3c\x94\x9d\x3d\xe7\xd9\x4e\x3a\xc7\x0f\x55\xb0\xc7\xdf\xd5\x29\x49\xc6\x74\xdb\xdc\x49\x9b\x27\x9a", 38, { 0x12, 0x88, 0x65, 0xe1, 0x77, 0x1a, 0x72, 0xd0, 0x39, 0xc4, 0xcd, 0xc6, 0x21, 0x0e, 0xa5, 0x13 } },
|
||||
{ "\x46\x6a\x3b\x21\x66\x3c\xd6\x2c\xaf\xd2\x2b\xcd\x36\x1e\xdf\x49\xf2\xae\x2d\x8f\xab\xb3\x29\x57\x10\xae\x22\xd4\xe8\xb6\x20\x15\x61\x68\x8c\xfd\x85\x6b\xef", 39, { 0x31, 0xe0, 0x8f, 0xd8, 0xfd, 0x6b, 0x31, 0xa2, 0xc4, 0x03, 0x70, 0xb9, 0xe1, 0x0d, 0x95, 0x16 } },
|
||||
{ "\xdd\xca\x9e\xd3\xab\xc8\xe1\xc5\xe2\x05\x7d\x7c\xf5\xec\x31\x14\x71\xdd\xda\x73\xae\x5e\xbd\xcd\x31\x6e\x74\x42\xa1\xfa\x74\xa4\x64\x69\x37\x57\xd6\x52\x0a\x51", 40, { 0x44, 0xa4, 0x8b, 0x8f, 0x05, 0x9d, 0x67, 0xeb, 0x05, 0xac, 0xed, 0x43, 0x92, 0x50, 0x91, 0xf9 } },
|
||||
{ "\x26\x4d\x75\x42\xcc\xe7\x42\xcd\xaa\xaf\x2c\xf3\xbf\x6d\x26\x91\x82\x72\x44\x00\xe1\x0b\x4a\xda\xd5\x0f\xd0\xdc\xa2\x98\x0e\xe7\xa8\xce\x4a\x21\xe9\xdf\xdb\x38\x18", 41, { 0xae, 0x76, 0x17, 0x96, 0x45, 0x61, 0xbb, 0x31, 0xbb, 0xf5, 0xc4, 0x6e, 0xe9, 0xc6, 0x22, 0xf8 } },
|
||||
{ "\x0b\xd8\xc7\x5a\xdb\x62\xd1\x9c\x71\x8b\x69\x90\xfb\xe2\x74\x45\x41\x9d\x87\x61\x5e\x61\xea\xfe\x8c\xb0\xbe\x1f\x18\xef\x3a\xce\x74\x13\x11\xd3\x6b\xe8\xf0\x12\x6f\xfe", 42, { 0x07, 0xd5, 0xac, 0x77, 0x53, 0xc4, 0x8c, 0xd9, 0xb4, 0xec, 0x2b, 0xa5, 0xa5, 0x57, 0x45, 0xaf } },
|
||||
{ "\x23\x82\x0e\x30\x57\xc6\x83\xd2\x7a\x69\x69\x76\xbf\xbb\x8b\x5b\xbd\x42\xd6\x73\xb7\xdf\x70\x10\xf6\x7f\xe1\x2a\x53\x7a\x6f\x4f\xd1\x8b\x89\x27\x66\x6d\x59\xa3\xdb\x0e\x7c", 43, { 0x52, 0x80, 0xcc, 0x28, 0xb7, 0x1b, 0x2d, 0x6f, 0xcd, 0x73, 0xe1, 0xd7, 0xa9, 0xd0, 0xe6, 0xb4 } },
|
||||
{ "\xc2\xc9\x72\xce\xff\xc3\x27\x5e\x5b\x92\x60\x81\x02\x9b\xb1\x02\x9d\x5d\x66\x77\x33\x17\x80\xaf\xbc\x86\x4d\x47\x44\xcc\xa3\x5b\xb9\x6c\xb9\x5a\x51\x72\xa1\xf3\x9a\xb0\x66\x2c", 44, { 0xe3, 0x96, 0x4f, 0xe1, 0x37, 0xb0, 0x7a, 0xc6, 0xeb, 0xbe, 0x59, 0x4f, 0xfa, 0xaa, 0x95, 0xf1 } },
|
||||
{ "\x1f\x22\xbe\x91\xb4\x73\x6c\x89\x5f\x99\x35\xc4\xe3\x9b\x7c\xd0\xea\x73\x7c\xcb\xce\x0e\x22\x33\x04\x6f\x85\xd9\x25\xf4\x03\xf4\x9b\xb1\xf9\x52\xe4\xf8\x1e\xa9\x86\xfb\x7d\x0c\x8f", 45, { 0x6f, 0xb0, 0xa2, 0x69, 0x84, 0x9d, 0x97, 0x2b, 0x05, 0x8d, 0x15, 0x87, 0x7b, 0x2b, 0xa3, 0xc0 } },
|
||||
{ "\x88\x0d\x79\xc8\xf2\xee\x8f\x76\x10\x42\x5d\xcc\x5f\xa6\x55\xf0\x43\x4c\x5f\xa8\x6b\xb7\x0a\xa1\x51\x11\xdd\x5c\xe1\x2c\xcc\xb6\x31\x13\xc6\x12\x6f\x4c\x6b\x24\xd9\xae\xdb\x5d\xe4\xd9", 46, { 0x8c, 0x08, 0x81, 0x71, 0xd6, 0xf1, 0x21, 0x47, 0xe1, 0xac, 0x8a, 0xed, 0x99, 0xa2, 0x4c, 0x1f } },
|
||||
{ "\xaa\xee\x80\x55\xef\x7b\x73\x4a\x7c\x5e\xe2\xd9\x27\x95\xef\x17\x47\x49\x7b\xa4\x3b\xfc\x0c\xeb\x24\x4e\xca\xf8\xb2\x6b\xa4\xf0\x1c\x14\x90\x32\x29\x49\xef\x09\x6c\x91\x0e\x0a\x8d\xe5\xc9", 47, { 0xca, 0x4d, 0x13, 0x4c, 0xb6, 0xdf, 0xee, 0x5b, 0x9f, 0xb9, 0x05, 0x0d, 0xb6, 0x91, 0x7d, 0xd7 } },
|
||||
{ "\x11\xc1\x3f\x4a\xd2\x5b\xba\xef\x1e\x7c\x66\x4a\xb5\xe6\xaa\x41\xc2\xef\x56\x56\xf7\x91\x45\x01\x45\x9e\xab\x3a\x38\x10\x01\x13\xee\x7f\x8a\x81\xb2\xab\x80\x3b\x39\x39\xe0\xba\x78\x7b\xcf\x61", 48, { 0xf5, 0x57, 0x8d, 0x27, 0xa0, 0xa1, 0xcb, 0xc7, 0xe8, 0x2f, 0x77, 0xec, 0xdd, 0xa3, 0x84, 0xf7 } },
|
||||
{ "\x20\x68\xa7\xb7\xb8\xab\xa3\xcf\x55\xd7\x23\xc9\xf7\xb7\x9b\x71\x83\xc3\x1e\x04\x59\xaf\x83\x13\x91\x1e\x31\x81\xd7\x75\x8d\xa6\xe0\xca\xfc\x96\x88\xfa\x97\x7c\x8a\xd9\x6b\x1f\xdb\x85\x69\x87\xa3", 49, { 0x94, 0x10, 0x45, 0x76, 0xe9, 0xd7, 0x75, 0xce, 0x30, 0xcb, 0x28, 0xb7, 0xbc, 0xc0, 0x98, 0x94 } },
|
||||
{ "\xd4\xf1\xb9\xd9\xeb\xf5\x9d\x7a\xf0\xcd\x01\x65\xd7\x98\xb6\xd6\x59\x49\xd8\x7d\x03\x55\x2c\x3a\x6b\xf7\xa1\x78\x7d\x1e\xf9\x23\xf3\xf5\x81\x47\xe3\x0c\xfc\x46\x72\x28\x9e\xb6\xa6\xa4\x34\xd5\x5a\x81", 50, { 0x8f, 0x3d, 0x45, 0x4f, 0x31, 0xdc, 0xf9, 0xdc, 0x48, 0xbe, 0x95, 0x53, 0x80, 0xf1, 0xc0, 0x74 } },
|
||||
{ "\x61\xa9\x4a\x12\x02\xb8\x4e\x3d\xb3\x61\xa4\x6e\x6b\xd6\x66\x1e\x42\xb7\x1a\xfb\x54\x4b\x68\xb5\xbd\x5d\xe6\x65\xc3\xb1\x0f\x99\x13\x22\x53\x00\x24\x59\x48\xaf\xb8\x2c\xfe\x0d\x81\x90\x70\x62\xe0\x3c\x15", 51, { 0x5d, 0xe7, 0x06, 0x6a, 0xbc, 0x01, 0xd0, 0x64, 0x94, 0x29, 0xae, 0x04, 0xf1, 0xcc, 0xb5, 0xd6 } },
|
||||
{ "\xf6\xc8\xdd\x96\xe9\xc2\xef\x9b\x8f\x09\x3f\xbf\x85\xd5\xfa\xa2\x55\xb5\x70\x1c\xc1\x15\x6b\x8e\xb0\xdf\x26\x55\xb2\x3e\xec\x58\x32\x7e\x4f\xc1\x37\x10\x01\xc8\xd6\xa9\x52\xab\x38\x89\x46\xba\x44\xd9\x52\x8e", 52, { 0x84, 0xae, 0x25, 0xbc, 0x36, 0x9c, 0x91, 0x9b, 0x44, 0x2e, 0xd6, 0xef, 0x9e, 0x1f, 0xe2, 0x8f } },
|
||||
{ "\xe9\x2d\xb3\x5a\x09\x2a\x6c\x59\x05\x41\xda\x67\xe1\x99\xf5\xac\x14\x0b\x25\x73\xef\x47\xbe\x19\xa7\x14\x1a\x20\x01\xb4\x52\x63\x99\x65\x98\x64\xce\x04\x34\xc1\x4d\xcd\x19\xc5\x39\x3d\x24\x1b\xf4\x18\xf0\x9e\x8d", 53, { 0x1e, 0xa3, 0x3b, 0xad, 0x84, 0x80, 0xa6, 0x3e, 0x7a, 0xbe, 0xe1, 0xc2, 0xf6, 0x07, 0x6c, 0x8f } },
|
||||
{ "\x86\x58\x4b\xc6\x59\x8a\x58\xc0\x6a\xc4\x5e\x45\x21\xaf\xb1\xb2\x12\x54\xd0\x7f\xc4\xbf\xf8\x6d\x8e\x2f\xd3\x4b\x9b\xf6\x4e\x64\x0c\xf3\x88\x88\x3c\xaa\xe6\xb5\x1f\xfd\x43\x63\xc3\x89\x45\x69\xf9\xa0\xcb\x8f\x0d\xde", 54, { 0x18, 0x55, 0xdc, 0x67, 0x81, 0x98, 0xdf, 0x9d, 0x59, 0x3d, 0xed, 0xb3, 0xf2, 0x14, 0x22, 0x43 } },
|
||||
{ "\x82\xb1\xb0\x6a\x97\x8c\xf7\xcb\x86\x28\x7c\x64\x11\xe2\xa2\x8e\x4d\x15\xf7\x50\xd6\x64\xb2\xbd\x23\xa7\x5b\xeb\xf4\x70\x8a\x8b\xe8\x39\xc7\x2a\x2b\x2b\x91\x03\x4c\x8d\x7a\x7e\x2c\xc8\x6f\x49\x12\x13\x16\x12\xdc\xbf\x50", 55, { 0x7c, 0xd8, 0x1e, 0x1e, 0xfb, 0x01, 0xad, 0x5a, 0x4c, 0x0e, 0x83, 0xbd, 0x9d, 0x2e, 0xe1, 0xff } },
|
||||
{ "\xde\x50\x21\xdd\x09\x91\x17\x1f\xda\xad\x39\xf7\xc2\x53\x9e\xcc\x32\xa2\x48\xaa\x16\x1c\x2d\x86\xf1\xb9\xe2\xa0\x96\x18\xe6\x01\x80\xd0\x89\x24\xcf\xe5\x77\xb1\xe0\x57\xe5\x64\x87\xd4\x57\x0d\xeb\x8d\x0b\xb0\xff\x25\x06\xcc", 56, { 0xb5, 0x25, 0x80, 0x30, 0x10, 0x74, 0x47, 0xb8, 0xac, 0x64, 0xa9, 0x31, 0x47, 0xd4, 0x6a, 0x69 } },
|
||||
{ "\x99\xc6\xb8\xb9\x30\x4e\x4e\x2a\x37\xa7\x95\xd2\x10\x35\x86\x24\xaf\x68\x72\x32\xcc\x71\xcb\xb7\xc4\x11\x8c\x30\x0d\x8c\x46\x24\x54\xbd\xc8\x85\x35\x43\x6b\x2f\x96\xd9\xf7\x8d\xa0\xc4\x36\x5b\x5b\x65\x13\x85\xe6\xee\x6d\x2f\x4f", 57, { 0xf2, 0xeb, 0xbc, 0x0f, 0x7b, 0x22, 0x29, 0x53, 0xd2, 0xcb, 0x16, 0x52, 0x41, 0x8f, 0xf5, 0x27 } },
|
||||
{ "\x31\x7e\xce\x15\x94\xe2\x73\x37\x21\x47\x28\xf8\xba\xb0\x73\x32\x69\x65\xf7\x54\xd6\x7b\x3a\xfa\xd2\xfc\x82\x28\x0f\xb2\xd8\x22\xf2\x95\x2e\xea\x81\xce\x9c\x57\x77\x67\xc6\xce\x77\x92\x5a\xa0\x5d\x93\xb6\x00\xaf\x4a\xa6\x9f\x32\x61", 58, { 0xb7, 0x47, 0x82, 0x40, 0x69, 0x9d, 0x2d, 0x25, 0xd5, 0xce, 0x1b, 0xd5, 0xeb, 0x8c, 0xbf, 0x71 } },
|
||||
{ "\x4b\xe6\x99\x0e\x17\xcf\x58\x85\xf4\x60\x98\xfe\x84\xc6\x43\x5e\x84\x0a\x3e\x84\x4a\x72\xb7\x33\x6d\x77\x94\x97\x83\x5d\x0a\x76\x05\x75\x4f\xf4\x4f\xeb\x67\x02\xc4\x4c\x1b\x65\x0f\x99\x09\x5f\x84\x00\xd4\xfc\xa4\x3d\x7b\xfa\xbf\x8d\xc7", 59, { 0x82, 0x36, 0x57, 0xa2, 0xc1, 0xad, 0x78, 0x3f, 0xb9, 0xfb, 0xa2, 0xc6, 0x79, 0x7e, 0xca, 0x7a } },
|
||||
{ "\x55\xb4\x4a\xde\x6f\xd4\x28\xf6\xd9\xe5\x0a\x23\xc1\x42\x82\x50\xf8\x20\xe4\x4c\x9e\xeb\x05\xfc\x6b\xce\x95\xaf\x9d\x52\x16\x8f\x7a\x1e\x78\x32\x81\xdd\x53\x50\x31\x3d\xc0\x8f\x75\x13\xd5\x7b\xaa\x9b\xbb\x91\x4f\xdd\x6c\x7a\x48\x2c\x0e\x55", 60, { 0x7a, 0x3f, 0x5c, 0x60, 0x63, 0x7e, 0x72, 0xdf, 0xcc, 0x23, 0x8a, 0xa3, 0x84, 0x14, 0x20, 0xe2 } },
|
||||
{ "\xcf\xc9\xe7\x2d\xf7\xa4\xfd\x8a\xde\x42\x4b\x23\x6f\xba\xa1\xb1\xd1\xd9\x19\xde\x70\x65\x31\x5c\xa6\x7f\x8a\x13\x05\x21\x3c\x72\x43\xc7\xd4\xe7\xc3\x2b\xeb\x69\xbc\x28\x64\x32\x08\xc0\x41\x8b\x8b\x39\x22\xbf\x3e\x62\x5c\x31\xd7\xf3\xb2\x8a\x17", 61, { 0xe3, 0x74, 0x31, 0xe3, 0xd2, 0x5e, 0x01, 0x00, 0x51, 0xde, 0x8c, 0x48, 0x58, 0x76, 0xaa, 0xca } },
|
||||
{ "\x12\xb3\x0a\xb0\xf2\xaf\x00\xd0\x96\x57\x55\x4e\xb4\xf0\x42\x70\xb4\x34\x21\x56\xd7\xc5\x61\x07\x75\x4f\x94\x17\x5e\x39\xa3\xf1\x62\x07\x21\xc7\xed\x4f\xbc\x13\xca\x55\xd0\xc8\x08\x46\x15\x1a\xfa\x0d\x79\xe7\x58\xd6\x09\xc0\x82\x1d\x08\x98\xe5\x72", 62, { 0x14, 0x7a, 0x4d, 0x78, 0xbe, 0xcf, 0x03, 0xf0, 0xa6, 0x57, 0x16, 0x8d, 0x7e, 0x07, 0xa8, 0x36 } },
|
||||
{ "\x22\x09\x76\xcb\xba\x3d\x5c\x85\x60\x7f\xaa\xf9\x5e\x5e\x4a\xb7\x71\x7b\xf5\x62\x95\xf0\x5e\x28\xf9\x5d\x6e\xdb\x12\x90\xaa\xb1\xcc\xd0\xb2\x95\xdb\xc7\xe3\x27\x2f\x09\x1b\x57\x85\x45\x9c\x99\x1a\x07\x09\xc5\x7a\x27\x8e\x8f\x77\xd2\x1d\x9e\x36\x32\xd3", 63, { 0x8d, 0x97, 0x7a, 0xb1, 0x6f, 0x7a, 0x54, 0x80, 0x88, 0x10, 0x07, 0x3b, 0xb4, 0x6a, 0x19, 0xb9 } },
|
||||
{ "\x4a\x64\xbd\x79\xf7\x86\x17\x25\x09\x6d\xa5\x01\x83\xc7\xaf\x23\x3f\xd2\x31\x9c\xcc\x2c\x3f\x8d\xdf\xc7\x12\x72\x78\xf8\xb3\x82\x93\xae\x42\x2f\x86\xbf\xe3\xc8\xfd\x5e\x46\x3f\x90\xa9\xd2\x04\xfe\x5f\x6e\x0f\x09\xaf\xeb\xfd\xed\x2b\x11\x52\x7e\xdc\x45\xdd", 64, { 0x15, 0xf4, 0x8b, 0xb9, 0x10, 0x92, 0xcd, 0x68, 0x96, 0xc1, 0x4c, 0x7d, 0x00, 0x47, 0x36, 0x34 } },
|
||||
{ "\xdd\x6e\xd4\x39\xd6\x8c\xde\x6f\xda\x47\xe1\xb9\x94\xaf\xe1\x62\x29\x84\x32\xc9\x11\x06\xe2\x84\x8d\xe9\xc5\xa0\xc4\x65\x1d\x07\x7e\x69\xe6\xfb\x7c\xef\xbc\xbe\x71\x6b\x6a\x54\xa1\x5d\x10\x60\x15\x06\xf0\x2b\x78\x37\xd5\xc4\x92\x44\x20\x41\x5e\x18\x70\x23\xc9", 65, { 0x8e, 0x53, 0x6f, 0xfb, 0xda, 0xda, 0x44, 0x77, 0xb3, 0x44, 0x3e, 0x65, 0xec, 0xbc, 0x40, 0x2a } },
|
||||
{ "\x62\xed\xd8\x0a\xed\x32\x59\x98\x0e\xd4\xf4\xcd\x36\x93\x24\x15\xa7\x1d\x9c\xd2\x44\x79\x63\xd0\x81\x16\x18\x60\x79\x71\x57\x13\x1e\x5d\x34\x15\x8a\xf2\xe4\x23\x75\x14\x7c\x2a\xc0\x9f\xd1\x7e\x2d\x2c\x7d\xb3\x32\x83\x03\x1c\xe2\x9d\x0a\xdd\x0b\x54\xc6\xaf\x5f\xa9", 66, { 0x3b, 0xd1, 0xd1, 0xc0, 0xfa, 0xcb, 0x9c, 0xdb, 0x86, 0x97, 0x8f, 0x09, 0x31, 0xa6, 0x10, 0xca } },
|
||||
{ "\x74\x30\xca\xb2\x03\xe5\xe2\x1e\xd0\xcd\x7d\x66\x8a\xa2\x5c\x92\x35\xaf\x04\xa5\x4a\x49\xad\xa7\xfb\xeb\x54\x4d\x93\xf2\xeb\x46\xfc\xf1\xb1\x24\x5a\xb2\x9c\xe5\xd5\xca\xf1\x1e\x75\xd8\xf6\xc3\x26\x5a\xc0\x95\xda\x2b\x26\x28\xcd\x9d\xd6\x90\xe4\x2f\x85\xa8\x2f\xeb\x42", 67, { 0xfe, 0x03, 0x68, 0xe3, 0xc5, 0xf8, 0xb8, 0x4d, 0x9b, 0x29, 0x4b, 0x26, 0x36, 0x39, 0x34, 0xe6 } },
|
||||
{ "\xfe\x8e\x5f\xe4\x5e\x6f\x35\xa2\xfa\xb5\x71\xc1\x33\xb4\x47\x68\x06\x59\x97\x8f\x16\x67\x06\x16\x52\xdc\xba\xf2\x42\x72\xb1\x82\xf3\x41\xbf\x00\x7d\x81\x22\x12\x2e\x6e\xc3\x80\x55\x44\x0c\x01\xac\x6a\x60\x2e\x63\xab\x3b\x98\xc5\x9f\xe8\xf5\x89\x28\xd9\x75\xb8\x18\xa6\x33", 68, { 0xb7, 0x0e, 0x24, 0x63, 0x59, 0x66, 0x0c, 0xa2, 0xfb, 0x46, 0xc6, 0xa1, 0x72, 0xd1, 0xd9, 0x3f } },
|
||||
{ "\x35\xf0\xa5\xc6\xee\xc3\x22\xf8\x9e\x3a\x3b\x8e\x3c\xb0\x5b\x46\x03\x7d\x51\xdf\x1f\x50\x0c\x52\xf1\xb6\xf5\x1e\xff\xb7\xe9\xc1\x7b\x9f\xd2\x42\x6e\xda\xe1\xeb\x81\xf9\x69\x15\x68\xd1\x5b\x1b\xec\xc2\x5a\x71\x93\x15\x7a\xcd\xed\x7f\x9a\x83\x7e\xc2\x5b\xee\x43\x73\xbc\x0a\xe3", 69, { 0xd4, 0x3f, 0xb8, 0xeb, 0x1a, 0xb1, 0xed, 0xed, 0x3a, 0x26, 0x8f, 0x0b, 0x7d, 0x06, 0x0a, 0x64 } },
|
||||
{ "\xd6\x54\x1f\x73\xe5\x2b\x98\xe6\x70\x34\xf2\x10\x5e\x6b\xd0\x55\x11\x87\x2b\xf2\xe8\x5d\xa6\xe7\xde\xd1\xff\x80\x4f\x79\xa2\x7f\xdb\xd0\x58\xe8\x63\x13\x1c\x69\x31\xbb\x0e\x63\x34\x98\x81\x99\x68\x87\x2f\x74\x54\xd0\x8c\xf0\xad\x1e\x37\x27\x18\x1b\x8d\x78\x0d\xa8\x58\x54\xd7\xb6", 70, { 0xbd, 0x93, 0x38, 0x13, 0x7b, 0x70, 0x0d, 0xa8, 0x1b, 0x1a, 0x7a, 0x2d, 0xbe, 0x11, 0x15, 0x38 } },
|
||||
{ "\xa5\xa5\xb7\xc4\xb3\xda\x29\xf5\x07\x93\x3e\xcd\x9d\xe6\x28\x88\x38\x4c\xd4\x17\xdb\x2c\xb2\xb8\x50\x01\x90\x30\xe5\x2a\xa4\xa8\x37\x4e\xa8\x21\x26\x69\x20\x96\xe8\x78\xb7\xad\x39\xbd\xc7\x19\xb0\xaf\xf8\x8f\x2d\x82\x00\x62\x6f\x4e\x88\xbd\xc2\xdf\x2f\x7d\xd5\x18\xa7\xa9\xa9\x04\xfd", 71, { 0x7a, 0x7d, 0xc9, 0x94, 0x96, 0xaf, 0x51, 0x90, 0xc5, 0x48, 0x51, 0x9b, 0xeb, 0xd2, 0x6d, 0x3c } },
|
||||
{ "\x8e\xa6\x7b\xf7\x7b\xc8\x6d\x96\x16\xf6\xce\xbb\x5a\x73\x1e\xe6\x2e\x6d\x93\x19\xa2\xb3\xe6\xdb\xc8\x84\xb7\x58\x2d\x83\x9e\xa6\xf3\xc6\xcf\x22\x8c\x0d\x69\xf9\x15\x0f\x5b\xc3\x4d\xf0\xf3\x49\x30\xd0\x05\x67\x34\x7d\xb4\x0d\x1f\x48\xe0\x5f\x83\xf5\x2c\xfc\xd7\xcc\xaa\x5c\x34\xcc\x26\x53", 72, { 0x82, 0x13, 0x1c, 0x29, 0xf6, 0x16, 0x5a, 0x23, 0xba, 0xc4, 0x25, 0x2c, 0x5a, 0x9e, 0x9b, 0xde } },
|
||||
{ "\xa9\xff\x0c\xb2\x3b\xe9\xf7\x0c\x7c\x1a\xd6\x96\xc6\xe3\xbd\x28\x15\x25\x46\x60\x7e\x45\xa1\xe6\x50\x3b\x3f\xc9\xc6\xca\x17\x08\x65\xca\x94\x2e\xf8\xa1\x1b\x14\x26\xd0\x3c\xca\xad\xa9\x74\x91\x3d\x1e\x9d\xff\xf3\xb5\xf3\x45\x70\x99\xc3\x8e\x96\xca\xb2\x7d\xdf\x73\xa7\xd9\x59\x5c\x56\x45\x42", 73, { 0x92, 0x2d, 0x15, 0x76, 0x2c, 0xb6, 0xf5, 0x81, 0x60, 0xcc, 0x0e, 0xd5, 0x09, 0xff, 0x39, 0xb8 } },
|
||||
{ "\x76\x6a\x28\x3c\x94\x4e\xab\x2c\x39\x99\xe0\xb5\x8c\x14\x00\x4c\x68\x68\xcd\xf8\x90\x69\x16\xa9\xff\xf9\x59\x32\x5e\x9a\x82\xe3\x8f\x94\xd2\xc7\x66\xbf\xdb\x77\x78\xee\xa7\x99\x0b\xf8\xf9\xf9\x2d\x64\xab\x41\xe0\xb0\x36\x58\x72\x3e\x50\x55\xec\xdc\xb0\x1f\xa0\xee\xed\xa3\xe5\x3a\x84\xb0\xe0\x50", 74, { 0xa5, 0x43, 0x80, 0x60, 0x02, 0x56, 0x20, 0x34, 0xdf, 0x73, 0x76, 0xbf, 0xe5, 0x73, 0xcb, 0xbc } },
|
||||
{ "\xf8\x72\x78\x94\x14\x89\x6b\xea\x4c\xc5\x7f\xfc\x42\x80\xd0\x2a\x64\x98\x48\x0f\xb2\x08\x2e\xad\x9d\x23\xd5\x34\x0b\x6c\x74\x74\x78\x14\x16\xdc\x36\x11\xa8\x2e\xd4\xd7\x30\xc1\x9d\xb5\x1d\x72\x38\xcf\xb9\x28\x6d\xb4\xba\x03\x07\x9b\xf8\x21\xd4\x3f\x3a\x0c\xc9\x54\x29\xc3\x42\xa4\x66\x64\x68\xcb\xb7", 75, { 0xf9, 0x8f, 0xcc, 0xd8, 0x9b, 0xcd, 0x41, 0x55, 0x5b, 0xb0, 0xb5, 0xa2, 0xf4, 0x53, 0x3a, 0x88 } },
|
||||
{ "\x73\xac\x8b\x5c\xc9\x6f\xcd\x80\x1b\xc4\x35\xcb\x26\x4d\x60\x14\x74\x42\xbd\x34\xce\x90\x05\xf6\x3f\x1d\x58\x2a\xc0\x2a\xf6\xd9\x85\xd2\x96\x92\xe3\xaf\x66\xe3\xdc\x9c\xa0\xe3\x49\x94\xc6\xec\xa2\xb9\x7a\x67\x6d\x71\xfc\xc0\x41\xab\x40\x78\x76\x40\xab\x58\x6c\x74\x6a\xc3\x74\x9b\x6f\x25\x5e\xd8\x09\x88", 76, { 0xaa, 0x3b, 0xd6, 0x8d, 0x86, 0x26, 0x1f, 0x65, 0xe7, 0x23, 0x96, 0x84, 0xda, 0x55, 0xa7, 0x8d } },
|
||||
{ "\x9f\x01\x1f\x45\x1f\x9e\x09\xd7\x9d\x10\x0c\xcb\xc0\xcf\x6f\xd3\xbb\xcc\x3e\xfb\x9b\xf5\x9b\xf3\x30\xd7\xbb\x8a\x96\x5d\x84\x3c\x5f\xb6\xc2\xe2\x5e\x55\x00\x87\x12\x12\x09\x5b\xae\x6e\xfb\xc1\xc1\xf3\x04\x83\x87\xba\xbc\x25\xcb\x06\x1f\x57\x77\x0e\x25\x83\xba\xd8\x00\x87\xd4\x41\xf2\x7d\x81\x19\xc8\xb5\x00", 77, { 0xe5, 0xee, 0xc1, 0x56, 0xbb, 0x5a, 0x4f, 0xa7, 0x4c, 0x76, 0x0d, 0x17, 0x27, 0xfb, 0xc2, 0x3e } },
|
||||
{ "\x6b\xf6\xc4\xbe\xda\x50\xb6\xa4\x26\x63\x5e\xfa\xce\x6e\xcf\xf6\xd0\x00\xe3\xe5\x8c\x2f\xf8\xf5\xc7\x72\xbb\x9d\xca\x1c\x1c\xa9\xaa\x76\x61\xe5\xa3\x77\x56\x65\x9e\x22\xa2\x70\xd2\x7c\x36\x07\x86\x29\xde\x15\xf4\xa3\xfa\x34\x4a\x15\x46\x19\xca\xda\xd4\x9e\x11\x8d\x1c\x6b\x74\xcc\x2a\x3f\x86\x8e\xf5\xe0\xb6\x1e", 78, { 0x78, 0xa5, 0x61, 0x3a, 0x59, 0x4a, 0x02, 0xa5, 0xa3, 0xa6, 0x94, 0x54, 0x0b, 0xe8, 0x94, 0x0f } },
|
||||
{ "\xd0\x9d\x15\xb4\xf9\x7d\x36\xae\x4f\x06\x2e\x70\x21\xab\xbb\xd5\x22\xd3\x81\x50\x78\x82\x6f\xa4\xf3\xa6\x41\x3c\x5b\x00\x1e\x27\xe2\xad\x61\xb4\xb8\x51\x75\xa7\xbe\xdf\xd9\x15\x52\x06\x43\xe1\x49\x3b\xe1\xd3\xfa\x5f\xba\x52\x77\x0e\x33\xbe\xd7\x84\xae\x6c\xaf\x2b\x4d\x3f\x9f\xc5\xd4\xdf\x08\x32\xac\x99\xdb\xdf\x04", 79, { 0x23, 0x58, 0xdd, 0x9f, 0x9e, 0xdd, 0x10, 0xda, 0xc2, 0x01, 0x1b, 0xaa, 0xb3, 0xec, 0x5e, 0x13 } },
|
||||
{ "\xd3\x8d\xcb\x12\x2a\x27\x37\x78\x2a\x79\xea\xc1\xa9\x6e\x1e\x0a\xc0\x7b\x0a\xbd\x67\x31\x0d\x79\xac\xf3\x74\x0e\x90\xc1\xe8\xa4\x7e\x32\x77\xfb\x69\x80\x3d\xcc\x81\xbd\xae\x4f\x91\x24\x83\xd6\xf8\x8b\x3f\x96\x41\xf4\x5d\x86\x62\x42\x18\x61\x8e\x08\xd6\xc5\xb7\x7d\x32\x7d\xa3\x8c\xa5\xdc\xaa\x08\xd0\x40\x0a\xfd\x68\xb6", 80, { 0xe2, 0xa8, 0x37, 0xb5, 0xf7, 0x9d, 0x34, 0x76, 0x8c, 0x62, 0x65, 0xbe, 0x61, 0xb3, 0x81, 0xfb } },
|
||||
{ "\xe6\x21\xbe\xbc\xe1\x6a\xea\x21\x53\xb9\x93\x09\x27\xb4\x5e\x0d\x51\xb1\xf1\x7f\xee\xcd\xa3\xcb\xf9\x1d\xc2\xf8\xa7\xfc\x80\x4e\x61\x84\x7a\x12\x5c\x18\xe6\x6d\xd6\x1d\x59\x6b\xee\xc8\x33\x1e\x20\x12\xa8\xe3\x5d\xc9\x6b\xbc\xc3\xc0\xf9\xdd\xfe\x27\x7f\x42\x3a\xf5\x68\x7d\xc4\x81\x87\x8e\x3c\x30\xde\xea\x79\x49\x09\x9e\xf9", 81, { 0x56, 0x9a, 0x78, 0x23, 0xde, 0x2b, 0xe3, 0xea, 0x51, 0x96, 0xff, 0x8d, 0xac, 0x0f, 0x6e, 0x95 } },
|
||||
{ "\xe5\x4a\x8d\x03\x02\x32\xd5\x5c\xb6\xe8\x50\xa1\x80\x19\x36\x47\xba\x7c\xe0\x2d\x2a\x00\xa7\xdb\xb9\x95\xeb\x5a\x3b\x94\x30\xaf\x6c\xcc\x62\xf5\xfc\x2a\x39\x16\xc1\x04\xb7\x26\x0c\x02\xcf\x5c\x16\xa9\x20\xad\x98\x85\xde\x07\x79\xf3\xd2\x27\xa2\x88\x78\x17\xee\x22\x46\x48\x3d\x89\x0c\x47\xa7\xc1\x76\x1f\xce\xee\xaf\x4c\x4d\xe4", 82, { 0x2e, 0x98, 0xba, 0x76, 0xed, 0xff, 0xf1, 0x24, 0x93, 0x11, 0x1d, 0xae, 0xa9, 0x3c, 0x2c, 0x19 } },
|
||||
{ "\x20\x57\x4d\x4b\x56\x13\x36\x6b\x02\x72\x81\x9a\x19\x04\xac\x3f\x1c\x0e\x47\x82\x72\x43\x2c\x92\xf1\x22\xcc\x92\x7b\xeb\xa3\x21\xc5\x3f\xcd\x84\x33\x53\xb3\x73\xdf\xd0\xdd\x7d\xb9\x4b\xec\x18\xc8\x5c\x9f\x49\x8f\x5d\x12\xec\x8a\xc1\x08\xa1\xd7\x0e\x5d\x53\xf2\x78\x9e\x66\x99\x1c\xb4\x7c\xce\xd5\xbb\xe4\xfb\xbf\xf0\xa1\x2f\x46\xc9", 83, { 0xc1, 0x06, 0x74, 0x68, 0xa6, 0x97, 0x98, 0x95, 0xee, 0x75, 0x92, 0x71, 0xe1, 0xe8, 0x5a, 0x0a } },
|
||||
{ "\x12\x87\xe9\x1f\x42\xa8\x91\x87\xce\x68\x88\xbe\x6f\x8c\x18\x42\x24\xac\xc1\xfd\xfd\x33\x15\x1c\x85\x83\x34\xff\xcd\x35\xe0\x49\x11\x7e\x3c\x16\x0a\xad\x26\x4c\xcf\xd0\x2d\x0b\x69\x76\x31\x3e\xf2\x90\x96\x53\x68\x71\x24\x07\x13\xf5\x7f\x5a\x91\xbd\x3e\xa2\x7b\x98\xa9\xbc\xb6\xfd\x14\x5d\x58\xb4\xd2\x86\x34\x95\xd8\x16\x04\x69\xf0\x79", 84, { 0x0b, 0x29, 0x0b, 0x0f, 0xff, 0xe0, 0x89, 0x9c, 0xea, 0x43, 0x82, 0xda, 0xea, 0x48, 0x69, 0x79 } },
|
||||
{ "\x32\xed\x96\x7e\x43\xf4\x73\x47\xe0\xac\x73\x59\x83\xf9\x85\xd4\xba\xfd\xef\xbc\x1b\xb9\x4b\x75\xc5\xcd\x21\x4e\x8e\x5b\x22\x34\xce\x0a\xff\x87\xc7\x26\xe4\x09\xaf\xe5\x95\xf2\x5c\xc5\x23\x22\x8c\x10\x4a\x6e\xcd\x81\x6a\x1b\x0f\x01\x20\x69\xc4\x8a\x81\x46\xb1\x2d\xf3\x24\x55\x2e\xa7\xe4\xf2\x4d\xb6\xf1\x3c\x20\xd7\x6a\x9d\x9b\xbb\x77\x23", 85, { 0xd1, 0xd8, 0x5e, 0xa5, 0x95, 0xa7, 0x49, 0xac, 0x47, 0x06, 0x57, 0x0d, 0x28, 0x00, 0xf4, 0xa0 } },
|
||||
{ "\xb2\x05\xbd\x07\x15\xe9\xec\xdb\x1a\x60\x75\x4f\xb9\x05\x59\x9f\xb0\x90\x1d\x9d\xc7\xec\xda\x56\x2e\xf6\x70\x64\x02\xd4\xdb\xd0\xee\xf0\x9e\xa1\xee\x90\x5b\x06\x2f\x14\x84\x1b\x13\xcb\x2c\x5b\x50\x71\xf7\xa3\x38\x49\x30\xdf\x13\xd3\xf9\x53\xa8\x2b\x9d\x88\xdb\xfe\x02\xd1\x70\x29\x3a\x78\xed\xf0\x38\x8a\x9e\xd7\x9f\x3c\xb2\x20\xb6\xf9\x83\xe2", 86, { 0xf1, 0x5f, 0x79, 0x80, 0x57, 0x2d, 0x9a, 0xb6, 0xc1, 0x7f, 0x79, 0xf3, 0xc9, 0x37, 0x04, 0x63 } },
|
||||
{ "\x78\x09\xf3\xc3\xc8\xdf\xf2\x52\xc2\xff\x1b\x03\x2d\x8a\x7e\xc8\x0c\x67\x79\x48\x54\x10\xbf\xbe\xb7\xf6\x7a\x71\x9f\x92\x8d\xcb\x36\x0a\xf2\x19\xa2\x7c\x43\xde\x4e\xe9\x54\xd4\x64\xc1\xfd\x80\x57\x07\xf5\x71\x9c\x20\xd9\x15\x78\x3e\x4d\x37\xf4\x64\x39\x19\xee\x15\x35\x29\x4a\x9d\xff\x64\x45\xfb\x29\x44\xe9\x69\xd0\x67\x9d\x8a\x86\xbe\xd4\x2f\x51", 87, { 0x1b, 0xd6, 0xd5, 0xe4, 0x5a, 0xec, 0x0f, 0xb0, 0x32, 0x9f, 0x48, 0xd3, 0x30, 0xa0, 0x5c, 0xc7 } },
|
||||
{ "\x6e\xe6\xc6\xcd\x46\xfb\x60\x6c\xdd\x23\x5d\xde\x48\x84\xb7\x8c\x76\xab\xe7\x3d\x28\x03\x77\xdb\x8f\x63\x26\x50\x83\xc1\xb1\x8b\x5e\x04\x44\x9f\x73\xf8\x7d\x0a\x2e\x5b\x19\x12\xca\x14\x3d\x4b\xa9\x83\x63\x36\x53\xf3\xdf\x04\x0d\x2c\x0d\x78\x15\x26\x19\xea\x79\xd7\x6b\x67\x91\x2d\xad\xf6\x1f\x18\x7a\xf6\x01\xbe\xa4\xa3\x90\xd2\x22\xb7\x99\xff\x95\x2c", 88, { 0x10, 0x9b, 0xe4, 0xa6, 0xe5, 0x6b, 0x8b, 0xa9, 0x93, 0x3d, 0x1f, 0x2b, 0x86, 0xee, 0x43, 0x6f } },
|
||||
{ "\xf6\x7e\x75\x20\xc8\xc7\xdc\xd2\x52\x63\xef\xc9\x75\xe0\xe5\x14\xc4\xde\xb5\xac\x43\x47\x60\xf5\xc1\x9c\xd8\x63\xcf\x6a\x8c\x3a\x5c\xdb\x91\x6e\xee\x68\x6e\xa8\x7f\xac\x84\x6a\xf2\x54\x18\x49\x30\x33\xff\x59\xe4\x72\xe5\xa8\xcf\xe5\x39\xe0\xc8\x78\xb8\x10\x54\xc8\x95\x84\xde\xce\x42\xd0\x93\xb6\xde\xec\xdc\xce\x3b\x79\x79\x99\x8a\x22\x37\x04\xa6\x1d\x4d", 89, { 0xc5, 0x4b, 0x08, 0x71, 0x93, 0xf9, 0x29, 0x50, 0xdf, 0x2e, 0xf2, 0xdb, 0xd3, 0xc0, 0x45, 0x8e } },
|
||||
{ "\xb0\xfa\xd1\x59\x6e\x0f\x92\xf2\xc9\xb5\x87\xe9\xbc\xcd\xad\x21\x84\xb2\xf4\x08\x90\x42\x87\xb1\x96\x8c\x29\x90\xbf\x18\xbb\xd1\x02\xcd\xda\x55\x8f\x83\xa5\x4a\x61\x26\x9c\x65\xf6\x83\xa4\xbf\x1b\xb2\x27\x49\xe0\x20\x58\xee\xac\x38\x94\x44\x69\xae\xe4\xed\xdf\x68\x9f\x90\x1f\x09\x2c\x6f\x15\x1a\xe5\xa6\x41\xd7\x18\xff\x7f\x94\x27\x74\x02\xca\xcf\x42\x5f\xc2", 90, { 0x87, 0x4d, 0x37, 0x7f, 0xf8, 0xc5, 0xf8, 0xbc, 0xa4, 0x91, 0x41, 0xf0, 0xcb, 0xc4, 0x24, 0xfc } },
|
||||
{ "\x85\xa6\xc5\xdd\xfc\x37\x4b\x7e\xc4\xdf\x62\x94\x0c\x77\x6a\xc7\x88\xfe\x60\x3e\x6d\x76\xb4\x0b\x99\x5c\x38\x34\xd1\xc2\x35\x5f\x22\x0a\x98\x19\x68\x41\x4a\xc3\xed\x15\x9d\x19\x29\x75\xe1\x60\xa8\xc4\x17\x2c\x09\xb9\xbd\xcb\x22\xd5\xc8\x51\x41\x82\xb0\x41\x8d\xc5\xa5\xd5\x8c\xa0\xdf\xeb\xbe\x07\x13\x8c\x66\x7c\x01\x19\x68\x49\x2a\x14\x4d\x5a\xa0\x88\x64\xb4\xf5", 91, { 0x9a, 0x75, 0xb0, 0x83, 0xa7, 0xef, 0xdc, 0xd1, 0xec, 0x55, 0x02, 0xe0, 0xc3, 0x21, 0x11, 0xcb } },
|
||||
{ "\x17\x04\x96\x55\x9e\xec\x2a\xb0\x86\xcb\xe8\x0f\xaa\xdb\x88\x08\xe0\xa7\xa1\x4d\x26\xee\xe3\x5e\x6b\xa0\xee\x5f\xf7\x05\xcc\x04\x77\xfd\x12\xa8\xa9\x62\x8e\x7d\xa0\x89\xad\xde\xb4\xe8\x6c\xc1\x0a\xd1\xf9\x48\xbc\x5c\xe6\x76\xa4\x64\x08\xfe\xca\xa7\xf2\x37\x68\x11\x09\x2d\x96\x12\x44\xd1\x96\x2b\x83\x50\xbe\x89\x88\x80\xfe\xc8\x96\x77\x0d\xd8\xa4\x36\x35\xfd\x3e\x83", 92, { 0x76, 0x5a, 0x38, 0x22, 0x4b, 0x74, 0x03, 0xca, 0xef, 0x81, 0xf9, 0x95, 0x2f, 0x9a, 0x61, 0x09 } },
|
||||
{ "\xb7\xf0\xf9\xd4\xdc\x23\x91\x67\x99\x22\xa1\x6f\xdd\x15\xfd\x68\x7b\x62\xaf\x8c\xaf\x6f\x8d\x5e\x4f\x85\x74\x63\x8f\xd0\x23\xf0\x71\x83\xb6\x1f\xc7\x18\xbc\xdb\xe6\xb5\xf8\x1b\xe9\xaa\xb1\x2c\x9f\x17\xb6\x26\x12\xab\xf2\x80\xb5\x87\xa7\xc0\x29\x40\x4b\x4a\xac\x03\xfc\x5a\x1e\xd3\xa0\x0d\xb1\xef\x9d\x99\x2d\x4f\x32\x9e\xde\x4c\x70\x94\x1b\x5f\xd9\x63\x73\x01\x93\x11\x75", 93, { 0xd5, 0x80, 0x2e, 0xe7, 0x75, 0x2b, 0x14, 0x45, 0xe7, 0x79, 0xbb, 0x8a, 0x9e, 0x25, 0xbe, 0x59 } },
|
||||
{ "\xb2\x49\x95\x1c\x16\x9f\xcb\xd5\x39\x4f\x81\x2f\xf3\xe5\xae\x1e\x67\x13\xc2\xec\xa5\xb2\x19\xbd\x70\x56\x89\xbd\x19\x8c\x1a\xe8\x8a\xb2\xd5\x75\x5f\x73\xb5\xe0\x2e\xdf\xba\x93\xe7\x23\x1d\x30\x57\xe9\x9e\x7e\xc7\x4f\xf9\xed\xc1\x7c\x77\xc7\xf2\xe5\xa0\xf5\x2b\x1b\x0e\x6c\x81\x4e\x5c\x32\x95\x62\x3e\x11\xee\xac\xab\xd6\x82\x49\x34\x46\x54\x1b\x78\x9f\x37\x61\xb0\xc6\xb0\xf2", 94, { 0xe7, 0x95, 0xef, 0x83, 0xc5, 0xa8, 0xfd, 0x49, 0x2c, 0xea, 0xcc, 0xb6, 0x5a, 0xd5, 0xfa, 0xf8 } },
|
||||
{ "\x66\x12\xf9\x16\x43\xb3\x22\x01\x05\xc0\x53\xed\x8f\xdd\x2c\xd2\x1a\x85\x4d\xc5\x8a\xfa\xf1\xeb\xdb\xc6\xb5\x18\xba\xec\x77\x08\x30\xb0\x59\x38\x79\x00\xe5\x62\xf3\x7e\x4b\x94\x32\x2b\xc5\xec\x30\xb1\x1b\xf2\xa2\x4d\x42\x92\x65\x57\x20\xb4\x17\x6f\x6b\x7a\xc3\x46\xaf\x15\xb4\x06\x6e\x44\x6a\x5f\x61\x6b\xaa\x2f\xdd\x4c\xb0\xcd\x51\x64\x80\xf3\xec\xe4\x5b\x45\x5b\x4a\x4c\x82\xb0", 95, { 0x78, 0xba, 0x8a, 0x34, 0xdc, 0x24, 0xb8, 0xf7, 0x78, 0xb9, 0x19, 0xfa, 0x5e, 0x19, 0xcd, 0x1d } },
|
||||
{ "\x9c\xe1\x46\x5e\x41\xf7\x79\x61\x7c\xaf\x58\x7a\x85\x7d\x1e\x98\x46\x5f\x4e\x53\xaf\x2a\xa0\x91\xb6\xff\x86\x4b\xef\xdd\x59\x6a\xc3\x50\x25\xcb\x50\x48\x0d\x62\xdd\x04\x5d\x7a\xf8\x2d\x2a\x1a\x2e\xff\xa8\x83\x67\xa2\x08\xd7\xdb\x97\x0b\xd4\xb5\x4e\x28\xbd\x42\xd4\x56\x59\xd6\xa9\x77\x15\x3c\xb0\x61\x44\xd7\x3f\x89\x87\x59\x56\x4e\x48\x1f\xed\xe0\x60\x28\x66\xcb\xd9\xb1\x22\x24\xcd", 96, { 0x4c, 0x22, 0xab, 0x04, 0x6c, 0xee, 0xab, 0xc7, 0x2b, 0x36, 0x9d, 0x34, 0x1e, 0x33, 0x3e, 0x9d } },
|
||||
{ "\x6e\x2f\x4e\x6d\x66\x1f\x69\x1e\x6c\xf4\x59\xbd\x35\x37\x6e\x03\x1b\x28\xb5\x04\x6d\x0f\xda\xd1\x70\xb1\xb8\x3e\xf7\xde\x7f\xbe\x9a\x27\x81\x6a\x96\xae\x99\x20\x41\x16\x38\xc8\x28\x98\x0d\xb2\xc7\x37\x51\x1b\xe4\x0c\xac\xcf\x88\xbb\xc7\xe8\x9b\x06\x6f\xb4\x1b\x80\x62\xb5\xf8\x59\xba\xc2\x90\x58\xf3\x4a\xc2\xe8\x9b\xb8\xb1\x49\x95\xf3\x17\xe7\x09\xfd\x43\xc8\xec\xbb\xb0\x1e\x27\xd3\x44", 97, { 0xf5, 0xdd, 0x03, 0x8a, 0xea, 0x22, 0xdd, 0xfb, 0x84, 0x4d, 0xe1, 0x47, 0x01, 0x83, 0x5f, 0xfa } },
|
||||
{ "\xfc\x66\xb1\x22\x26\x80\xa5\x2c\x01\x7e\x26\x18\xa9\x4a\x3a\x2d\x21\xf6\xed\x9b\xa5\xa5\xfe\x75\x1c\x1a\x9a\x4c\xa9\xdb\x40\x69\x61\x01\xc3\xa6\x17\x9f\x6e\xe9\x52\xcd\x41\x3e\x60\x50\x5a\x91\x84\xe7\x6f\x05\x4a\x34\x78\xf3\xfc\x46\x69\x82\x2d\xbf\x1d\xdf\x72\xa7\x4e\x19\x30\xcc\xc1\x9c\x91\xd3\x7f\x48\x91\xe0\x3d\x2e\x34\xdd\xdd\xe7\xda\x6b\x0d\x90\xaa\x63\x0e\x65\x2c\x07\x8f\xf9\xf3\xcb", 98, { 0x3d, 0x89, 0x3a, 0x16, 0x78, 0x2f, 0xa7, 0x44, 0x52, 0x47, 0x8e, 0x03, 0xaf, 0x55, 0xc5, 0x4e } },
|
||||
{ "\xb7\x0f\x77\xb9\x42\x19\x01\x85\xc3\x4a\xbf\x2d\x07\x5a\xf7\x4c\x9a\xd6\x59\xfd\x63\x21\x6d\x66\x6a\x0b\x2b\xe8\xba\x0b\xa9\xe1\x62\x1c\xef\x1c\x95\x32\xe6\xd6\xf1\x58\x6f\x6e\xdd\x68\x91\xa8\x0b\x66\xca\x9d\x1d\x79\x86\x43\x64\x86\xad\x95\xc3\x6a\x57\x5f\xb2\xd4\x9b\xa8\x5e\xbe\x85\xbb\xee\x86\x25\xd4\xe1\xad\xc4\x64\x93\x2b\x32\x01\xde\x6c\x3b\xed\xdd\xeb\x38\x41\xcc\x6a\xc1\xb7\x0b\xcb\x80", 99, { 0x19, 0x77, 0x92, 0x3c, 0x8c, 0xe5, 0xc6, 0xcc, 0x04, 0xed, 0xe0, 0x02, 0x69, 0xa4, 0xb0, 0x14 } },
|
||||
{ "\x11\x42\x8e\x21\x28\x9e\xe8\x65\x94\x38\x7c\x56\xf5\x97\xb8\x95\xdc\x4c\xcf\xcf\x5a\xbc\x4e\x4e\x22\xfa\x5d\xab\x5d\xd2\x95\xa2\x0b\xe3\x78\xfe\x10\xe4\x91\xb3\xe3\x07\x29\x0a\xce\x7a\xa3\xf7\xe2\x0a\x75\x86\x7b\xe2\xc3\x74\x6c\x72\x9a\xda\xc6\x6b\xc5\x04\x4a\xe6\x50\x60\x69\xa4\x97\x92\xf3\x70\x09\xa4\x64\xa1\x7f\x5b\xc8\xbc\x33\xa5\x47\x36\x5e\x2e\x51\x56\x72\x11\x66\x39\xf1\xab\x82\xef\xe8\x8c", 100, { 0x55, 0x0f, 0x1a, 0x5e, 0x93, 0x15, 0x75, 0xf2, 0xb7, 0x6b, 0x67, 0x79, 0x45, 0x36, 0x12, 0xe1 } },
|
||||
{ "\x24\xc3\x0c\x87\xfa\x99\x6f\xe9\x2b\x6f\xdf\xc6\x40\x06\xdc\x6f\xb0\x9a\x33\xff\x06\xcc\x3b\x15\xb1\xa1\xab\x9c\x68\xa3\x17\xc5\x38\x25\x05\x16\x2b\xa4\xb0\x9c\x97\x49\x58\x3c\x00\x8c\x44\x28\xab\xf2\x56\x6d\xc0\xf6\x49\xa8\x1a\x06\x89\xd8\xaf\xa4\xae\x4f\x97\xad\x97\xc3\xba\xb7\x1f\x81\x1b\x93\x7f\xc1\xbb\xf1\x40\x14\x2b\x23\xda\xfa\xb2\xfa\xee\x90\x16\xcd\x1d\x66\x0b\x98\x83\x6f\x35\x40\xd4\x11\xdc", 101, { 0x7e, 0x9b, 0xb1, 0xbf, 0xc2, 0xf0, 0xd6, 0xa9, 0xd1, 0xa3, 0x5d, 0x1f, 0x74, 0xae, 0xd6, 0xc5 } },
|
||||
{ "\xf4\x11\x5d\x2b\xb0\xe6\x59\x25\xdb\xa3\x78\x25\x10\xd5\x2b\x10\xfa\x81\x90\x19\x59\xfc\x49\x30\x21\x6a\x68\x08\xc1\xd1\x86\xc3\x81\xd9\xf3\x3d\x04\x22\x07\xf2\xed\x42\x97\x8d\x9e\x59\x83\x0e\x1c\x53\x6d\x96\x0f\xba\x84\xd2\xe5\x36\x7e\x02\x15\xa2\xa4\xa5\x81\xcb\x07\xc3\xf4\xc7\xd0\xd6\xcb\xf0\xb5\x56\xb1\x7c\x88\xe0\x83\xba\xe9\x02\x52\xeb\x1c\xa5\x86\xbb\xf5\x18\x1f\x5a\xf0\xb5\x17\x3c\x5d\x32\xe4\x69", 102, { 0x0a, 0x37, 0xdb, 0x00, 0x9a, 0x07, 0x39, 0xfd, 0xd4, 0x36, 0x02, 0x15, 0x7e, 0xce, 0x60, 0x3c } },
|
||||
{ "\xb8\x86\x19\x81\x17\x75\x2c\x50\xbc\xba\x52\x0a\xca\xd0\x87\x23\x15\x5e\xaa\xcd\x12\x3d\xc4\x0f\xed\x27\x69\x7f\xba\xfd\x37\x9c\xc3\xb4\x7b\xca\xff\xde\xf4\xea\xa4\xd1\xaf\x95\xd4\x76\x11\xf6\x72\xb0\xf3\x41\x18\x66\xe7\xd4\x21\x2f\x9a\xe8\xe1\x99\x52\xf4\xf4\x16\x96\x9e\xb4\x84\xec\x5e\xc4\x57\xbd\xb2\xc9\x66\x55\xf8\x39\x4e\x07\xeb\x4b\x87\x6d\xbc\x0e\x01\xcd\xcc\x96\x7a\x98\x04\x50\x5f\x0c\xd2\x77\x5c\xf9", 103, { 0x5f, 0x1c, 0x52, 0x55, 0xd4, 0xde, 0x34, 0x35, 0x0d, 0xbb, 0xf3, 0x57, 0xa6, 0x15, 0x3f, 0x6f } },
|
||||
{ "\xc0\x9f\x82\xa0\xb2\x6f\x14\xb6\xbc\x6c\xee\x89\x9e\xf0\x93\x3a\xdd\x39\xd1\x28\x7f\x9d\x13\x6d\x62\xdb\x43\x82\x39\x8e\x5a\xfe\x24\xbb\x85\x7b\xeb\x89\xf5\x99\xd8\x10\x44\x1c\x2e\x49\x7f\x31\x49\x26\xd4\xce\x53\xbb\xd9\x37\xa0\x99\x76\x9c\xa7\x3c\x71\xdf\x9e\x9a\x94\x74\xb1\xdb\x7d\x62\xde\x28\x02\x66\x70\x9d\x3e\x36\x15\x58\x3d\xe3\x9e\xb3\x40\x57\x54\x8e\xad\xfe\xf1\xc5\x96\x82\x42\xc1\xe4\xae\x57\x2a\x20\x74", 104, { 0x3c, 0xd5, 0x22, 0xa8, 0x37, 0xc4, 0xe8, 0xad, 0x2a, 0xf4, 0xf6, 0x6d, 0x03, 0x38, 0x4e, 0xa9 } },
|
||||
{ "\x63\xba\xdd\x0a\x37\x2d\xc6\x2e\x56\x54\x40\x8b\xb4\x49\xbb\x34\x10\xbd\x9a\x4d\xeb\x6d\xbc\xc8\x23\xb4\xa7\x4d\x31\x39\x51\x33\xfc\xc8\x8a\xab\x57\x3f\x09\xfd\x1e\x9f\x11\xea\xe8\x42\xbf\x2f\x69\x2b\xf3\x2b\x67\x79\xd9\x98\x57\xf6\x13\x75\x94\xcc\x85\x04\x3b\x57\xbc\xef\xa5\x16\xfb\x86\x82\xba\xe4\x23\x8e\x61\xc0\xaf\xf3\xdc\x6b\x3d\x3b\x2c\xdf\xd4\xf0\x0c\x5b\x4a\xd3\xa8\x2f\x4b\xb5\x6b\x27\x79\xf5\xf6\x91\xae\x96", 105, { 0x34, 0x7e, 0x78, 0x3a, 0xaa, 0xd6, 0xde, 0xb7, 0xf4, 0x1f, 0xf8, 0x13, 0x4d, 0xe7, 0xba, 0x0f } },
|
||||
{ "\x2c\xed\x5c\xfb\x6a\x31\x16\x42\xd4\xb6\x27\x3b\xcb\xc2\x60\x04\x7a\xb3\xf0\x42\x90\xc4\x6b\xfe\x08\x7f\xed\x19\x23\xbf\x58\x6d\x78\x61\xb8\x82\x21\x87\xc8\xea\x17\x88\x8e\x3a\x98\x77\x21\xa5\xc4\x4f\x8b\x36\x48\xb8\xc9\xaa\x31\x78\xef\xe7\xe2\x79\x68\x1d\x21\x72\x5b\x78\x4b\x35\x2a\x7f\xa8\x95\x14\x0c\xd9\xf2\xfa\xe8\x6e\x63\x3f\x02\x94\x7e\xc8\x4c\xeb\xc7\x23\x33\x76\xb2\xc4\xb9\xac\x56\x6a\x30\xab\xb1\xa0\x95\x8c\x92", 106, { 0x56, 0x75, 0xe1, 0xc5, 0x9d, 0xa4, 0xf9, 0xec, 0x3b, 0xf3, 0x7d, 0x8f, 0xb3, 0x9a, 0xef, 0xb5 } },
|
||||
{ "\x5f\x86\xd1\x27\xd0\xe1\xfb\x23\x30\xfb\x39\x8b\xcd\x7a\x3a\x1e\x2d\xd0\x23\x5f\x4d\x54\x9d\x40\x07\xfe\x05\x6d\x8d\xbf\xc7\x32\x11\x7b\xc5\x09\x87\xa4\xf0\xc4\x82\x74\xfa\x53\x3b\xc7\x22\x33\xb1\x92\x2e\x74\xea\x04\x77\x64\x57\x37\x1e\xdd\x55\x93\x5c\x28\xd0\xc0\xf8\x8d\x02\x45\xd1\x79\x59\xc2\x9b\x49\x77\xc6\xa7\xb9\x53\x4e\xda\xe4\x7c\xdb\xbf\xf7\x7e\x2e\xb9\x76\x5d\xa3\x51\x2a\x3e\x28\xae\xa6\x26\xd8\x22\x75\xd9\x38\xe0", 107, { 0x4e, 0xe1, 0xda, 0x97, 0xf7, 0x4d, 0xce, 0x3c, 0xae, 0xd0, 0x5a, 0x17, 0xa8, 0x9d, 0xea, 0x3f } },
|
||||
{ "\xe3\xe4\x0c\xcc\x64\xb7\xd7\x6b\xa4\xea\xee\xfa\x2b\xa0\x38\x9a\xac\x09\x84\xa8\xeb\x01\x87\x2b\x4a\xd6\x71\x67\xee\x27\x2a\x8e\x92\xe7\x2e\x96\xe8\x81\x02\x26\xa7\x16\x51\xa9\x36\xe1\xa8\x85\xf3\xbc\xcb\x66\x20\xbb\xb2\xb4\x6a\xf6\x23\x23\x18\x65\xed\x68\xcd\xe3\xbe\x09\xf9\x55\xa2\x4d\xe2\xe4\x18\x53\x4b\x66\xd3\x3f\xbe\xda\x0a\x8f\x7b\x12\x7c\x8b\xfd\x6b\x04\xdb\x25\xb8\xd4\x33\x06\x3d\x51\x29\x4c\xd7\x8b\x26\x49\x39\x57\x7b", 108, { 0x56, 0x6e, 0x56, 0xba, 0xee, 0x28, 0x17, 0xeb, 0x10, 0xc1, 0x9b, 0xf4, 0x7b, 0xbe, 0xf1, 0x99 } },
|
||||
{ "\x9d\x51\x0b\x8b\x82\xc9\xd6\x26\xb2\xa9\xb9\xf7\xf5\x19\x26\x13\x4a\x44\x33\xb1\xb1\x59\x7b\xf9\x93\xab\x92\xf5\xcf\xf8\x22\xa4\x63\xc7\xa7\x2d\xb2\xea\xc3\x31\x77\x23\x3e\x39\x47\xe3\x9e\x4e\xbc\x2e\x5f\xa8\x44\x9a\xd0\x7e\x84\x75\x8a\xfc\x6a\x06\x8d\x53\xce\xec\xf8\xea\xc4\xa4\x65\xb2\x80\x26\xdf\x97\xe6\xae\x81\x12\xae\x98\xac\xdb\x31\x64\xe4\xbc\xd2\xda\x47\x81\x0b\x47\xac\x0c\x13\xe5\x54\x85\x29\x58\x4f\xae\x80\x55\x6f\x54\xc7", 109, { 0xca, 0x20, 0x60, 0x9f, 0x8f, 0x6d, 0x8f, 0x91, 0x97, 0x72, 0x2c, 0xe3, 0xfd, 0x2a, 0x05, 0xa5 } },
|
||||
{ "\x5d\xe1\xe1\x54\xa7\x6d\x0f\xec\x1c\x4a\xb7\x31\x7c\x9e\xc7\xa9\x9e\x92\x52\x67\xd4\x0f\xc2\x58\x6d\x17\x28\x2c\x54\xc2\xb4\xde\xd5\xd3\x40\xe2\x80\xf6\x06\xeb\x26\x98\x73\x56\x00\x63\x13\x36\xf0\x55\xab\xfc\xdf\x7c\x65\xc3\x45\x50\x26\x36\xc6\xac\xfc\x1f\xfa\x6b\xb3\x8c\x45\x9b\x86\xa0\xe5\x61\xf3\xf3\x0b\x69\xa7\xa7\x20\x07\x99\x08\x28\xef\x33\xdf\x44\x8d\xaa\x54\x51\x02\x6f\x7d\xae\xbc\xbd\x87\x1c\xb1\x53\x7f\xbe\x38\x3c\xbe\x3f\x84", 110, { 0x51, 0x82, 0x43, 0x6a, 0x40, 0xa6, 0x76, 0xb1, 0x58, 0xa4, 0x3d, 0xb1, 0xd3, 0xcd, 0xde, 0x96 } },
|
||||
{ "\xc9\xef\x12\xbd\xa1\xbe\xd5\xbd\xef\x1f\xcf\x64\xb9\x38\x98\x98\x51\xec\xd8\xdc\xe4\x05\x27\x8c\x2f\xfd\x14\xb2\x52\x69\x41\x89\xbd\x03\xac\x8c\x47\x52\x08\x39\x5d\xf8\x49\x67\x57\x98\x3f\x41\xe6\x62\x5a\xde\xaa\x3c\x8c\x7e\xe0\x8e\x4c\x64\x39\xaa\xb6\x4b\xc5\xd7\xcf\x86\x0e\xf9\xe7\xb7\x42\xde\x17\x2b\x87\x27\xea\xd1\x73\xd1\x18\xd5\x94\x5f\x6d\xde\x29\xa6\xc9\xe0\xf4\x34\x40\x9e\x27\x5e\x61\xc0\x7b\xe5\x94\x8c\x60\x44\x9d\x44\x4f\x99\x3d", 111, { 0xbc, 0x5f, 0x18, 0x15, 0x64, 0x22, 0x74, 0x18, 0xa4, 0xa0, 0x96, 0xdb, 0x00, 0x70, 0x9d, 0xb4 } },
|
||||
{ "\x1c\x3b\x2d\xf7\xd7\x25\xa2\xf0\xfd\xcf\xb8\xf0\xbb\x88\xbc\x85\x57\x26\x8d\x46\x4e\x12\x4c\x35\x0b\x7d\xa0\x3e\x46\xb1\xa2\xdc\xf8\x82\x6c\xdb\xf6\xe3\x39\x38\x31\x95\x39\x24\x89\xf9\xf4\x27\x49\x07\x58\x62\x43\x57\x61\xed\x89\x5d\x63\x5e\xc5\xb2\xf7\x6b\x36\x8d\x80\xa7\x48\x50\x59\x68\xce\x3e\x9d\xca\xde\x4b\x92\xcc\x49\x0c\xb2\x97\xb5\xce\x58\xdf\x59\xc2\x04\x62\x55\x56\x4b\x8e\xac\x9e\x5e\x40\xdf\xf1\x34\xa6\x27\x91\x57\x45\x4e\x82\x48\x16", 112, { 0x3e, 0x3d, 0x87, 0x58, 0x0e, 0x01, 0x69, 0x78, 0x5c, 0x50, 0xd4, 0xb4, 0xf2, 0x87, 0x15, 0xf9 } },
|
||||
{ "\x2a\x7b\x90\xcc\xb7\xfa\x65\x31\xd0\x72\xf5\xae\x8a\xa0\x51\xe9\x2d\xfc\xf9\x89\xd0\x4a\x00\x15\x90\x4f\xdc\xfa\x6c\xa1\xcc\xab\xc0\x98\xe6\xe3\x5c\x61\xbc\x06\x41\x30\xaa\xa5\xf7\x95\xbf\x20\x8e\xe8\x46\x66\x2f\xdf\xf0\xd9\x5d\x3e\x9f\x4c\xce\xad\xd1\x2e\xe0\xa5\xa7\xc0\xba\x84\x91\x82\x00\xc1\x99\xac\x32\x39\x48\xd8\xa2\xa8\x38\xbd\x10\x33\x38\x15\xe3\x21\x15\xa0\x06\xaa\x0b\x42\x5d\xe8\xc8\x48\xe3\xea\x19\xc8\x62\xe8\x34\x26\xcd\x90\xa1\xb3\x3d", 113, { 0x19, 0x09, 0x55, 0xc0, 0xf8, 0xda, 0x05, 0x7f, 0xa9, 0x81, 0xbc, 0xa1, 0xcc, 0x3f, 0xe1, 0x11 } },
|
||||
{ "\x7f\xc5\x6f\x87\xcb\x0c\xef\x76\xbd\xb2\x5a\xaa\x9c\x2f\x8d\x0c\xa4\x3d\x5f\xec\x16\x87\xfe\xba\x69\xef\x78\x5e\x9e\x7c\x56\x34\xb1\xdf\x63\xa7\x2b\xa0\x8a\x69\xd4\xea\xdd\x4c\x86\xef\xb2\xc0\x1d\xf9\xe8\xea\x8b\x0f\x47\x5d\x08\x40\x05\x77\x66\x8f\x65\x5a\x82\x7a\x7a\x86\xd7\x29\x0a\x10\x2c\x30\x8d\x81\x6e\x01\x55\x4e\x98\xf1\xc7\xef\xce\xe5\xc7\x9e\x8a\x99\x32\xad\xed\x8c\x85\x84\x37\x8c\x9b\x36\x52\xd9\x93\xc0\x89\xf9\xd0\xdd\x56\x18\x19\x89\x58\x19", 114, { 0x4e, 0x98, 0x6a, 0xa5, 0x5f, 0x57, 0xb4, 0x40, 0xd2, 0xf5, 0xf2, 0x3b, 0x19, 0xa7, 0x14, 0xa0 } },
|
||||
{ "\xe1\x10\x63\x3d\xa2\xd1\xb2\x6e\x62\x94\x37\x29\x58\x85\x13\x06\xa7\xcd\x21\xe6\x49\xcc\xad\xb8\x07\xf4\x43\xe7\xa4\x45\xa1\x64\x1a\x61\xce\x4b\xfc\x4b\x44\x35\xfa\xc0\x48\x19\x83\x32\x5b\xdf\x85\x5d\xc8\x83\x50\x88\x5e\xe2\x98\x5a\x38\x25\x99\x57\xb8\xc7\x55\xf5\x92\x44\xf9\x5f\x04\x5f\x5e\xc5\x24\x10\xab\x5e\x51\x09\x17\xfb\xcb\xe4\xcc\x49\x5f\xeb\xe7\xa3\x3b\x83\x9c\x92\xe0\x35\x77\xe2\x34\x5a\xbd\x62\xb7\x63\xf1\x37\xce\xc3\x72\xdd\x3b\x79\x41\xbc\xae", 115, { 0x73, 0x08, 0xff, 0x52, 0x04, 0x9f, 0x74, 0x4f, 0x24, 0x7d, 0x90, 0x31, 0xe7, 0xa5, 0x0d, 0x41 } },
|
||||
{ "\x3d\xe1\x62\x74\x46\x57\x63\x4e\xb6\x51\xca\x5d\xa3\x63\x3b\x38\xc3\x6c\xa7\x20\xb3\x17\xaa\x4b\xe4\x7d\x84\x5c\x23\xe8\xb2\xf4\xc3\xb3\x28\x62\x68\x4d\x2e\x76\x73\x5c\xd4\x73\x05\xfe\x13\x22\xb2\x2a\x82\x03\xc4\x35\xb1\x9f\x29\x71\x26\xf9\xfa\xf0\xf2\x22\xa8\x66\xee\xec\xc5\x2c\x97\xb6\x6d\x61\x83\x67\x4f\x2b\x80\x76\x5b\x1b\x48\x25\x0a\xaf\xe2\xcd\x45\xf0\x97\x55\xf3\x3c\x8f\xbc\x22\x1e\x09\xd6\xd1\x59\x34\x14\x57\x04\xac\x7b\x74\xcf\x94\xb7\xf3\x63\x4c\x49", 116, { 0x57, 0xd9, 0xf8, 0x21, 0x2c, 0xc8, 0x6d, 0xe5, 0xdc, 0xbf, 0x77, 0x8f, 0x8b, 0x15, 0x62, 0xfd } },
|
||||
{ "\xf8\xe8\xcf\xdb\xec\xa0\xac\xb4\x01\xb0\x9f\x46\x64\xff\xcc\xe5\xff\x37\x97\x92\xe7\xe9\x22\xf6\x69\xcd\x64\x6a\xac\x27\xe3\x33\x03\x44\x0e\xcb\xd2\x23\x39\x5a\x19\x31\x35\x44\xa2\x2d\x8b\xdb\xc3\x2b\x55\x35\xd1\xb4\xba\x19\x21\x0a\x04\x13\xbc\x89\x60\xa7\x9e\x28\x31\xa2\xab\x1f\x10\x8c\x2f\xa3\x65\x39\x10\xcd\x9b\x7e\x93\x99\x03\x01\xc7\x09\x47\x2a\x92\x69\x88\x36\x56\xae\x17\x6a\x3f\xf8\xcd\x64\x2b\x37\x08\x8c\x37\xe9\x42\xaa\xe2\x01\x4f\x92\xe1\xe3\x33\xfa\x7f", 117, { 0x88, 0x12, 0x61, 0x94, 0x21, 0xa3, 0xcb, 0x31, 0xa8, 0x60, 0x2d, 0xff, 0x13, 0x02, 0x40, 0xa5 } },
|
||||
{ "\x8c\x9d\x6c\xad\xcf\x04\x56\xad\xba\x5d\x3f\x57\x17\x76\x14\x07\x0e\xf2\xa1\x24\xe8\xe1\x1b\x4d\xee\xfb\xd9\x21\x70\x7a\x23\xab\xe1\x91\x23\x69\x20\x8c\xf9\xf8\xd2\x85\xea\x5d\xea\xc0\xb8\xf2\x4a\xa4\x0c\xeb\x83\x57\x10\x84\xb9\xf4\x19\xc9\xa2\x6c\x82\x01\xad\xf6\x94\xb8\x3f\x34\xa1\x68\x18\xe4\x30\xc3\xd4\x3f\x52\xa0\x8e\xf2\x13\x7f\x9f\xb6\x0c\xba\x84\x8e\x15\x4b\xdd\x9c\x19\x34\x92\xa1\x02\x8f\x10\x10\xd2\x32\xb1\xcd\xd3\xfe\x3a\x87\xe7\xc5\x7e\xae\xf9\xd5\x1f\x13", 118, { 0x1f, 0x41, 0x60, 0x14, 0x09, 0xd9, 0xff, 0x1c, 0x0b, 0x49, 0x8c, 0xd7, 0xbe, 0xa9, 0x80, 0x08 } },
|
||||
{ "\x94\x25\x74\x1c\x92\x1b\x86\xa0\xec\xf8\x35\x65\xb1\xe1\x78\x33\x12\x8b\xc2\x94\x9a\x81\x7f\x2b\x7a\x15\xbd\xaf\x02\xe1\xe8\x82\x2c\xf9\xae\xf2\x53\xaf\x01\x0b\x01\x01\x3b\x16\xe5\xa3\x5b\xb3\xe3\xa5\x6d\x8e\x46\xc2\x08\xc1\x11\x44\xf1\xc6\x73\x96\xdd\x17\x58\x68\x54\x64\x1c\x79\xb1\x70\x5a\x04\x46\x89\xe3\xc9\x9c\xa2\xcb\xb6\xd8\x0e\x9d\x32\x39\xdb\xae\x07\xbd\xc9\x8f\xe9\xe3\xe6\x9c\xa7\x8c\xc7\xb1\xed\xfb\x65\xfc\xb3\xfb\x91\xee\x46\x20\x15\x4b\xf1\x25\x69\x62\x48\x74", 119, { 0x58, 0x70, 0xa6, 0x06, 0xac, 0xb1, 0xee, 0x1f, 0x53, 0xe8, 0x72, 0x20, 0x3c, 0x05, 0x3b, 0x77 } },
|
||||
{ "\x0f\x56\x10\xc5\x8c\x9a\xce\xde\x03\x7b\xeb\x78\x6f\xd7\x81\x42\x7c\xeb\xc4\xff\x03\x4a\x0f\xca\x20\xea\x8a\x7a\xf2\x59\x76\x20\xef\x0d\x15\xad\xe1\xd8\x39\xb1\x81\x7a\x67\x3e\xae\x50\xa6\xeb\x4a\x2b\xea\xf4\xb2\x3c\x18\x7f\xd8\x2b\xb6\xf9\xfe\x46\x31\x9f\x10\xd6\xc9\x19\x9f\x8e\x1d\x40\x76\x1d\x4e\x00\xdb\xe3\xd3\x59\x63\xbf\xd9\x7f\x72\x07\x55\x22\x4f\x91\xa7\xc8\xe0\xee\xec\x55\x06\xb7\xe0\xad\x97\xff\x6e\x70\xf4\xe8\xd7\xe4\x47\x51\x7a\xf1\x5c\xad\x45\x45\x18\xef\xb9\x98", 120, { 0x26, 0x76, 0x51, 0x74, 0x00, 0x2d, 0x40, 0xe3, 0x3e, 0x70, 0x71, 0xc5, 0xf9, 0x19, 0xf1, 0x8b } },
|
||||
{ "\x9a\xa1\x93\x09\xec\x14\x1c\xa7\x65\xb2\x0f\x0d\x9f\x6f\x22\x25\x11\x5e\x33\x0d\x48\x60\x10\x16\xc7\xf7\xe3\xe9\x77\x38\x38\xc4\xcc\xdf\xad\xe2\x77\x7c\x35\xf9\xc1\xcc\x08\xdd\x8b\x23\x2b\x42\xdf\x04\x97\x9e\x32\xd3\x09\x2d\x38\xa1\x65\x0e\x64\x27\xc8\x8b\xfb\xcf\x29\x76\xd4\xeb\xaa\xae\xae\x08\x81\xc1\x2e\x5d\x7d\xab\x73\x5e\x38\xbd\x58\x6e\xd8\x99\x45\xb1\x81\x5a\xb2\xff\x5b\xd0\x3a\xf4\x3b\xe8\x57\x24\xf0\x2b\xc0\x6c\x2d\x5d\x5c\x64\x0e\x45\xe1\xf0\x48\x8d\x0e\xf6\xf2\xbf\x81", 121, { 0x3a, 0xfd, 0x49, 0x99, 0x51, 0xab, 0x70, 0xe1, 0xaf, 0x2e, 0xa2, 0x10, 0x8f, 0x52, 0x9c, 0x6e } },
|
||||
{ "\x29\xea\x6f\x36\x04\xe5\x78\x9c\xd3\x17\x5e\x55\xeb\x7b\xd3\x8b\xfa\xbf\x55\xea\x79\xd0\xf4\x3d\x3e\xfd\x31\xa8\x2d\xca\x02\x7f\x0f\x54\xf3\xc2\x7b\x5c\x66\x37\xf0\xf1\xfb\x22\x05\xbe\x0b\xa2\xb7\xee\x4d\xab\xe2\xb7\x9b\x9b\xcb\x8a\xcf\x7b\xda\xd5\xc7\xd5\x65\x73\x89\x2d\xa6\xb2\x7f\x1d\xcf\xfe\xe3\x10\x34\x2e\x36\x9b\xa7\x6b\xe9\x73\xe2\xb9\x1f\x0f\x1c\x23\x8a\xdb\xbe\x87\x72\x15\x2f\xfb\xd4\x48\xcc\xdb\xa7\x63\xf3\x71\x3a\x76\x3e\x3f\xb9\x08\xce\xeb\xce\x17\xbd\xc8\x63\xad\xb5\xfd", 122, { 0x1a, 0xfc, 0xd7, 0x74, 0xe1, 0x55, 0x51, 0x67, 0x6b, 0xe7, 0x1b, 0xc8, 0xd4, 0xab, 0x39, 0x47 } },
|
||||
{ "\x86\x1b\x9f\x54\x66\xd5\x73\xa1\x7a\xe9\x2e\xcc\xc1\x1d\xe2\x7e\x24\xa5\xe7\x64\xf7\x7e\x2f\x23\x9e\x6a\xb7\xd8\x4c\x88\x1a\x4a\xe7\x8f\x40\xaf\x08\xa7\x33\x17\x1e\xe4\x12\x79\xb1\x60\x1e\x59\xc4\xf3\xf1\x12\x55\x91\xcf\xc5\xfe\x41\x15\xde\xbd\xb6\xce\x40\xd1\x8c\x65\x0d\xbb\x20\x74\x13\x64\x0c\xbb\xd6\x5d\x3e\x2c\x36\x40\xb3\x22\xbd\x36\xd5\xb2\x87\x93\x6f\x1a\xce\x9b\x49\x57\x12\x68\x65\xd2\xe1\xe3\xd4\x3a\x48\xef\x35\x6d\xd6\xa6\xcb\x8f\x49\xbb\x3a\x3d\xd8\xff\xde\xdc\x1c\xff\xc9\x0b", 123, { 0x31, 0x66, 0x6a, 0xcb, 0x7f, 0xb2, 0x21, 0x3b, 0x4c, 0xb3, 0xbc, 0x28, 0xe1, 0x8b, 0x32, 0x58 } },
|
||||
{ "\x9c\xca\x57\x37\xf3\xd0\x6e\x4c\xa0\xe5\x57\x89\x6a\x65\x34\x6c\x6e\x72\x1d\xcd\xc7\x59\xdb\x07\xd8\x13\x40\x50\x39\xe7\x21\x2a\x3b\x2d\xf2\xf2\x1a\x2d\xfc\x96\xbe\x25\x3d\x64\x2e\x69\xdc\xfd\x92\xa5\x47\x68\xe2\x3e\xeb\x43\x31\xd7\x8f\x14\x90\xf0\x4e\xbd\xa0\xa8\x2f\x0e\xb8\xa3\x62\x75\xae\x06\x1a\xd0\x46\x9f\x01\x63\x35\x22\x5d\xe5\xd0\x8e\xbd\xb5\x56\xaf\x5f\x2a\xd6\xbc\x22\x07\xbf\x20\x22\x0d\x02\x56\xf5\xab\xe6\xed\x81\xd1\x68\xab\x78\xe2\x4c\xce\x72\xc8\xc4\x6d\xa5\x21\xbc\xfe\x43\x97", 124, { 0x69, 0x78, 0xc0, 0x8c, 0x6b, 0x92, 0x3d, 0x79, 0x26, 0x06, 0x37, 0x64, 0x96, 0x5e, 0x9a, 0x6b } },
|
||||
{ "\xc0\xf1\x71\x4d\x8b\x79\xdf\x75\x2d\x6a\x08\xfe\xd7\x3d\x08\x6b\x46\x31\x15\xbf\xca\x8c\x9b\x94\xf2\x00\xf8\x4c\xd6\x28\xd1\x5e\x01\x31\x0f\xd2\xf9\x96\x7a\xc8\x6b\x03\xf0\x31\xf8\x5b\x41\xa1\x96\xd5\xaa\x3d\xa4\x41\xed\xcf\x8f\x69\x09\xf8\x1a\x92\x9b\x85\x4d\x22\xd1\xda\xfc\x5b\x07\x8a\xf2\x45\x00\x09\xbb\xaa\xc2\x79\x0b\x3b\x0e\xa0\xce\xd0\x7a\xfb\xcd\xcd\x2d\xeb\xfa\xa0\x37\x0e\x58\x66\x8a\xa9\x89\xad\x99\x41\xf5\x54\x8c\x49\x94\x8f\x1d\xf5\x59\x07\x12\x2d\x3c\x1e\x57\x9d\xe2\x50\xb7\xe9\xea", 125, { 0x5a, 0x5a, 0xd4, 0x98, 0xee, 0x0c, 0xa8, 0xdd, 0xef, 0x60, 0xed, 0xc3, 0xf6, 0xd3, 0x95, 0x0f } },
|
||||
{ "\xb5\x37\xfe\xd6\xa3\x0f\x84\x94\x70\x46\x6f\xa9\x55\xe9\xb5\xf9\x6e\xe7\x1a\x35\xdd\x8c\x26\xe1\x0f\x98\x38\x00\x16\xfc\xb5\x5f\x36\x30\x59\x7c\x7b\x33\xad\x11\x87\x20\x99\x40\x6a\x6a\x11\x5c\xaa\xb4\xeb\x51\x62\x50\xd1\xb2\x86\x51\x52\x5d\x44\x4e\x13\xcd\x86\xb6\x22\xfc\x94\xcb\x6b\xf3\xd7\x3d\x43\xef\xb8\x64\x22\x32\xa7\x18\x6e\x63\x38\x30\x72\xa2\x67\x96\x6d\x2c\xfc\x04\xc7\xa8\x0a\x5d\x5e\x0c\x91\xaa\xff\x2f\x43\xaf\xf1\xeb\x64\x29\xab\xee\xca\xa7\xa5\x1e\x04\x02\x4b\xa6\x97\x7b\x0e\xa2\x63\x6f", 126, { 0x17, 0xca, 0x2b, 0xf4, 0x91, 0x4e, 0x34, 0x11, 0xb0, 0x08, 0x52, 0xdc, 0x95, 0x8c, 0xfb, 0x2c } },
|
||||
{ "\x95\x63\x25\xb9\x12\x5f\x16\xa4\xaf\xb8\xb0\x8b\x26\x67\x90\x10\x70\x05\x76\xf5\x95\x36\x6a\x9a\xa2\xb2\xfa\x13\xb9\xf1\x9e\xe5\x42\x73\x3c\x5e\x3f\xa9\xc6\x8e\xbe\x83\x01\xe5\x67\x97\x61\x6b\x35\xea\x11\x96\x42\x5f\x0e\xcb\xba\xba\x73\x74\xf2\x4f\xcf\xba\x91\x4b\xb2\xdf\xec\x9e\x47\x3b\x70\x84\x1b\xd2\x38\xaf\xfc\x8e\xbf\x13\xfc\x1d\xaf\x4d\x95\x69\xd8\xb1\xe6\xb0\x3c\xee\x1c\x41\x47\x60\xec\xd2\x1c\xf2\x3c\x80\x0a\xae\xe1\x63\x1d\xe3\x83\xcd\xd1\xf2\x9d\x20\xe2\xb5\xa1\x49\x3e\x8b\x38\xdd\x1c\x04\xa7", 127, { 0x75, 0x90, 0x2f, 0x4a, 0xfb, 0x9d, 0x91, 0xb1, 0x0e, 0x74, 0xd7, 0x1c, 0xb6, 0xb0, 0x98, 0x06 } },
|
||||
{ "\xce\x26\x26\x4d\xca\xd2\x5a\x49\x30\xcf\xf6\x38\xaf\x9a\x68\x1c\x7d\x2f\xfb\x58\x31\xdd\x49\xd7\x3e\x32\x3e\x4d\x0d\x16\xc4\x96\xb6\xf4\x10\x3a\x5a\x13\x89\x12\x1f\x03\x50\x04\xc9\x32\x70\xe9\xf2\x9e\xa4\x90\xe6\xa5\xbf\xdc\x1d\xf8\xbc\x08\x55\xae\x62\x0b\x4c\x75\x93\x16\x17\xe3\x32\x3b\x22\xea\xaf\x27\xc5\x6a\x31\x10\x7f\xe1\x5f\xaa\xd1\x3d\xca\x52\xb9\xd2\xfa\x4e\xc9\x67\x13\x2c\xe4\x6b\x23\x46\x95\x45\x0b\x67\x0c\xc9\x08\x88\xb6\xc6\xde\xb3\x78\xbc\xa0\x09\x87\xab\x1e\xdf\xe7\x06\xeb\x02\x7d\xc7\x09\x1b", 128, { 0xdd, 0x13, 0xdd, 0xd7, 0xfd, 0x85, 0xb9, 0xfe, 0xcf, 0x5f, 0x63, 0xd8, 0x30, 0x7f, 0x81, 0x37 } },
|
||||
{ "\xd3\x9c\x34\x2e\x69\x3f\xc8\x3c\xb2\xe3\x4f\x09\xb2\xca\xab\xf8\x31\xf3\xdc\x12\x9c\xf1\x6f\x25\x79\xd7\x84\x09\x85\x50\x7a\xfe\x6d\xcb\x39\x31\x25\xd3\x1b\x5d\xe7\x7c\x78\x8e\xcb\xf9\xcc\x02\xff\x4b\x87\x28\xa4\x14\x72\xca\x46\x8a\xb9\x46\xf5\x87\x99\xf7\x04\xbc\xa6\xb4\x5e\x06\xb9\x6e\x80\xd9\x76\xfd\x16\xd8\x76\xf4\x36\x87\x15\xb0\x33\x18\xd9\x70\x1f\x61\x7d\x9e\xe1\xef\x9a\x2c\xee\x34\xf1\x1a\xa7\xdb\x57\x14\x4f\x3c\x3d\x37\xa8\xeb\xdb\xf4\x29\x6b\xf9\x0d\xdd\x00\x5a\xbd\xda\xa2\xc5\xf4\x5d\x0e\xb1\xc0\x7f", 129, { 0x85, 0x9f, 0x82, 0x66, 0xc3, 0xf3, 0xd5, 0xcf, 0xc6, 0x98, 0x4e, 0xcb, 0x74, 0xa6, 0x30, 0xe5 } },
|
||||
{ "\xf6\x8c\xc7\x96\x58\xa8\xf1\x2b\xec\xc3\x22\x93\xb6\x31\x25\x2c\xbc\xa8\xa4\x36\xd2\xa8\x53\x4b\x91\x85\x2d\x7c\x66\x12\xd7\x0a\xc6\xec\x20\xbe\x7f\x60\xaa\xe5\x2a\xfa\xa2\xec\xbd\xab\xaa\x93\x3d\x95\xd9\xd1\x90\x77\xd8\x45\x70\xb0\x2d\x54\x7c\xf1\x94\xe3\x68\x84\x89\xb2\x55\x33\xe3\x53\x3c\xd6\x9a\xc7\x83\x7d\xa9\xb4\xb2\x36\x0f\x44\x3f\x7b\xef\x9c\x85\x3b\xd7\xf7\xd3\x83\x1d\x5f\xa1\xc9\x65\x08\xde\xd5\x40\x49\x65\x4c\xef\x37\x8d\xdb\x45\xe0\xdf\xfc\xaa\x21\xe3\x68\x3b\x25\x13\x19\x0f\x7a\xf1\xfb\x95\xd1\x34\x2f", 130, { 0x09, 0x1a, 0xd5, 0xec, 0xd3, 0xed, 0x5a, 0x2d, 0xf5, 0x61, 0xe8, 0x95, 0x69, 0xe8, 0xda, 0x04 } },
|
||||
{ "\x19\x52\x1e\xfa\x65\x9a\xe9\x50\x84\x52\x5f\xf9\xa2\x6d\x89\x5e\x0f\xfd\x7f\xf3\x62\xb3\x5e\x40\xba\xf1\x58\x8d\x20\x8e\xe6\x29\x08\x25\x18\x57\xf7\x1a\x0c\xd6\x3e\x2b\x7d\x0c\xe4\xae\x73\xce\xa2\x6d\x18\xce\x07\x1a\xab\xa2\xbc\x70\x8d\x6d\xe2\xe9\x79\x2c\x97\x16\xd1\x9f\x98\x9e\x13\xd1\x00\xd5\x6a\x46\x2f\xf8\x61\xc1\xc6\x03\xb2\xaf\xce\x2f\x3d\x33\xf8\x0b\x14\xcf\xff\x36\xb3\xab\x2a\xb7\x4d\x86\xed\xf9\x41\x36\xaf\x66\xac\xdd\xa7\x9e\x18\xaa\xdf\x54\x51\x49\x5b\xc5\x58\xe9\x53\xd6\x71\xe7\x9b\xca\x57\x1c\x23\x9d\x90", 131, { 0x76, 0x56, 0x7f, 0xe3, 0x54, 0xbe, 0xa3, 0x1f, 0xff, 0x3a, 0xb0, 0xfb, 0x98, 0xfd, 0x35, 0x13 } },
|
||||
{ "\xc0\x9b\xff\xdb\xf9\x2f\xf0\xc5\x04\x70\xf4\x5a\xfe\x52\xf4\xf9\x50\x52\xb1\x41\xb5\xb0\xe5\x27\xea\xda\xf8\x2a\xf1\xe9\x5c\x9d\x01\x44\x85\x23\x0d\x62\x88\x3a\xef\xae\x4f\xed\x31\x83\x77\xad\x78\x56\xc6\x3b\x8e\xf3\x4c\xbc\x0a\xe0\x15\xee\x9e\xde\x87\x7a\xfd\x8d\x5f\x5f\x67\x2f\x42\x8e\xd2\x85\x03\x95\xb7\xd5\x70\x73\x76\x0d\xd9\x8a\x66\x02\x1e\xb2\x7d\xd1\x74\x69\x99\x66\xb4\x29\x69\x1b\x5f\xd2\xfa\x78\x32\x47\xe2\x19\x62\x15\x03\xad\x75\x4c\xfc\x1a\xbd\x72\x32\xbe\x71\x8d\x76\xd1\x69\x5f\x53\xe6\x76\xaf\xf7\x90\x5b\xc1", 132, { 0x0f, 0x4a, 0xeb, 0xeb, 0xe2, 0xf4, 0xfd, 0x1a, 0xa8, 0x5e, 0xe3, 0x62, 0x7d, 0xe0, 0xdf, 0x1e } },
|
||||
{ "\xbc\x21\x6c\xe7\x51\x8e\xc2\x30\x89\x6e\x19\x3f\xc0\x21\x46\x38\xe6\x0e\x57\xd3\x29\x04\x49\x92\x43\xc2\x60\x0f\x5d\x92\x27\x6f\x9e\x0f\x04\xf3\x55\x08\x77\xad\xbf\x7d\xef\x4f\x75\xc6\x49\x1e\x75\xd3\xe6\x06\xcb\x8e\x67\xc8\xdb\x5d\x08\x4f\x4e\xc3\x96\x20\x97\x26\x0e\xee\x21\xab\xd4\x4d\x17\x3d\x8c\x7f\xcf\xad\x99\x6b\xd4\xf4\x30\xab\x8e\x93\x18\xc4\x90\x1b\x00\x71\x7e\xc9\x7c\x18\x99\x49\x9e\x5e\xe9\x9b\x2d\xd6\x06\x13\x85\xd4\x82\x7a\x0a\x60\xf6\x53\x4a\x46\xa8\x38\xaf\x4b\xd6\x62\xdd\x7a\xa1\x46\xae\x9c\x99\x5d\xc7\xc5\xe1", 133, { 0xee, 0x0d, 0xd8, 0x9d, 0x25, 0x60, 0xda, 0x7a, 0x2c, 0x60, 0x14, 0xc7, 0x3f, 0x1d, 0x3b, 0x3d } },
|
||||
{ "\xfd\xd7\x0b\xff\x63\x6c\x52\x42\xd2\x71\x43\xd0\xd4\x48\x5b\x4b\x9f\x80\x1f\x20\x93\x33\x6e\x6c\xe0\xff\xee\x8a\x45\x9f\xa8\x3d\xf3\x25\xb0\x77\x90\xd6\xfd\xc4\x57\xa2\x57\x56\x5c\x3e\x6e\xad\xed\xe0\x06\xe3\x14\x96\x50\x91\x3a\x44\x55\x62\xe6\x38\x8b\x32\xa2\x6c\x8a\xe2\xfe\x57\xd8\xbb\xae\x70\xe0\x7c\xce\x40\x02\x01\x46\x22\xc4\x92\x49\x9a\x25\xc6\xf7\x50\x12\x12\x23\xa8\xf2\xf3\x2e\xfe\x5c\xb3\x12\x83\xe8\xda\x7b\xaf\x23\x35\x0f\x62\x9c\x7c\xcf\x9b\x1b\xa2\x95\xd3\xf1\xbe\xbd\xf7\x6b\x91\xe1\x01\x60\xb3\xbc\x32\xea\x5f\x30\xee", 134, { 0x8b, 0x7c, 0xff, 0x2f, 0x5f, 0xb8, 0xe4, 0xec, 0x5f, 0x22, 0xc5, 0x45, 0x5e, 0xb0, 0x62, 0x87 } },
|
||||
{ "\x31\xd7\x62\x33\x63\x75\x03\xb7\xc0\x50\xaa\x9e\xd1\x87\x5d\xd5\xb8\x2d\x2f\x0e\xa3\xd1\x03\x58\x5a\xa8\x6e\x5a\xf8\x5a\xbb\x2b\xb7\x66\x08\xd1\xe4\x32\x8d\x55\xf1\xb3\xfd\x7f\xa9\xb5\x04\x34\x7e\xc7\xf1\x68\xfe\xc7\x6e\xc1\x64\x05\x6a\xca\x4b\x17\x17\xd0\x7e\x39\x0f\x5d\xea\x5e\x92\x4e\xb5\xd7\xea\x93\x67\x9f\xef\x83\x46\x41\xa7\xda\xc1\x66\x05\x50\x02\xff\xd2\xd6\xa6\x0b\xa9\x70\x89\x05\x1c\xaa\xba\xee\xf5\xb8\x8e\xf2\x96\x2e\xd0\xba\x82\x58\x16\x4d\xf4\x37\x2f\xa3\xad\x19\xb8\xc8\xcc\xd3\xce\xa9\xd5\x9e\xdd\x7f\xd4\x8c\x97\xd5\x9a", 135, { 0x8a, 0xa7, 0x2b, 0xac, 0xd5, 0x8c, 0x7a, 0xae, 0xe0, 0x26, 0xa8, 0xd7, 0xc0, 0xa2, 0x20, 0xb4 } },
|
||||
{ "\xa5\x01\x37\x26\xa2\xa7\x79\x20\x45\xf0\xa1\x7e\x53\x8c\x72\x49\x2f\x09\x96\x7a\x15\x85\x67\xfe\xef\x7e\x5a\xd9\xd7\xc5\x08\x66\x2a\x91\xda\xbd\x45\xb0\x51\x2d\xdf\xd9\xf0\xe8\x03\x1c\xc6\xbe\xa8\x7a\x9c\x02\xef\x91\xb7\x89\xf8\x70\x4a\xd0\x60\x89\x7b\x3d\x5b\xc4\x10\x7e\x6b\xb0\xb6\x0e\xbb\xd4\xee\xd6\x1a\x24\x94\xf0\x97\x8f\x0d\x86\xb5\xb5\x0d\xd9\x4b\xb6\x03\x5e\xfb\x26\x21\x02\x4c\x1c\x0b\x8f\x67\x6a\x1b\x27\x6b\xe6\x4f\xec\x6d\xe7\xd0\xc2\x0f\xcc\x1f\x2c\xbb\xb6\xde\x53\x7d\x55\x39\x25\x7b\xe0\xef\x9a\x11\x1e\x01\x12\x8d\xa2\xf5\xdb", 136, { 0xcb, 0x2c, 0x7e, 0xc1, 0x58, 0xd4, 0xea, 0xf8, 0xb3, 0xc1, 0x82, 0x69, 0xcc, 0x3c, 0xaf, 0xa0 } },
|
||||
{ "\x84\x14\xc7\xce\xcf\xa9\x6d\x18\x26\xb4\x06\x16\x56\x56\x9e\x5a\x22\x51\xa0\xcb\xb4\xfb\xd9\xe9\xbe\x4e\x25\x2d\x32\x1c\xb8\x8e\x9a\x60\x0b\x20\x14\xaf\x60\xd7\xee\xcd\xf4\x6a\xda\x5b\xc1\x53\xce\xae\xed\xf2\x7b\xbc\xd2\xd1\x67\x30\xab\x03\xa9\x9d\xd7\xa5\x41\xce\xcd\x86\x11\x3b\x9d\xe3\x7c\x99\x1f\x4b\x9a\x89\xba\xa1\x15\x70\xd2\x40\xa3\x66\xcf\x39\x20\x47\xc7\xb7\x46\xe8\xc7\x84\x0c\x64\xc3\xa4\x99\x94\x17\x1f\xe4\x9c\xb9\xdd\xea\xa2\xfe\xa9\x8a\x9a\x05\x58\x00\x3d\xc4\x03\xfc\x18\xad\x6f\x5e\xc1\xfc\x8e\x91\x24\xa0\x1e\x81\xfb\xc3\x70\x3a", 137, { 0xa3, 0xac, 0x47, 0xc4, 0x7f, 0xf0, 0xfa, 0xcf, 0x5a, 0x75, 0x87, 0xd1, 0x31, 0x8d, 0x68, 0xe1 } },
|
||||
{ "\x5c\xf8\x43\x1f\x6c\x00\xcf\xc3\x31\x39\xdd\x67\x86\xa4\x13\x11\x27\x91\x4e\x45\xec\xe9\x28\x62\x13\x18\x99\x9c\xb6\x95\xb9\x92\x5b\x0f\xa3\x8c\xaa\x36\x76\x52\x39\x23\x75\xab\x83\x64\x4e\x71\xf8\xa8\x78\x4d\x2e\x03\xb5\x15\x35\xdf\xb7\xbf\x08\x80\xdf\x00\x1e\x32\x20\x85\x20\x11\x02\xcd\xb6\x75\xc3\xa1\x7b\xf8\x98\x31\x0f\x25\x11\xcd\x4a\xbe\x9a\x3c\x8d\xaa\x1d\xbd\x35\x79\xc5\x97\x29\x96\xde\x5f\x93\x08\xd8\xc6\xac\xe4\x6a\x1c\xaf\x53\xd4\x65\xef\x3c\x3c\x16\x04\x8d\x3a\x6d\x21\x2b\x6f\x6a\x81\x74\x50\x6d\x00\x6d\x01\x6d\xc6\x8d\x5c\xd2\x1e\x25", 138, { 0x4a, 0xa7, 0x74, 0xe4, 0x2d, 0x30, 0x28, 0x86, 0xda, 0x3f, 0x18, 0x0c, 0xef, 0x15, 0xa0, 0xb2 } },
|
||||
{ "\x10\xf0\x65\x6a\xe6\x21\x1d\x21\x1f\x7e\x21\xe5\xfa\x3a\xf3\x18\x52\x9b\x31\x64\x63\x95\x27\xed\xad\x04\x7d\x15\xf1\x85\x11\xeb\x58\xf2\xe0\x31\xb3\x79\x1d\x08\xdd\x59\x64\x3a\x3d\x38\x08\x24\x68\x23\x88\x3e\xe3\x22\x21\x48\x06\x77\x7d\x13\xfb\x73\x89\xea\xe6\xf6\x64\x9b\x1f\x81\x73\x25\x9a\xf9\x91\xff\x68\xfb\x64\x03\x56\xd6\xcb\xf6\xb3\x29\x73\xb4\x30\x1a\x89\xfc\xdf\x30\x89\xd6\x5e\xce\x35\x9d\x0d\x4d\xa2\xad\x7a\xb5\x6c\xa9\xde\x17\x0a\x69\xc1\x89\x3c\x7f\xb8\xbf\xa1\x65\x4f\x42\x65\x44\x01\x50\x17\x63\x64\x51\x98\x2a\x62\xf1\x2f\xd2\xa1\xde\xba", 139, { 0xa0, 0x86, 0x6f, 0x0d, 0x37, 0x2f, 0x7e, 0xf8, 0x9a, 0x82, 0x03, 0x51, 0x49, 0x80, 0x26, 0x4c } },
|
||||
{ "\xac\x04\x20\xff\x0a\x4b\x0f\x21\xce\xd6\xf6\x2e\x8d\x87\x43\xd5\x5f\xc4\x67\x35\x45\x9c\x50\xd0\x38\x01\x80\x9e\xca\x33\xca\x3e\x7b\x3e\xa9\x48\x9b\x99\x3d\xbd\xd6\xf0\xe3\xa0\x61\xfc\x6f\x9e\xc0\x8d\x09\xe8\x31\xa9\xa1\x21\xb8\xcf\x10\x73\xc8\x54\xcd\xbc\x8b\xef\x48\xe6\xce\x50\xe6\x55\x8c\xea\x9a\x79\x16\xd2\x1c\x83\xdc\xbf\xc9\x34\xda\x31\x17\xd0\xa1\xaf\xb3\x32\x00\x29\x39\xf9\x50\x7b\x8f\xe0\x59\x12\xdf\x2c\xe4\xa9\x2f\x3e\xde\x2d\x9e\x48\x26\xbf\x3d\x1c\xf4\xd7\x87\x20\xe5\x86\x7f\x5e\xa7\xd4\x65\xb8\x3d\x47\x14\x38\xef\x85\xfb\x86\xd2\x11\xb5\x73", 140, { 0x0f, 0x04, 0x8f, 0x85, 0xdf, 0x16, 0x04, 0x94, 0x33, 0x86, 0x13, 0xb6, 0x66, 0xea, 0xc7, 0x9c } },
|
||||
{ "\xef\x31\x48\xb1\x13\xf0\xf7\xa5\x33\x40\xc4\x55\x79\x37\x86\x7c\xef\x7a\xa2\xbd\xc7\xb7\x69\xf4\x44\x4c\x0e\xa7\x49\x05\x42\x9b\x7c\x02\x6e\x83\x17\xb7\x8c\xd4\x4b\x0e\xa3\xb4\x50\xa7\xdd\x10\x0e\x3f\x46\xcc\x61\x2e\x23\x16\x0d\x0a\xed\xd4\x3e\x6a\xe9\x3b\xba\xc5\x65\x81\xa5\x78\x91\xaa\xf0\xe6\xf7\x7f\x60\xb9\x98\x9e\x36\x47\xa5\xaa\x80\x11\xd6\xa2\xfc\x65\x6b\x4f\xa4\x23\xbd\xd7\xdb\x9c\x80\x70\x32\x96\x98\x2e\xd7\x6c\x94\xfc\x9a\x52\xcb\xa9\x9d\xb7\x12\x1a\x98\xc3\x17\x9e\xc7\xff\x5d\x5f\x70\x14\xd4\xf3\x14\xac\x14\x12\x32\x75\x36\x62\xb2\x44\x4f\x6f\xf5", 141, { 0x4c, 0xac, 0xbf, 0x73, 0xc7, 0x06, 0x64, 0x46, 0xda, 0x86, 0x95, 0xdf, 0xb9, 0xb8, 0xb5, 0xd6 } },
|
||||
{ "\x56\x8a\xb6\x76\xb1\xe1\xe0\x1d\xa9\x78\x0c\x20\x7e\x96\x45\x96\x23\x40\x13\x9a\x19\x74\x2d\x18\x7a\xff\x4c\x37\x12\xfb\x1a\x63\xa8\xe9\x49\xf6\x5a\x66\xc1\x82\x26\x8d\xf1\xbd\x85\xea\x47\x0a\x31\x16\xba\xa0\x08\xf4\x84\x59\x09\x86\xee\x19\x7b\x6d\x43\xd9\x2c\xfb\xe6\x4f\xd7\xf6\x80\x3c\x9f\xec\x51\x51\xb8\x2e\xa8\xbf\x25\x6a\x6e\x5a\x9b\xe9\xdc\x69\x85\x61\x4c\x0c\x21\x78\x2d\x4a\xc7\xd6\x11\xb7\x4a\xe5\xe1\xbe\x77\x28\x30\x91\xba\x35\xac\xaa\xe1\x50\xb1\xfc\xf8\xa6\xf7\xbb\x52\x23\x6c\xc5\xa9\xf0\x1d\xab\x5d\x8c\x4d\x60\xd8\x86\xa8\x7d\x13\xd4\x91\x2f\x31\xd4", 142, { 0x63, 0x7e, 0x3a, 0xe0, 0x18, 0xd6, 0xf3, 0xb6, 0x8a, 0x93, 0xae, 0x2c, 0x75, 0x4d, 0x53, 0x73 } },
|
||||
{ "\x98\xbe\x49\xdc\x07\xba\x41\x7f\x9b\xc4\xd5\x5f\x50\xf6\xb7\xaa\x56\xf0\xd1\x33\x1f\x80\xa6\x2d\x9a\xed\xd6\x86\x7a\xe0\xc0\xde\xaf\xf0\x42\x22\xf6\xc9\x9c\xc9\x8c\xf8\x72\xab\xfe\x55\xf0\x79\x1c\x0c\x08\xdd\x0b\x4a\xd6\x2f\x7a\x82\x25\xd0\xed\x59\x0b\x27\x35\x34\xaf\x36\x00\x5b\x2b\xd8\x8c\xca\x8c\x99\x77\x94\xf6\x32\xb3\xf5\xe5\x9f\x95\xf2\x8e\xdf\x0c\xaf\x64\x48\xee\x4d\xb6\x84\x6e\x7d\x75\x2c\xaa\xa6\x14\xff\x61\xaf\x88\xbe\xc2\x69\x6f\xa8\x5f\x9c\x4d\x8d\x41\xad\xf1\x91\x15\xe8\xf6\x80\x83\x70\x65\xc8\x9f\xc0\x78\x17\x78\xdd\x79\x92\xce\x1a\xc9\xae\xe2\x87\xfd", 143, { 0xa5, 0xdb, 0x01, 0x1b, 0x71, 0xec, 0xf0, 0x5c, 0x2f, 0xaf, 0x35, 0x2c, 0xf6, 0x74, 0xfd, 0x3e } },
|
||||
{ "\xaf\x65\xf8\x23\xbb\x92\xad\x22\x9a\x57\xa3\x3f\x0d\xae\x76\xbc\xc8\x0b\xf1\x9b\x0d\xee\x34\x80\xe5\x98\x81\xb4\xfe\xda\xa3\x46\x1c\x08\xfb\x4c\x3d\x0d\x28\x47\x4e\x98\x52\xa4\x83\x74\x13\x5f\x57\xf6\x03\xc2\x20\x8f\xdf\x4b\x4d\x82\x55\xac\x40\xaf\x6f\xec\xc2\x8d\x99\xab\x27\x36\x51\x82\xff\x9c\x6a\x89\x76\xd9\xfc\xf2\x49\xa5\xeb\xd2\x65\xe1\x13\x00\x1e\x50\x0d\x16\x08\x65\xa1\x95\x76\x36\xc8\x25\x8d\x90\x5c\xf9\x03\x25\x5e\x51\x7a\xe1\xe3\x19\x73\x5a\x9d\xaf\xf0\x66\x02\xc2\xab\xc6\x1b\x55\xec\xff\xeb\xe3\x0b\x49\x7a\x9d\x82\xa1\x7d\xcf\xae\xf9\xa3\x60\x22\x90\x7e\x78", 144, { 0x70, 0xcb, 0x37, 0x7b, 0x48, 0x29, 0xcd, 0x1c, 0x9e, 0xe6, 0x27, 0x97, 0xf6, 0x5f, 0xb5, 0xdd } },
|
||||
{ "\xa8\x5c\x0c\x3c\xd5\xa2\xe2\xb5\x48\xa8\xf4\xce\x7f\x83\x03\x7c\x55\x0a\xa3\xf8\x1c\xeb\xe8\x28\x53\xdb\xad\x1c\x04\xe9\x80\xb3\xbd\xec\x2d\x5e\x28\x1b\xe6\xfc\x4a\xbb\x0c\xe5\x54\xf3\x9c\x02\x29\xbb\x39\x19\x6d\xf3\xd1\x27\x46\x90\xef\xe6\xb3\xf1\x9d\x6e\x85\x50\xf4\xf8\xfd\x53\x42\xbd\x04\xc2\xd6\xfd\x01\x54\x6a\x1b\x5b\xa2\x2e\xe5\x8b\x3d\x6d\xf2\xdc\xdb\xde\x24\xc2\xac\x89\x4e\xd4\xcb\x54\xef\x68\xd0\x2a\x1b\xca\x82\xc7\x7a\x18\xa9\x22\x6a\xbd\x02\x76\x40\x88\x4c\xef\xac\x68\x80\xee\x3a\xc6\x1d\xf9\xf5\x7f\xa1\x42\x26\x7d\x13\xd2\x3a\xf1\xbd\x52\xc1\x2f\xf8\x76\x93\x25", 145, { 0xaa, 0x81, 0x41, 0xd2, 0xf2, 0x8b, 0x40, 0x43, 0x3f, 0xcb, 0x21, 0x01, 0x79, 0xcd, 0xe5, 0xf0 } },
|
||||
{ "\x1f\x06\x0d\x79\xa6\x8b\x79\x3f\x43\x92\x8c\x54\x4a\x9f\x08\x5a\x16\xb2\x82\x50\xa3\x6f\x3e\xcc\x39\xec\x36\xd8\x43\x1c\x39\x67\x3e\xd2\x30\x72\xcd\x75\x7d\xb4\xe9\x3f\x7c\xfe\x35\x31\x2b\x37\x6f\x97\xe6\xf4\x03\x33\x4b\xb0\xba\x09\x3c\xa8\x8f\xc6\x02\x56\xa2\xce\x8f\x87\x46\xe1\xdc\x1b\x35\x69\x71\x59\xe3\x62\x03\xec\xef\xe6\x37\x7e\xb6\x54\x85\xf0\x02\x1c\x37\x33\xe0\x2a\x91\xc6\x8f\xed\x0b\xcc\x94\x03\xba\xc9\xeb\x83\xcd\xf9\x58\xe6\x32\x4d\xdb\x92\x58\x03\x41\x05\x10\xe0\xd7\x9b\x8d\x0d\x3a\xfb\x8a\x8c\x4a\x24\x8a\x55\x3d\x10\x3b\x11\xcf\x02\xf4\x72\x97\x71\x5d\x2d\x75\x91", 146, { 0x08, 0xbc, 0x75, 0x2b, 0x6e, 0x0a, 0xe8, 0xd2, 0x25, 0x7e, 0x6c, 0x2b, 0x47, 0xf3, 0x79, 0x7f } },
|
||||
{ "\x2e\x95\x28\x7a\x10\xd5\xfc\xf7\x9f\xca\xa0\xee\x91\x7b\x16\x67\xf0\x36\xc3\x3a\x83\x48\xa6\x59\x4b\x58\xa5\xb8\x29\x60\x03\xd5\x9d\x49\xee\xe7\xa9\x23\x35\xa7\xd3\xfe\x17\xb5\x4a\x67\x37\xa9\x20\x82\xab\xb7\xb6\xc1\x33\xfe\x35\x3e\x86\x6d\x38\xbb\xc8\x52\x87\x33\x19\x81\xff\x1c\x47\x1d\x8d\x3c\xa3\x06\x59\x25\xf1\xdf\xff\x4f\x79\xba\xf8\xd0\x3a\x63\x17\xba\x3e\x46\x30\x11\x09\xfd\xd3\x67\x2b\x7a\x36\x16\xf5\xce\x30\x1a\x48\x93\x62\x89\x89\xfc\x70\xaf\xb0\x77\x6d\xca\x80\xfc\x55\x5f\xd1\xf6\xb3\x37\x09\xca\x63\xf9\xa9\x08\x72\x65\x03\x2d\x21\x2a\x0a\x12\x09\x65\x41\xf5\x58\xb8\xd6", 147, { 0x43, 0x95, 0x30, 0xa4, 0x0d, 0xbc, 0x2d, 0x03, 0x2c, 0x61, 0xc3, 0x95, 0x63, 0xd2, 0x7d, 0x95 } },
|
||||
{ "\x23\x39\x02\xc8\x3e\x52\xc0\x42\x30\x67\x00\x0c\xad\x1c\xfd\x17\x5e\xd7\x5c\x36\xaf\xc4\x02\xec\x36\xf2\x90\x60\xbe\x9a\x7c\x6d\xf0\x80\xcd\xd6\x9d\x73\x72\x97\xab\xee\x40\x56\x99\xe1\x87\xf8\xb0\x89\x4f\x50\xc8\x7b\x34\xf3\xb4\xc1\xdb\x27\x4b\x1b\x10\xfa\x14\x67\x7e\x6e\x8d\x1b\x0a\xd2\x18\xee\xcc\x2c\x83\x96\xaa\xd2\x32\xad\x93\x17\xeb\xad\x55\x23\x3e\x1a\x1c\xdc\x8f\xbf\x88\x00\xc1\x10\x69\x55\x81\xae\x1a\xf7\x2c\x0a\x77\xd0\x5e\x21\x7c\x27\x18\x65\x7b\x4f\x8d\xbc\xf9\x7f\x89\xa1\x26\xc2\x7f\x69\xf8\x05\x2d\xa0\xe3\x4e\xee\x92\x37\x0c\x9c\xe5\x15\x89\x1f\x63\x0f\x7b\x97\xd6\x5c\xba", 148, { 0x7a, 0x61, 0x56, 0xe4, 0xc4, 0xdf, 0xf9, 0x6d, 0xc2, 0x11, 0x35, 0x16, 0xf1, 0x9a, 0x6e, 0x89 } },
|
||||
{ "\x22\x0c\xb4\x0d\x4a\xfa\xce\x1d\x0e\xfd\x74\x8b\x8b\x3b\x3f\x1d\x47\x28\xf5\x13\x1b\x25\x7b\x98\xba\x42\x78\x54\xe2\x24\x89\x1e\x1d\x02\x1a\xcf\x34\xc9\xe7\x32\x31\x60\x10\x17\x10\x06\xd2\x87\x02\xd7\xe8\x11\x5d\x6d\x7d\x43\x23\xa2\xcc\x35\x2c\x74\x56\x3f\xf3\x02\xbf\xca\xfb\xb3\x46\x44\xdc\x76\xdf\x2d\xee\x23\xef\x4e\x90\x00\xa3\x0a\x16\x60\xee\xcd\x4d\x67\x1d\xa1\xab\xe8\x18\xdf\x18\x6f\x37\x02\x53\x5a\xbe\x97\x03\x22\xf7\x51\x5b\xb7\xea\x39\x68\x0a\xbc\x02\xfa\xa4\xa2\x7a\x2c\x73\x80\x1d\x92\xa6\x22\xc4\xff\xad\x15\x7a\xf0\x63\x23\x6f\x99\x48\x6a\x06\x89\xe7\x18\x09\xfc\x56\xc6\xfc\xbd", 149, { 0x69, 0x0d, 0x82, 0x75, 0x0b, 0x92, 0x08, 0xa6, 0xae, 0xc8, 0x57, 0xe3, 0x5e, 0x0f, 0x9f, 0x3e } },
|
||||
{ "\xdc\x6d\x8f\xb6\xad\x09\x2d\x16\xd0\xc8\xb1\x1d\x21\xef\x38\x87\x73\x4a\x11\x92\xcd\x4e\xd1\xae\xd5\xcd\x84\xc1\x4b\x54\xfd\x14\xac\x24\x4f\xdd\xf7\xcc\x54\x69\x8b\x5f\x6a\xe6\x2f\x57\x3e\xca\x2c\x06\xc0\xe4\x95\xb5\x36\xfd\xa7\x5b\x6d\x2a\x4b\xfb\x09\xb1\xb8\x9b\xfe\x96\x35\xdc\x17\xc1\xfc\x3b\xb4\xcd\x3a\xe3\x91\x6f\x33\x2c\xc0\x81\x83\xb4\xb9\xaa\x7f\x18\x88\xac\xba\x50\x24\x4a\xa4\xa5\xe0\xd4\x4c\x4f\xfb\x50\x46\xaf\x52\x47\xa7\x25\x34\x29\x2d\x8f\x56\x5e\x7c\x5f\xdd\xea\x83\x58\x99\xbb\xfd\xe5\x52\x92\x14\x16\x3a\x8c\x1f\x37\x81\x4c\x8c\x0f\x08\xc7\xd9\xb2\x2d\xac\xbc\x03\xc5\x6e\x63\xca", 150, { 0x7f, 0x92, 0xfb, 0x9d, 0x68, 0x56, 0xeb, 0x53, 0xe8, 0xab, 0x26, 0x4d, 0xd0, 0x3f, 0xf8, 0xe6 } },
|
||||
{ "\x28\xef\xd6\x6e\x65\xca\x78\x4f\x96\x3d\xac\xc2\x4f\xb2\x93\xaa\x30\xe8\xf4\xaf\x9a\xc3\x35\x1e\x7e\xac\x86\x5d\x51\xa6\x1d\x09\x1c\xef\x9b\xae\xaf\x4f\x8e\x22\xf5\x00\x10\x7e\x63\x39\x8c\xba\x8b\x59\xa0\xe4\xcd\xad\x1e\xfd\x2c\xde\x2d\x70\x3e\xfa\x8d\x30\x3d\x1d\xf8\x6d\x3c\xbb\xa3\xf2\x73\x8d\xe4\x1e\xbb\x16\xed\x7d\x15\xd1\xb6\x02\x64\xf9\xf9\xe3\x3b\xf4\x57\x11\xd1\x5d\x98\x53\x11\xad\x10\xfe\xce\x85\x1c\x53\x14\x9a\xcc\x75\x99\x3d\x9b\x05\x53\x86\x59\x5c\x23\x1c\x29\x64\xaf\xa4\xa6\x13\x4d\xc4\x21\x85\x1a\xd3\x06\xb6\x2b\x1f\x5d\xd9\xdb\xd9\x6c\x57\x44\xa1\x79\x67\xc9\xaa\xac\x46\xcf\x8a\x13", 151, { 0xf3, 0x88, 0x0d, 0xa8, 0x7a, 0x3e, 0xd7, 0x9e, 0x5d, 0x42, 0x7d, 0x7a, 0xaa, 0xbc, 0x6e, 0xd4 } },
|
||||
{ "\x14\x8b\xa1\xc0\x4b\xf6\x23\x0d\xdc\xde\xc3\x00\xe7\x16\xfd\xc9\x17\xce\x00\x68\x99\xfd\x37\x6b\xb7\xfa\x73\xd5\x15\x2a\xb7\x1b\x86\xd4\x9f\x48\x8c\x11\x6d\x40\x6a\xdf\xb1\x21\xe8\x54\x95\xc5\xa3\xef\xc2\x64\x0e\x0a\xf3\x57\x09\x6c\x14\xf7\x1c\xfb\x16\xa4\x50\x8e\x52\xe1\xaa\xe0\x97\x9d\x45\xa1\xd2\x8d\x0b\xa7\x59\xb4\x0f\x43\xd4\x04\x8a\xae\xc8\x1e\x71\xa1\xc1\x36\xaf\x03\x1c\x12\x04\xbd\x6e\x31\x79\xaa\x95\x08\x7f\xaa\x59\x67\xa4\xd6\xbd\xfb\xf1\xcd\xe8\xec\xe2\x2d\xab\xa7\x02\x1e\xaf\xb6\x23\x08\x3c\xca\x37\x64\xa8\xdb\xcf\xb0\x5a\x66\x2d\x7c\x7a\xd5\x07\xa2\x37\xfd\xdb\x93\xb4\xc1\xe9\xcb\x90\xd3", 152, { 0x60, 0x2b, 0xfd, 0x08, 0x46, 0xc2, 0x5c, 0x0d, 0x1d, 0x63, 0x05, 0xd8, 0x59, 0x14, 0x44, 0xd1 } },
|
||||
{ "\xd2\x66\x10\x9b\xcb\xcd\xeb\x30\x7e\x89\xb2\x83\x7d\x38\xdb\x9b\x63\x9c\x69\xfa\x89\xd0\x39\x1f\x62\x97\xea\x25\x74\xcd\x6a\x89\xf3\xff\x1a\x09\xfc\x16\x9d\xa7\x6b\x2e\x42\xcc\x59\x85\x0b\x8a\x35\x8e\x5a\xfa\x7e\x25\x37\xc4\x1a\xde\x40\xbd\x56\x76\x2e\xab\x7b\x6b\xff\x23\x09\xa7\xc6\x93\x93\x57\x0b\x5c\x36\xdb\xe0\x17\xb7\xd6\x81\xf9\x38\x64\xa7\x51\x97\x6b\x69\x2e\x64\x0b\xcf\x1d\x7c\x2f\xf5\x0f\x46\x45\xd9\x5a\x8a\x0a\xc1\xd6\xe9\x7e\x4b\x28\xfd\xf7\x13\x1b\x0e\x52\xfa\x2a\x6d\x44\x19\x1a\x71\xce\x43\xc4\x0b\xcf\x2f\xf0\x08\xb3\x4a\x5d\xe4\x49\x18\xde\x45\xb3\x43\x9e\x1b\x77\x42\x84\x51\xb2\xa7\xb1\x30", 153, { 0xa7, 0xb7, 0x03, 0xe9, 0xa9, 0xbe, 0x15, 0x1f, 0xd7, 0x1d, 0x12, 0xad, 0xa6, 0x66, 0x1e, 0x57 } },
|
||||
{ "\x6b\x05\x26\x51\x05\x7b\x83\x3d\xcf\xe2\xeb\xa3\xb6\x8f\x03\x34\x1a\xc5\x18\x1f\xbd\xba\x60\x24\xd8\x44\x58\x57\x48\x20\x4d\x74\xe5\xdf\xf7\xd9\xf3\x6e\x3f\x24\xb2\x40\x22\x69\x10\x1a\xad\x10\x7f\x7a\x28\x4a\xe0\xa5\x4f\x2e\x9e\x4c\xbb\x74\xd8\xda\x60\xcc\xb6\x5d\x2f\xdc\xdd\x0e\xdc\xd5\xfd\x7f\xba\xb0\x87\x60\xc2\x0b\x7c\xed\xb2\x9a\x61\xf8\x52\x4b\x4f\x8e\xd1\xfa\x27\x49\x4e\xce\xe2\x32\x74\x2e\x06\x50\x3d\x64\x34\xd1\xd7\xcc\xde\xd4\xa3\xb8\x17\xd1\x5a\xe4\x83\xa6\x4a\x90\x6d\x3f\xbf\x40\xf7\xe0\x7d\x0c\x6c\x12\x68\xa4\xb2\x28\x46\xe4\xdb\x6c\x9d\x10\xda\xeb\xb7\xac\x52\xda\xc4\xfb\x8a\xa4\x1e\x12\x7d\x91", 154, { 0x83, 0xe9, 0x8a, 0x97, 0xe1, 0xf0, 0xd6, 0x1c, 0x85, 0xf4, 0xed, 0x7e, 0x3a, 0x05, 0x3d, 0x25 } },
|
||||
{ "\xa7\x97\x0f\x14\x4e\x1b\x59\xb1\xb1\x12\x25\x89\xdd\x6b\x75\x83\x30\xd0\x3e\x19\x5f\x7c\x32\xbc\x94\xb3\xbb\xe5\xb0\xe3\x03\xba\xae\x55\x30\x58\x27\x90\xad\xc3\xf2\x4a\xa4\x68\xe3\x0c\x88\x4a\xb4\x61\xce\xd1\x02\xba\xbb\x2c\x6e\xe1\x58\x5e\xe4\x18\x83\xec\xf8\xce\x20\x22\x6c\xfd\x6c\xfd\xce\x23\x72\xb8\x3e\xda\x96\xf6\x4e\x16\x4e\x88\x02\xfb\xf1\xdc\xf6\x59\xa7\x03\x9f\xc5\x80\x5d\xa9\x55\xa2\xe3\x80\xf7\x9a\x11\xeb\x6e\xd3\x6e\xd2\xea\x24\xb9\x20\x44\x83\xb2\xc3\xd3\xd7\x82\xd0\xed\xec\xc8\xc4\xfe\x80\x40\xe6\x3e\x7a\x12\xc8\x12\x3a\xb5\xec\x01\x0b\x7e\x82\x51\xb5\xc9\x4f\x3e\x30\xc2\xaa\xd6\x72\xd1\xa1\x74\x69", 155, { 0xad, 0x2e, 0x8c, 0x9f, 0xe8, 0x7f, 0x9d, 0xba, 0x71, 0xc8, 0x41, 0x50, 0x33, 0x22, 0x2e, 0xaa } },
|
||||
{ "\xa0\x38\xd6\x05\xca\xd1\xdd\x6c\x21\xa7\xe2\x51\x9c\x74\xb0\x5f\xdb\x33\x21\xcf\x59\x00\x58\x19\x2d\x1b\x98\xc6\x7d\x0b\xbf\x64\x7f\xdf\x63\x94\x2d\x90\x88\x3d\x85\x82\xfa\xe3\x7a\x29\x4d\x12\x7a\xc8\x6f\xf4\x9d\x55\xe7\x02\x67\x79\xac\xd7\x3a\xb3\xa4\x20\x5b\x9c\xb8\xb0\x9f\x45\x90\xb0\xb1\xbc\xf0\xf4\x03\xae\xae\x68\x4f\x26\x4f\xa9\xc9\x74\x3e\xb0\xe3\x28\xa8\xa9\xbc\x3d\xf7\xe2\x26\x54\xe8\xdf\x52\x15\x4b\x8a\x1b\xba\x57\x87\xeb\xa7\xa7\xa6\x4e\x31\xd5\x72\x11\x7f\xb1\xe6\x16\x8e\x1f\x3f\xb7\x4e\x8a\xed\xd5\xea\x09\xa3\x7c\x25\x0c\x8d\x34\xdf\xc2\xa1\xe7\xb8\x0b\x0f\x6a\xcb\x15\xd2\xaa\x9b\x95\x68\x74\x0c\xa4\x9e", 156, { 0x0d, 0x7b, 0x57, 0x4b, 0x26, 0x26, 0xcd, 0x87, 0x41, 0x4e, 0x6a, 0xff, 0x3b, 0x56, 0x58, 0x20 } },
|
||||
{ "\xe0\x88\x34\x85\x5b\x42\x2d\x81\x50\x97\x28\x7f\x73\x90\xc7\x46\xaa\x84\xaf\xe7\x97\xdb\x23\x4f\xc6\xed\x3e\xfb\x70\x08\xcc\xca\xea\x91\xc6\xee\xad\x41\x69\xfc\x02\x91\xf2\x24\x4a\x31\xf8\x7a\xe7\xb1\x65\x72\xcb\x43\x12\x6b\x9b\x97\xff\x62\x7f\xe6\x2c\xc7\x89\x0b\x16\x6c\xbf\xcb\xd1\x9a\xc7\x35\xbe\x3e\x2e\x25\xea\x41\x54\xe2\x04\xf5\xf8\xe7\xf8\xab\x5c\xbf\x2c\x61\x15\x09\x56\x98\x71\x9b\xf8\x44\x84\xc3\x79\xdd\xd1\xa9\xe1\x93\x92\xd0\x31\x9e\xa5\xbb\x5d\xb3\x13\xac\xe7\x92\x3d\x88\x19\xbc\xa5\xd6\xdf\x43\x56\xe6\x3f\xb9\xf1\x0e\x75\x4a\x56\x10\xaf\xe6\xeb\x97\x61\x96\x8c\xe0\x46\xf0\x0f\x76\xf5\xa6\x72\x15\x1c\x38\xa4", 157, { 0x73, 0xb6, 0x03, 0x35, 0xf6, 0xda, 0xb2, 0x8b, 0x69, 0xf1, 0x80, 0xf7, 0x40, 0x0b, 0x06, 0xc0 } },
|
||||
{ "\xb0\x5b\xca\xec\x8e\xbf\x10\xfa\x8f\xd9\x65\x89\x8d\x7a\xfb\xad\xde\x0e\x2d\xbe\xf5\x93\xf1\xe1\x28\x34\x69\x30\x8c\x86\x98\x85\xfc\x5e\x31\xe8\x39\x4c\x8b\x92\x2b\xb9\xb2\x9e\x46\x99\x97\x4b\x08\xcc\x67\xf0\x9e\x17\xf9\x7d\xa6\xb9\x60\xa9\x10\xad\xa0\xbd\x1e\x7c\x7e\xfd\x8a\xbb\x70\xae\xc6\x28\xb4\xc9\x5e\x5d\x7d\x3a\x7a\x2f\x47\xd5\x7f\xa6\x4c\xd6\xd6\x98\x0f\x13\xc4\xe4\x15\xc0\x78\x48\xb3\xdf\x24\xe0\x03\x42\x43\x3c\xf0\x3e\xf8\x1c\x71\xee\x97\xca\xd3\x21\x3d\x14\x2e\xe1\x99\xe5\xf9\xa1\xce\x80\xba\x02\x71\x58\xd6\x42\xad\x8e\x86\x41\x86\x07\xea\x31\x3a\x29\x37\xda\xc3\x33\x0d\x88\x7a\x37\xe4\x92\xd5\xb4\xa4\x87\x51\xd4", 158, { 0x26, 0x34, 0xea, 0x0f, 0xa7, 0x52, 0x4b, 0x9a, 0xb2, 0xdf, 0xcc, 0x1f, 0xf1, 0xd3, 0xd0, 0x78 } },
|
||||
{ "\x53\xf6\x6b\x3e\xe8\xda\xc8\x99\x3f\xa0\x74\x9f\x26\xd7\x47\xd9\x94\x73\x64\xfc\xf9\xbe\xdb\xe0\xb1\xdc\x6e\x19\x92\xf9\x71\x34\xa4\x11\xca\x90\xf0\x5b\x18\xd6\x71\x53\xf0\x16\x28\x63\x43\x7f\x4b\x2d\xdb\xbb\x9d\x77\x04\xe5\xd9\xb4\x47\x28\x48\x2b\x52\xf5\x72\xc6\xf3\xe0\xf1\x79\x43\x18\x60\x4d\xe0\x81\x73\x08\x52\x70\x21\x7b\x8f\x02\xfb\x68\x99\x19\xa0\x0d\x45\xf4\x49\x52\x18\x6a\x80\x8a\x4a\xc3\xee\xe9\xec\x33\x51\x83\x25\xf4\x8c\xfd\x98\xff\xd8\xd2\xe1\x66\x19\x44\x3f\x51\x4b\xdd\x4c\x93\x1b\xa0\xe6\xe8\x92\xd1\x32\xcd\xec\x5e\xb7\xfc\x87\xe9\xa5\x83\xf7\x73\x39\x80\x36\xa6\x38\x7b\xf9\xbe\x98\x60\x1d\x16\x3e\x17\x40\x4b\xe2", 159, { 0xe6, 0xaf, 0x93, 0x2f, 0xba, 0x00, 0x41, 0x8d, 0x2c, 0x9f, 0xc7, 0x71, 0x81, 0x48, 0x2c, 0xfe } },
|
||||
{ "\xc2\x6d\x0f\x10\x92\xef\x8c\x47\x47\x46\x72\x44\x42\x38\x9f\x59\x48\xfe\x6a\xf6\xd5\x9f\x8c\x49\x1a\x5b\xac\x02\x96\x3d\x86\x2f\x4c\xd3\xb7\x47\xa6\xfa\x27\x42\xe6\xd3\x13\xe5\x45\xd2\xb6\x1c\xaa\xf5\x93\x7f\x08\x11\x62\xf7\x54\x47\x94\x7a\x22\x96\x85\xf1\xdb\x8b\x3e\x3b\x9d\x13\xe3\x4b\xaf\x71\xbf\x6d\x9f\x4a\xea\xa6\xfb\xdd\x95\x38\xa8\x51\xf2\x44\xe2\x27\xc2\x8a\xd0\xcf\x7c\x4c\xc3\x56\x17\x52\x0b\x3c\x75\x06\x76\x64\x6c\xbf\x66\x24\x71\x1b\x8e\x7c\xe3\x85\x49\x64\xf2\xd6\x96\x3e\x2a\x17\xb4\x6b\xa0\x65\x56\xfa\xb7\xed\x84\x7a\x8f\x17\x0e\xf0\x0b\xc0\xad\xe4\x7e\x9f\xb7\x96\xf2\xc9\x7e\x4e\x14\x4f\x47\xd1\xbf\x05\xe2\xef\x23\x5e", 160, { 0xc1, 0xf7, 0x9a, 0xa7, 0xb1, 0x56, 0xdd, 0x85, 0x09, 0x0d, 0x4f, 0xc0, 0xd1, 0x25, 0xb0, 0x3c } },
|
||||
{ "\xeb\x39\x92\x73\x9b\xd1\xe7\x22\x4b\x5a\x93\x53\x87\x0e\x45\x56\xcb\xed\x35\x68\xdd\x13\x0e\x55\xc6\x23\x76\x37\x6e\xdf\x3b\x5c\xd3\xda\x1b\x45\xe6\x44\x30\xcb\x02\xe4\xf6\x5d\x09\x25\xfb\x64\x1d\x47\x22\xc7\xf8\xb6\x93\x8a\xe9\x78\x42\x91\x6c\xbf\x1b\x83\x64\x9e\xc7\xca\xf7\xd9\x1e\xb6\x06\xd5\x29\xc1\x48\xae\xd2\xed\x02\x67\x2b\x4a\x65\x3c\x57\x94\x83\x14\x19\xf8\xef\x12\xf7\xf7\xf1\x4b\x0a\x64\x63\x92\x65\x87\x2c\x6e\x20\x64\x56\x2d\x00\x15\xcd\x12\xc4\x54\xb6\xa9\x0e\x15\x69\x3c\xec\x50\x0d\x5e\x03\xdc\xcf\xa4\x57\x77\xbf\x74\xb9\xe2\x47\xf5\xce\x29\x48\x26\xb7\x01\xd2\x0a\x62\x49\x80\x01\x6d\xb3\x6e\x33\xb2\x7c\xd9\x25\x73\x57\x51", 161, { 0x25, 0x9e, 0x60, 0x07, 0xc6, 0x99, 0x48, 0xe3, 0x91, 0x92, 0x4e, 0x39, 0xd7, 0x44, 0x7f, 0x63 } },
|
||||
{ "\x6d\x23\x68\x9d\x82\xcf\x6b\x2b\xad\x27\xf5\x32\x1c\x2d\xd3\x66\x15\x79\x8f\x57\x48\x26\x11\x67\x3d\x5d\x61\x66\xec\x7c\x8a\xcc\x6b\xe2\x9a\x92\xc2\x5a\xc7\xad\xda\x21\xac\x28\x94\x95\xb0\xdc\xf7\x7d\x87\xcf\x81\xef\xd2\x27\x9e\xe2\xe2\xc9\x36\x50\x9a\x93\x61\x07\x72\x32\x36\x0d\x98\xa0\xc1\xae\x31\x3d\x12\x24\xbd\x89\x72\xe1\x98\x7c\xb1\x7b\x9c\x82\x9b\x34\xe4\x16\x89\x25\xac\xfa\x13\x07\x54\x10\xe3\x9e\x83\xd9\xa5\xc3\x68\x87\x1a\x0c\x1c\xc0\x4c\x1a\x23\xf2\xdc\x7e\x12\x4d\x77\x48\x4a\x62\x67\x2e\xe2\x56\x45\x56\xa3\xc2\xcd\xc0\x2c\x2b\xca\x53\x36\x19\x30\x83\xf2\xd6\x48\x9b\x8f\xc4\x06\xac\xd8\x5b\x76\x12\xf9\xbf\x55\x9f\x61\xfa\xbc\x67", 162, { 0x02, 0xa5, 0xc5, 0x80, 0xb9, 0x42, 0x65, 0x02, 0xa8, 0x7b, 0x20, 0x32, 0x10, 0x65, 0xad, 0x6c } },
|
||||
{ "\xc3\xdb\xf7\x28\x38\x6a\x74\x53\x7f\x06\xd7\xbb\x64\x1d\x2a\xd9\x3e\x88\x32\xba\x91\x81\xdd\x86\xd4\x42\xd7\xad\x4e\x3b\x3b\xaf\x1a\xee\x67\x88\x49\x6b\xe8\xb7\x26\x63\x94\xea\x94\xec\xb7\x48\x94\xd0\x65\x5a\xe3\x92\xef\x97\xc0\xfe\x70\x8a\xcb\x6c\x87\xa2\x09\x91\x1f\x96\x04\x01\x69\x73\x10\x45\xeb\x43\xa8\x94\xb2\x5b\xf6\x32\xa3\x42\x71\x62\xf0\x39\xa1\x09\xa6\x6c\xfe\xe1\x62\xb3\xf6\x56\x24\x05\x0e\x01\x3b\x7a\x20\xbe\x60\xfa\xc2\x6c\xdf\x87\xc7\x40\xf0\x25\xdf\xc6\x24\x62\x5a\x76\xfb\x85\x09\xef\x92\x57\x45\xd2\x79\x88\x09\x3e\xa3\xc0\x3a\xe3\x77\x44\x08\xc5\x03\x40\x6c\x8f\x50\xb7\xd1\x91\xd0\x04\xcf\x58\xf4\x0b\x12\xe9\xda\x02\x59\x99\x24", 163, { 0xbf, 0x90, 0x55, 0xe1, 0xda, 0x81, 0x3d, 0x69, 0x5c, 0x5d, 0x2c, 0x5d, 0x96, 0xe9, 0x51, 0x54 } },
|
||||
{ "\xd6\x9b\x8c\xe4\x3b\x44\xc8\xb3\x53\x9c\xf5\xe1\xfa\x49\xb3\xc6\xac\xeb\x98\x37\x13\xe5\xc5\x14\x31\x3c\x24\xff\x27\x97\x40\x27\xa0\x66\xc0\x42\xdd\x20\x81\x99\x5d\xa4\x4f\x3d\x28\xc1\x40\x57\xb8\xd1\xae\x9d\x85\x80\xcf\xe1\x2c\xaa\xf3\xc3\x3b\x62\x59\x87\x9b\x10\xad\x01\x9a\xb2\x22\xad\x95\x43\x28\xdb\x3e\x38\xca\x07\x90\x27\xa7\x47\x4c\x83\x8b\xdd\x2e\x82\xaa\xec\xb1\x1f\x78\x48\x7c\x3b\x28\x66\x68\xdf\xbf\x72\x2e\x9c\xd3\x80\xb2\x13\xe5\xda\xe6\x91\x58\x78\x5c\xd2\x0e\x8d\x6d\xe7\x9e\x3e\xff\x32\x33\x6d\xf5\x8d\x04\xb4\x39\x8a\x6b\x6e\x5f\xd5\xa5\xef\xf6\xb6\x25\xd3\x70\xb3\x95\x74\xab\x52\x6a\x75\x1b\xfc\x22\x7b\x96\xfd\x1d\xfc\xbc\xa8\x15\x2f", 164, { 0x9c, 0x17, 0x1d, 0x5e, 0x84, 0xcb, 0x1e, 0x60, 0x48, 0xd1, 0x73, 0x61, 0xee, 0xa5, 0xbb, 0x78 } },
|
||||
{ "\x01\x98\x3c\x23\x59\x11\xf1\xec\x7f\x84\x1e\xf7\xe1\x31\x30\x7f\x2b\xe7\xb4\x18\x6e\xe7\x8b\x69\xed\xe7\xc9\xf7\x84\x32\x30\x1c\xb6\xec\x44\x16\x51\x74\x0b\x3b\xc0\xe2\x63\x4b\xed\xaf\xff\xde\xd0\x74\x00\xfc\x99\xcb\x2c\xcb\x76\x52\xcd\x63\x01\xce\x28\xbe\x4a\x6b\x99\xcb\x7c\x21\x48\xa1\x2e\x33\x8a\xd0\x48\xd2\xd6\xd4\x90\xde\x61\xa3\xd0\xcc\x59\x65\xa6\xa2\xbb\x44\xe8\x1f\xd2\x59\xb1\xf9\x4d\xc5\x0d\x3e\xfb\xe1\x3d\xdc\x25\x8d\xa7\x3c\x88\xa5\x5d\x08\xed\x92\x48\x0e\x67\xfc\xf0\x3c\x29\x9d\xeb\xcb\x01\x31\xe1\x79\x75\x8a\x37\xee\x78\xbf\x60\x40\xc9\x84\xbc\x92\xe9\x95\x2b\xd7\xb7\x4d\x33\xb4\xa9\x53\xca\x84\xa9\x73\xc0\x75\x8a\x8b\xcb\xcf\x25\x9c\x31", 165, { 0x17, 0x89, 0x0e, 0x3e, 0xab, 0xcb, 0x90, 0x4d, 0xe0, 0xf3, 0x5b, 0x5b, 0xfe, 0x31, 0x6d, 0x40 } },
|
||||
{ "\x55\x14\x00\x0c\xc4\x0a\xbb\x3d\x78\xce\xe9\xf0\x2e\xd2\x57\xc7\xe4\x74\x2e\xa5\xdd\xd0\xca\x1a\xc1\x40\xaa\x66\xe0\x71\x7f\x2c\x97\x23\x67\xb4\xcb\x7c\x33\xdd\x93\x0a\xe4\x9d\xf2\x54\x35\x36\xc1\x1b\x52\xf8\xac\x32\xa6\xad\x53\xf7\xd2\xa4\x90\x6d\xb9\x5d\xd8\xf7\xb8\xce\xba\xb3\xf3\x50\x85\x71\xcb\x29\x07\x4f\x6b\xb6\x6f\xf3\x82\x35\x54\x63\x0b\x2d\xce\x84\x47\x7a\xc2\x2d\xcd\xf9\x3c\xe7\xb7\xcc\xf5\x43\xfe\x4a\xf3\xd8\xe0\x86\x50\xd8\x7d\x7a\x12\x4e\x82\xd1\x39\xf7\xfc\x4e\xd8\xba\x4e\xdc\x5b\xc4\x3e\x32\xe7\x44\x29\x22\xdf\xc0\x57\x7f\x82\x13\x69\xa9\xb1\x03\xef\xb7\xce\x83\x16\x3f\xc1\x82\x7e\xc4\x14\x6d\x2a\xbd\x3e\x48\x91\x3e\xfd\x64\xd1\x46\xdc\xbe", 166, { 0xf1, 0x4c, 0xc8, 0x4a, 0x3c, 0x5d, 0xf7, 0xd0, 0x16, 0x5d, 0x8d, 0xf6, 0xf1, 0x0e, 0x52, 0xec } },
|
||||
{ "\x03\xa4\xd4\xf4\xa9\x86\x0f\xe5\x44\x9f\xc7\xe3\x03\xf4\x4d\x97\x95\x44\x26\x72\x1f\x12\x50\xcc\x4a\x50\xa2\x9b\x73\xa9\x51\xd0\x06\x6b\x8f\x51\xe5\x10\x4d\x8f\x01\x68\x22\xc5\x0c\x64\x44\xcc\x45\x81\xb2\x9c\x72\xce\x74\x63\xec\x9c\xfa\x3b\xd4\xc2\xa2\x8c\x64\x8a\x55\xfe\x60\x3c\x51\x18\xaa\x44\x01\x7a\xf5\x02\x07\xb3\x92\x2f\x5c\xc0\x66\xe7\x8f\x22\xfd\x57\x29\x9b\xb7\x03\x32\x84\x20\xb4\xcc\xce\x5e\xfd\xfc\x93\xc3\x69\x89\x58\x82\x43\xfd\xe2\x7f\x02\xc8\xb1\x3f\x4e\x84\x1d\xff\xb3\x54\x0c\xe0\xe1\x65\x4e\x3f\x9d\x96\x95\x23\x48\x34\x14\xd0\x0a\xde\xb2\x78\x9b\x88\xeb\x11\xae\x9a\x44\x42\xfa\x38\x69\x77\xe6\x9d\xe4\x13\xd0\xa0\x7c\xc5\xfa\x59\x28\xf4\x11\xdd", 167, { 0xa0, 0x91, 0xf8, 0x02, 0x18, 0x02, 0x02, 0x74, 0x19, 0xaf, 0xbf, 0x2f, 0xe5, 0xd5, 0x0a, 0x96 } },
|
||||
{ "\xae\x54\x5b\x24\xdd\x9a\x7d\x0c\x63\x4c\xe7\x77\x4c\xb1\xdd\x8f\x18\xe8\x22\x29\x77\x15\x43\x47\xa3\xb6\x7d\xb8\x5a\x14\x4c\xda\x77\xd4\x91\x80\x2c\xad\x5e\xee\xde\x34\x62\x01\x9d\xd2\xec\x6c\x3f\xd8\x9d\x1c\x18\xa9\xaf\xbd\x57\x15\xdc\x56\x00\xc7\xec\x10\x81\xd4\xde\x14\xf4\x73\xb2\x91\xf0\xcc\xd1\xdd\x0c\xe9\x1a\xb3\xf1\xc9\x8a\x9b\x1b\x93\x87\x67\x2c\xe8\xc9\xd9\xed\x51\xe6\x62\xe2\xd8\x78\x05\x88\xb2\xec\x5a\x2d\x19\xea\xaf\x6c\x38\x5c\x49\x44\x40\x1e\xc8\xd5\x98\x40\xa8\xb6\x31\xfa\xe4\xf5\xf7\x2d\xb5\xac\x63\x92\x78\x3c\x2d\x81\xad\x29\x1f\x60\x1b\x92\x05\xa6\x12\x4b\xc1\x8b\xc8\x99\x7b\x4e\xe5\x89\xf5\x22\x1a\xed\xfc\xb6\xec\xf4\xfa\x60\x8f\x65\xa9\xe5\xed", 168, { 0xac, 0x8b, 0xae, 0x88, 0xd7, 0x6a, 0x35, 0x60, 0x7d, 0x02, 0x43, 0x98, 0x20, 0x2a, 0xd6, 0xec } },
|
||||
{ "\x78\xe2\xe7\xc6\x51\x93\xec\xf1\x19\xcf\x07\xc0\xbb\x00\x25\x81\x38\x37\xf5\x21\xa8\xa4\x75\xec\xce\x21\x16\x6f\x56\xe8\x8b\x7f\xad\x66\x33\x52\x7d\x27\x21\xca\xc4\xf0\xc4\xd2\x90\xeb\x38\xe1\x59\xfd\x28\x9c\xfb\x34\x5d\x98\x4e\x5c\xe8\x3d\x64\xb1\xe8\xc6\x5e\xae\xf9\x64\xeb\x04\x39\x82\x5e\xa6\xf8\x24\x6b\x01\xfc\x69\x7f\x49\x6d\x2f\xb9\xef\x63\xd5\x88\x2e\x0b\x1b\xe2\xc5\x70\x26\x1d\xbf\xec\xa1\x6e\x6e\x2a\xfd\xfd\x76\xd6\xd8\xa1\x05\xe4\x7b\x3d\x20\x7a\x7e\xb6\x19\x7b\x86\x90\x1d\xb1\x2f\x24\xe9\x96\x04\x80\x9d\xbf\xab\xdb\xa9\xe6\x1e\xb3\xe4\x92\x14\x85\xbb\x65\x7e\x28\x86\x02\x2d\xc7\xf6\x99\x90\x79\xab\x10\x9b\x7f\xe2\xcf\xc4\x19\x4c\x28\x27\x05\xf9\x62\xca\x95", 169, { 0xc4, 0xf0, 0x9b, 0x16, 0xea, 0x1a, 0x1a, 0x5a, 0x54, 0x70, 0x0c, 0xa8, 0xb4, 0xe3, 0x92, 0xd2 } },
|
||||
{ "\x73\x61\xfa\x6c\xe8\xf3\xd4\xd4\x7f\xb9\xe0\xbf\xcb\xb0\xd7\x59\x5d\x5b\x85\x46\x73\x8f\xc9\x7d\xcf\xda\xba\xc0\xa3\x91\xe4\xb7\xa8\x75\xb0\xa8\x4e\x01\xe1\xd6\x0e\x53\x3b\x73\xdb\xb4\x3e\x42\xb6\xc6\x10\xce\x61\x49\x78\x40\x2b\x8a\x06\xe1\xea\x68\x51\x2d\x07\x04\x59\x90\xb3\x04\x0a\xc0\x38\x84\xe2\xb6\x6a\x9b\xa9\x4a\x3c\x85\x5f\x6a\x6f\x72\x34\xf6\x64\xea\xb1\x3b\x13\xdb\xf4\x0b\x14\x41\x18\x75\xdb\x70\xb3\x27\x01\x01\x79\x5c\xbd\x57\xfd\x83\x71\xcc\x98\x6e\x61\x7d\x62\x33\x7e\xaf\x5d\xa3\x60\xdd\xb2\x64\x53\x5f\x13\xae\x88\xb8\x3f\x9e\x6d\x7c\xa4\x3a\x17\xdc\x1e\x02\xda\xd0\xde\x2f\xfb\xe0\x66\x8b\x7d\x8e\xb0\xec\x17\x63\x6e\x4e\x47\x95\x6d\x8c\x80\x51\x13\xbb\x7f\xab", 170, { 0x69, 0x9d, 0x5b, 0x85, 0x72, 0xec, 0xe6, 0xbf, 0x17, 0x47, 0xff, 0x53, 0xb3, 0xf0, 0xd5, 0x34 } },
|
||||
{ "\x07\x23\xbc\x20\xef\xdb\xfb\xc4\x54\x00\x01\x0c\xa3\x92\x64\x3a\x4d\xeb\x7c\x61\x0d\xdc\x76\x14\x49\x65\x87\xaf\x92\x11\x3c\x41\x46\xec\xf0\x15\x55\x22\x58\xdc\x20\x36\x38\x78\x7d\xdb\x38\x67\xd7\x72\xd1\xca\x73\x21\x62\x11\xcd\x8c\x5f\x45\x21\x33\xa8\xf2\x05\x68\xf8\xaf\x33\xeb\x74\x4c\x65\x24\x63\x96\x59\xfc\xfd\xc9\xf4\x58\x5c\x93\x83\x32\x8f\xc1\x1c\x56\xce\x88\x23\xb7\xc7\x72\xe8\x6c\x17\xe4\x6e\x4a\xd4\x48\x47\x1e\x47\xdb\x9a\x87\xb7\x14\x47\x6e\x60\xb0\x21\x24\x83\x57\x5a\x16\x97\xec\xfd\x2f\x9d\x76\x94\xca\x91\xa6\xe9\x53\xfc\x04\xea\x79\xa6\xba\xa5\x11\x69\xfd\x73\x8a\x21\x14\x32\x09\xc0\x06\xab\x21\x7e\xe4\x12\x30\x2d\xb0\xab\x59\xaa\xe9\x89\x19\x70\xb4\x71\x88\x46", 171, { 0x24, 0x02, 0xdb, 0x04, 0xc8, 0xa1, 0xc2, 0x6a, 0xaa, 0x95, 0x63, 0x35, 0x92, 0x4e, 0x35, 0x1b } },
|
||||
{ "\xa9\xde\x2f\x19\x37\x1e\x80\xe4\xb4\x9a\xf6\xcb\x04\x33\xca\x48\xe5\xc7\x4f\x7c\xd6\xd2\xea\xa7\xa2\x31\xb2\xb3\x8d\x02\xa0\xeb\x19\xa8\x73\xc9\x75\xeb\x23\xec\x83\x3c\xff\x28\x85\x15\x65\xb8\x63\x7f\x1e\x8e\x9b\xad\x54\xcb\xc5\xc6\x30\x4a\xc2\xc0\x14\x57\x81\x68\x72\x7e\x6d\x7e\x47\x7d\x77\xfc\x38\x5b\xbb\x77\x47\x92\xd1\x9f\x32\x67\xb3\xe1\x68\x5b\x46\x2b\xa8\xba\x87\xcf\x39\x50\x53\x81\xc0\x3b\xd2\x7b\xc1\xdc\x82\xc0\xb5\xe7\xdc\x7c\xc3\x9a\xa4\x8a\x1f\x0b\xd2\x10\xfc\x99\x18\x45\x2f\x84\x10\x53\x61\x99\x04\x58\xf1\x06\x59\x86\x64\x4c\x98\x69\x89\x51\x1a\x48\x2e\x95\x50\xa5\x78\x7d\xac\xe0\xe3\xcb\x30\xf8\xd7\x2f\x91\x70\xe3\xf6\x07\x50\x98\xe1\xb4\x42\x04\x11\xae\xdd\xca\x1d", 172, { 0x95, 0x82, 0xd6, 0xd6, 0x0d, 0x72, 0x51, 0x58, 0xba, 0xbc, 0x56, 0xa9, 0xf6, 0x07, 0x54, 0xa6 } },
|
||||
{ "\xab\x00\xdb\x46\x48\x54\xd3\xc2\xf6\xf3\xf2\x34\x82\x27\xb5\x3d\x3f\x4a\x10\x2c\xd1\xcd\x4b\xd1\x99\x55\x76\x6f\xb8\x00\x8a\xcf\xc2\xc6\x1e\x71\x01\xfa\xc3\xde\x63\xee\xfc\x19\x01\xb6\xdd\x34\x4c\x06\x3f\xfe\xd6\x35\x9d\xda\xba\x62\x8e\xab\xaa\xb5\xdf\xeb\x93\xbf\x4c\xdb\xef\xfb\xdb\xd4\xa6\x76\xd6\xbd\xa2\x8a\x63\x96\xee\xc6\xc1\x30\x89\xea\x21\xff\xcd\x0d\x1f\x08\x77\xe1\xdb\xf4\x52\x0f\xb8\x47\x85\xbc\xb1\xaa\x75\x2d\x53\x64\x58\x87\x5b\xe7\x58\xaf\xec\x87\x5f\x50\x6c\x45\x85\xfb\xfd\xca\x14\x68\x93\x6f\x34\xda\xb7\x79\x38\xa1\xd7\x62\x83\xb9\x47\x52\x18\x90\xd8\xad\xbe\xe5\x13\xc5\xcc\xcc\x13\xb0\x96\xce\xfc\x35\x74\x2d\x1c\xe0\x6c\x44\x9c\x35\x7b\x0d\xe2\x01\x85\xbd\x87\xcc\xd6", 173, { 0xd7, 0x83, 0x37, 0xf7, 0xb8, 0xcb, 0x87, 0x54, 0xc4, 0x01, 0x9d, 0xcf, 0x3b, 0x57, 0xf5, 0x8b } },
|
||||
{ "\x8a\xf0\x6a\x54\x8c\x8b\xb1\x44\xc1\xa8\x44\xb5\x2b\xf1\x8e\x8c\x14\x88\xcb\x2d\x72\xbb\x40\xc3\x65\x66\x8b\x2d\xdc\xe6\x15\x86\x58\xb5\xa3\x4e\xc9\xa7\x0c\x3a\x94\xc0\x05\x94\xb6\xb0\x18\x50\x02\xec\xb3\xad\x86\x69\x5d\x84\x0c\xf7\x03\x31\xbc\x39\x71\x1b\xdf\x3d\xdc\xe1\xbe\xbc\x9b\x22\xa8\xef\xf6\xe9\x13\x0b\x17\xb4\xda\x5b\x1e\x1f\xa5\xf9\x50\x32\x67\x29\x6f\x44\x00\x52\x24\x89\x02\x9a\x99\x3f\x90\x1d\x23\x72\x62\xc9\x1d\x67\xe6\xd9\xd0\xab\x81\xeb\x8e\xb8\xf3\xc0\xde\x40\xd9\x90\xd1\x19\x4b\x08\x73\xc6\xa5\xe1\x5d\x9e\x64\x1e\x68\x9c\x26\xe2\x7c\xc2\xd3\xeb\x86\x2a\xdb\xaf\x87\xaa\x95\x11\xc9\x23\xc7\xc0\x2e\x66\x43\x2d\xa1\xc4\xae\x26\xad\x31\x5c\x14\x2c\x14\x57\xcd\x17\xae\x7f\x17", 174, { 0x8b, 0xaa, 0x35, 0x9d, 0xe0, 0x56, 0x8f, 0x69, 0xc8, 0x17, 0x5c, 0x10, 0x2d, 0x43, 0x12, 0xe3 } },
|
||||
{ "\x7d\x24\xcb\xba\x8f\x2a\xad\x41\xd8\x4e\x94\x4d\x89\xdf\x8b\x95\xf2\x78\xff\x7d\x0d\x2c\x9d\x52\x35\x4f\x5a\x20\xf4\xdf\x8c\x30\xf9\x8e\x35\x22\x28\x6d\x61\xa3\xcc\x36\xa5\xca\xe8\x36\xc7\x14\xab\xd5\x7c\xfa\x01\xc4\x4c\x2d\x46\xc1\x92\x6e\x15\x0a\x9f\x0b\x3f\x5c\xff\xf9\xd8\xa6\xd3\x8b\x6b\x4f\x5d\xcd\x4d\x21\x9b\x7f\x0f\xd0\x0a\xb1\x0d\x2b\x8b\xf8\x23\xde\x63\x4a\x7f\xe1\x5d\x7b\x92\x81\x0a\x55\x21\x09\x29\x4d\x78\x0d\x21\xe8\xbd\x52\xaa\xaa\x62\x5d\x8c\xb6\xb4\x97\x80\x07\x91\x19\x33\x49\x36\x1a\x68\x55\x36\xf2\x3c\x48\x87\xca\x85\x3f\xb7\xe3\x54\xb0\x3c\x7f\x9a\x68\xe8\x6f\xe7\x1d\x7b\x3a\x4d\xaf\x53\xe7\x63\x00\x3e\x68\x66\x6c\x70\xa3\x79\xe7\x90\x1e\x0d\xb2\xec\x45\x5b\xba\xcd\x5b\x0e", 175, { 0x1e, 0x96, 0xa5, 0x23, 0xc0, 0x9c, 0x30, 0x9c, 0x2a, 0x99, 0x58, 0x95, 0xf2, 0x54, 0x8e, 0xed } },
|
||||
{ "\x8d\xe6\xfb\xff\xf9\xe6\x4a\x18\x43\x2d\xbc\x59\x01\x9a\x7f\xf9\x95\x83\x87\xa4\x46\xbe\x37\xe3\xfc\xdc\xa9\x9a\x98\x76\x9a\xaa\xee\x9f\xf5\xb7\x60\x79\xfa\x04\x18\xe3\x0b\x79\xe1\x50\x13\xc7\xa2\xb3\x93\xa2\x79\x96\x4b\x2d\x70\x4a\x81\x74\xdf\x39\xf1\x12\x5e\x57\x51\xf3\x64\xb7\x7f\x34\x81\x3a\x49\x27\x34\x62\xd9\x72\x6a\x44\xbb\x56\x94\x9c\x8c\x0e\x63\xfb\x42\x4e\x23\x1b\x12\xea\xb1\x53\x02\x98\x1a\x25\x0b\xce\xd2\xf5\xea\xc5\x8e\xd5\x83\xa0\xbe\x7b\xf2\xa5\xaa\x54\x30\xa9\x28\xb1\x5f\x8b\xf8\x1f\xb3\xd6\xbc\xd6\xfc\x8a\x96\x47\xd3\xf5\x60\xd8\x61\xba\x83\xac\xc7\xf3\x74\x9b\x2d\x73\xd1\x41\x6b\x24\x14\x32\x4d\x8f\xf1\x4b\x86\x7b\x52\x24\x35\xac\xed\xa1\x0c\xcc\x7e\xa8\x23\x68\xa6\xed\x58\x11", 176, { 0xbe, 0xf1, 0xe8, 0x50, 0x33, 0xbf, 0xf7, 0xbe, 0x13, 0x51, 0x2e, 0x59, 0x3c, 0x64, 0x15, 0xd8 } },
|
||||
{ "\x60\xe8\x60\xa3\x1c\xe8\x6f\xa2\x7a\x41\x80\xbf\xa4\xa1\x41\x7b\x48\x81\x9e\xe3\x31\xb7\xe9\x79\x81\x27\xa3\x33\x8d\x9a\xea\x9c\x55\xa7\x7e\x19\x9e\xcd\x71\x47\xae\xa3\x6b\x7f\xa3\x26\x97\x7b\x71\x32\x2e\x12\x76\x0c\x9e\x1f\xbc\x1c\x56\x80\xca\xb8\x31\x3a\x27\x1b\x7c\xba\x6c\x74\xa6\x36\x05\x1b\x83\x32\x84\xde\x3d\x1f\xa1\x7a\xd7\x1e\xd2\x25\x5f\xe2\x83\x48\xb0\xb3\xf3\x4a\xe1\x8e\xab\x88\x4e\x69\x9b\x60\x41\x95\xd2\x6d\x3c\x3d\xd9\xcd\xe5\x0b\xad\x9d\x8e\xea\x58\x86\x60\xe6\x2b\x71\x25\x2f\x9a\x56\xaf\x3c\xb4\x32\xe7\x0b\x3d\x17\x75\x87\x69\x5d\x09\x03\x38\xf6\x45\xe3\x69\xdf\x47\x5b\x1c\xb3\xd6\x4e\x07\x5a\x28\x58\x54\xde\x4d\xe7\x16\x5e\x3c\x84\x67\x1b\x78\x30\x1f\xaf\x5f\xe9\x33\x5e\x0f\x4c\xa7", 177, { 0x21, 0xa8, 0xb9, 0x73, 0x01, 0x98, 0x8c, 0x9f, 0x67, 0xfb, 0xb8, 0xdb, 0xc4, 0xde, 0x97, 0x6a } },
|
||||
{ "\x85\xf5\x54\x31\x2f\xf4\x40\x6c\xc7\x2e\x93\xb5\xe7\x71\x35\xa6\x4f\x41\xb7\x2d\xf1\x7e\xb4\x48\x28\xb2\x53\x5f\x09\xf9\xe8\x3d\xd2\x8d\xba\xad\x80\xed\xdf\xad\x7c\xaa\x44\x51\x75\xce\xc9\x37\x49\xe9\x89\xa3\x1c\xb9\x37\x37\x8c\x75\xa3\x50\xfb\xb6\x5c\xff\x0b\x03\x70\xa2\x28\xf7\x4f\x1f\x3e\x11\xce\xbc\x8c\x18\x47\x9e\x90\x29\xdd\xdd\x22\x5f\xdd\x40\x9d\x1d\x40\x9a\x37\xfa\x4d\xc0\x72\x4a\x5b\x25\xab\x45\xb4\x15\xd0\xd7\x96\x8a\x2f\x03\x53\xae\x69\xf4\x98\xee\x85\xa2\xca\xb7\x21\x1d\x8c\xd0\xc3\x7a\x5d\x54\x4d\x57\x5f\x4a\x8f\x0c\x32\xe3\xf7\x6f\xff\x4f\x63\x44\x91\x3c\x17\x40\x9d\xec\xca\xb8\x22\xf1\xdb\xeb\xeb\x88\xa1\xe8\x32\x90\xdf\x1d\x5f\x25\x57\x7e\xed\xde\x75\x4e\x6e\x9f\x2c\x8d\xa5\x1b\xde\xff", 178, { 0x51, 0x6b, 0x97, 0x49, 0x9d, 0x54, 0x92, 0x2b, 0x34, 0xc3, 0x79, 0x77, 0x7f, 0x03, 0x8d, 0x1a } },
|
||||
{ "\xd1\xe9\x75\xd4\x09\x42\x8f\xf9\xc2\x55\xd6\xfa\x6e\x47\x6d\x92\x3f\xca\x86\xd1\x09\x59\x10\xe8\x46\x0d\x8e\x94\x33\x1f\x03\x25\x17\xfb\x09\x2a\xa3\xfd\x02\xbb\x75\xca\x65\x63\xb7\x4e\x3a\xa7\xe4\x4d\xa1\x37\xab\xa8\x8b\xb1\xec\x2f\x8c\x0c\xdf\x1d\xc9\xa7\x54\x34\x0c\xee\x14\x76\xf6\xa6\x67\x7d\x54\xd7\xaf\x77\x8a\x53\x32\xc2\x2b\xe6\xf5\x20\xab\x1c\xc3\x97\x2c\xa9\x4d\xe8\x74\x79\x6b\xa9\x00\x55\x81\x01\x32\x2e\xfc\x00\xa5\x0a\xfc\x99\xa1\x88\x0c\x3d\xaa\x11\x0c\x14\x33\x9d\x30\xda\x70\x1f\x21\x55\x49\x8f\x41\x6e\x6a\x92\x0c\xf3\x77\xc7\x9a\xe8\x5d\xb0\x40\x86\xc4\x3b\x56\xd1\xa0\xec\x14\xd9\xe7\xaa\x96\x8d\x5d\x23\xff\x36\x8a\xdc\xb9\x98\xce\xd8\xda\xa0\x8b\xe4\xa2\xc9\x80\x7d\x21\x12\x36\x5f\xf6\x94\x92", 179, { 0x6b, 0xc1, 0x3c, 0x44, 0x56, 0x28, 0x48, 0xa5, 0xc9, 0x18, 0x9c, 0x37, 0xa8, 0x8e, 0xce, 0xf2 } },
|
||||
{ "\xac\x31\xc2\x8b\xb5\x5a\x42\xf6\x67\x8b\x62\x7d\x55\xb8\x38\xaf\x5d\x0f\x5b\x31\xfa\x7a\x38\x11\x26\x42\x11\x3b\xea\xcd\x98\x04\x83\x88\x24\xe4\x32\xe0\x8e\x41\xa1\x69\xab\x66\xed\x22\x65\x92\x54\xd0\x78\x2d\x7c\x86\xc6\x16\x5e\x46\x58\x17\xcd\xc2\xf2\x7a\xa7\x3b\x52\xb5\x97\x8b\x05\x40\x84\x3d\xe5\x87\x99\xda\x32\xfb\xf2\x3f\x4c\x43\xe0\x29\x0a\x91\xd9\xd3\xbb\x0f\xff\xb6\xb7\x77\x4b\x6f\xa0\xc2\x56\xbf\x3a\xf8\xc4\xac\xe4\x26\x4d\xc4\xb3\x6e\x69\x81\x2a\x38\x97\xc8\x97\x87\x4b\x8c\x0c\x66\x72\x90\xf9\x80\xa3\x49\x63\xcf\xe3\xe1\xc3\x6d\x15\x58\x7d\x86\xfc\xc5\xfb\x6f\xee\xbb\x66\xcf\x18\xc6\x01\xfb\x68\x15\x22\x60\x1b\x31\xcd\x19\xe3\xeb\xee\xa1\xb4\x55\x33\xa2\x2b\xe6\x84\xec\x9b\xc1\x20\x81\xb6\x0f\x55\xcd", 180, { 0x38, 0xf4, 0xa7, 0xc3, 0x5e, 0x5a, 0xf4, 0x32, 0xf2, 0x12, 0x4c, 0xf5, 0x99, 0xb6, 0x90, 0xe8 } },
|
||||
{ "\xd5\x88\xdb\xf3\xe4\x11\xce\x42\xed\x80\x47\xc6\x3f\x7b\x96\xfb\x3b\x7e\x1d\x9d\xba\xfb\xcc\x9b\x1e\x9b\x34\x29\xf4\xa3\x4a\xf4\x43\x72\xbb\x71\x74\x26\xe6\x4f\xdd\x5f\x7b\x0b\xec\x1b\xae\xa1\xec\xc0\x17\x60\x77\x39\x29\xd7\x79\x38\x4c\xeb\xdc\x99\x9a\x0a\xd5\xe7\x33\x7a\xca\xf7\x3e\xcb\xdf\xb2\x7c\x6b\x1c\xf1\x8a\x58\x3c\x81\xb3\xf0\x15\x45\x6f\xe4\x9f\x7b\x7d\x4b\xa2\x17\x98\xd3\x00\x4b\xd9\x12\x9c\x28\xa8\xfa\xe6\x5e\x60\x6b\x05\x1f\x7f\xe3\x9f\x22\x86\x50\x48\xc4\x73\x06\x84\x48\xd9\xcc\x7b\x3f\x99\x11\x38\x03\x3f\x3c\x9d\x5d\xfb\x21\xe7\x47\x3a\x8f\xda\xcb\xe0\x06\x89\x0a\x24\x86\xc4\x58\x09\x82\x1e\x85\x75\xf4\x99\x37\xf0\x8a\xf0\x72\xfa\xfe\x81\x3a\x08\x83\xd6\x50\x1d\x5b\xcf\x17\x02\x85\x6d\x9a\x22\x94\x3d", 181, { 0x0a, 0x5b, 0x96, 0x06, 0x98, 0x96, 0x99, 0xa6, 0xdc, 0x6a, 0xa5, 0xbf, 0xc4, 0xfa, 0x83, 0x48 } },
|
||||
{ "\xa7\x04\x9b\x5f\x13\x65\x45\x32\x21\xf1\x01\x9e\xfe\x9e\x5a\xfd\x63\xa5\x64\xa6\x5d\x1e\x52\x18\x29\x38\x25\xc0\x39\x12\x7f\x67\x53\x38\x96\x3b\xd9\xbd\x44\x78\x23\xf1\x3a\xb3\x08\xbf\x55\xc3\x7c\xa6\x09\x4c\x53\x52\xf9\xe9\x24\xd6\xa9\xf6\x48\x88\x4b\xf7\x02\x7a\xb5\xa8\xb9\x90\x74\xa1\x60\x43\xfa\xa6\xf6\xf1\xf2\x89\x29\xde\xb5\xbc\x16\xcb\xd4\x77\x2b\x31\xd5\x82\x2e\x1a\xfc\xa0\x56\x9d\x3e\x98\x97\xf4\x5b\xe1\xfb\x3b\x04\xe9\x2c\xc7\x37\x02\x0e\x21\xac\xe9\x89\x9e\x67\xf5\x64\x9c\x6e\xd9\x4d\x5b\x95\x15\xf5\x75\x75\xff\x58\xfb\x7b\x6a\x1a\x2e\x1c\xf0\x0d\xd7\x26\xe2\xcf\x44\x32\xc8\x91\xdf\x36\x96\xf2\x6c\x37\x6e\x09\xde\x1b\x0c\x82\xd7\x9c\xd3\xdf\xbb\x59\x71\xe0\x70\x07\x31\xfe\xb4\xc4\xdd\x10\x1a\x8c\x4d\x11\xa2", 182, { 0x34, 0xf3, 0xea, 0x31, 0xf3, 0x44, 0x99, 0x87, 0x3c, 0x5f, 0x60, 0xbc, 0xe5, 0xb0, 0x5a, 0xdd } },
|
||||
{ "\xc4\x90\xf9\xf4\xf4\xb6\xc7\x39\x92\x39\xa0\x96\xf9\x06\x11\x46\x79\x2b\x71\x53\x87\x1e\x62\xf1\x15\xa7\x76\x77\xfd\x6b\xed\xfb\x96\x17\x9d\x88\x69\x25\xeb\xfe\xfe\x4e\xf5\x87\xcf\x8c\xd2\xb2\x5e\xcb\xf1\x2d\x62\x2b\x9e\x23\x1d\xf4\xa3\x30\xc9\x17\x0b\xfd\x30\x5d\x01\x7d\x5b\x2f\xd8\xc3\x62\x00\x24\x7d\x62\x5b\x05\x11\x8d\x84\x84\x52\x5c\xce\x15\xdf\xdf\x79\x3c\x18\x34\x45\x4d\xbe\x16\x97\x4b\x26\x8d\x47\xf2\x1a\xc3\x04\xd1\x4d\xf7\x65\x8e\x78\x8b\x8c\x4d\x15\x37\x79\x2c\xb7\x60\xe9\xe5\x04\x83\xe8\x97\x51\xcb\xfa\x9e\xd8\xc3\xe2\x9e\x98\x26\x0d\x9f\xc9\xd1\x9e\x52\xfb\xd9\x17\x72\xca\xb9\xa0\x46\x40\xa4\xf7\x43\xc7\xf9\xf5\xce\xc9\xd5\xb9\x1e\xe6\xc2\x73\x40\xd1\x8c\xcf\x34\xc8\x34\xfb\x35\xae\xfe\x57\x16\xc6\xa5\xb9\xc8", 183, { 0xe0, 0x50, 0xf4, 0x13, 0x5b, 0x9f, 0x3d, 0x6c, 0xf8, 0xc9, 0x95, 0x5e, 0x68, 0x81, 0xb2, 0x0a } },
|
||||
{ "\x0e\xaf\x59\xf8\x36\xdb\x60\xd5\x3b\xb6\x08\xef\xa5\x4c\x6f\x3b\x59\xfc\xfe\x33\x1b\x65\x70\x1a\xa4\x7c\x82\x5d\x5c\xc0\x36\x15\xb5\x84\xc3\xaa\x24\x6b\x1c\x91\xbc\xf3\x1b\x35\x68\x28\x4a\xf4\xc4\x78\x4e\x40\x99\xa7\xf1\xe6\xf3\xd9\xca\x6b\xe1\xcc\x8b\x92\xc9\x29\xe7\xfb\x65\xef\x1e\xe5\x5e\x0f\x26\x14\x83\x17\x77\xce\xa6\x06\x74\xff\x13\x3e\x71\x7c\xae\x97\x65\x64\xa8\x8f\x2d\xa3\xdd\xa0\x7a\x90\xce\xaa\x59\xb6\x36\x90\x5d\xb0\x4b\xdf\x6b\x2e\x92\xa8\x22\x14\x5f\x6e\xe5\xc1\xe8\x3b\x86\x6d\x05\xcd\x90\xab\x87\xee\x31\x0e\x32\xe1\xc2\xe8\x58\xf8\xf5\x2d\x13\x43\x9a\x77\x1e\x62\x0e\x23\x50\x7c\x40\x98\xb7\x48\x61\xa8\x4d\x48\x28\x0e\x59\x16\xbf\x17\x65\xd7\x4d\x5e\xd8\xcc\x21\xb0\x2f\x07\x78\x0e\xdc\x3a\xeb\xd0\xbb\xab\x78\xe6", 184, { 0xf1, 0x8e, 0x78, 0x9a, 0x46, 0xe0, 0x68, 0x70, 0x90, 0x49, 0x85, 0x8e, 0x6b, 0x49, 0x0b, 0x61 } },
|
||||
{ "\x2d\x43\x2a\x3a\xd3\xc6\x68\x31\xe9\x1e\xd8\x51\x3c\xd0\xee\xfd\xc9\x90\x15\x5b\xf4\xef\x78\x56\x62\x32\x6d\xbf\x73\x3f\x7e\x8e\x5f\xb1\x16\x47\xec\x0a\xc5\x78\xc9\x08\x30\x5e\x8b\x10\x98\xa8\x41\xc7\x05\x53\xb5\xc0\x0e\xb4\x42\x4f\x48\x94\x4d\x7c\x49\x75\x61\x13\x58\xf3\xeb\xd9\xb2\x46\x8e\xd9\x7b\xe4\x24\xdc\x40\x43\x53\xf6\x25\xbc\xc7\x3d\xb0\x8b\x11\x95\x30\xf3\x1c\xa7\xcb\x7f\x47\xf0\x23\x62\x24\xf5\xa5\x00\xcd\x95\x6e\x86\xde\x77\xd9\xb3\x12\xa1\xa9\xba\x7d\x2a\xd0\x40\x63\x08\xda\x80\xb4\x03\xf9\x8e\x25\xcb\xad\xb9\xec\x24\x10\x09\x18\x3f\xbb\xe7\x8a\x25\x58\xdc\x94\x4c\xc6\x72\x2c\x4c\xe2\x37\xcc\xab\xf8\xdf\xea\xd4\xc6\x89\x0f\x27\x29\x1a\x97\x2a\x67\xc6\x04\xdc\x18\xad\xfe\x2a\xb1\xa1\xeb\x7b\xae\x06\x27\x66\x5c\xd3\xe0", 185, { 0x75, 0x72, 0xbf, 0x88, 0x25, 0xbe, 0x77, 0x6b, 0x6f, 0x97, 0x84, 0xf0, 0x11, 0xa5, 0xc8, 0x22 } },
|
||||
{ "\x83\x40\xb5\x91\x5f\x27\x52\x19\x89\xcc\xaa\x77\xc9\x1f\x9a\x25\x71\x38\x7b\x0d\xcb\xd8\xe7\x2c\xb1\x97\x9b\xc2\x3c\xb0\x78\x33\x94\x65\xa4\x7e\xe7\x10\xcd\x57\x75\xc8\x8e\xe2\xc7\xac\xea\x0e\xff\xcf\xf5\x8c\x4b\xc0\x91\x6b\x74\xb4\x56\x52\x93\x52\x8b\x59\xe2\x1b\x51\x84\xb0\x75\xe0\xdc\x6e\x52\xe8\x2c\xe7\x81\x19\x55\x8d\x91\xbe\x4e\xee\x5e\x84\xbc\x46\x39\x59\x2a\x2d\xb8\x70\xe5\x71\x17\x60\x77\xfe\x49\x6c\xbe\xfa\x9f\xde\xa8\xed\x14\x8c\x8d\x1e\x32\x7c\x28\xf9\xa5\xa4\x33\xab\x5b\xca\x9f\xd0\x54\x8a\x6d\x44\x0b\x76\x2c\x16\x81\x57\x0f\x9b\xe2\x92\xaa\x9e\xd6\xa6\x49\xb5\x67\xd2\xed\xaf\x8a\xd3\xe4\x29\x4c\xcb\x04\x40\x9a\x3e\x83\x60\xad\x35\x76\x3b\x10\x85\xe4\xd6\x4f\x2a\x87\xbd\x3e\xcc\x1e\x57\xe3\x64\x71\x54\x01\xf8\xe3\x42\x42", 186, { 0xbb, 0x9a, 0xed, 0xe2, 0x33, 0x52, 0xb1, 0x0f, 0xad, 0xa6, 0x08, 0x76, 0x99, 0x43, 0xe4, 0x6e } },
|
||||
{ "\x82\xad\x3f\x00\xef\xbd\xc9\xaf\x43\x2a\xb1\xeb\xd9\x52\x2f\x1a\xc8\x92\x0e\xbe\x62\xa1\x08\x5a\xd6\x89\x2c\xfd\xf5\x43\x7b\x6f\x11\xef\x93\xf7\x01\xad\x83\xc7\x42\x1b\xbd\x06\x38\x6b\x29\x78\x92\x1f\x56\xcb\xcb\x64\xcb\x80\xcc\x09\x7c\x73\xae\x1a\x58\x09\x9e\x1d\xff\xf6\xda\xe8\x91\xa8\xd7\x1d\xa2\x54\x85\x44\x49\x9b\xaa\x83\x58\xd8\x6b\xfc\xa6\x09\xea\xc3\x87\x57\x08\x7a\x5d\x43\x4b\x8c\x48\x6f\xdb\x02\xf8\x07\xa7\x05\xa4\xca\xa5\xf1\x13\xb9\x36\x11\xd8\x5a\xa7\xfd\x9b\xa9\xd4\x8d\x91\x9c\xe7\x79\x0d\x52\x3e\x8f\x30\xd7\x6b\x8f\xbd\x96\x54\xa6\x07\x5c\x7b\x85\x0b\x04\x59\x1e\x9a\xc5\xe3\xfb\xaf\x14\x2e\x3b\xdf\x37\x2e\x29\xee\x68\x9a\x7a\x7d\xa2\xec\x23\xe1\x0b\x84\xd5\x10\xfd\xec\x16\xb5\xb2\x36\xfd\x63\x8c\x82\x8a\xe5\xff\x9c\x9f\xb4", 187, { 0xf7, 0xcb, 0x61, 0x06, 0xde, 0xbd, 0x8d, 0xcb, 0xa7, 0x96, 0x12, 0x6e, 0x8e, 0x63, 0x04, 0x6a } },
|
||||
{ "\x1c\xc2\x9f\x82\xba\x82\xa2\xf3\x43\xc2\x52\x6b\x18\xda\x65\x02\xa2\xdb\xb7\x94\xf6\xf3\x03\xf6\x24\xe8\x3e\x43\x1d\xc2\x90\x54\x3e\x86\xef\x4d\x7d\x1c\x5a\x54\x2f\x52\xb0\x5d\x73\xf9\x2a\x21\x3f\x2d\x7b\x2d\x05\xb3\x83\x17\x01\x7b\xaa\xcb\x22\x44\xdf\x03\x92\x5e\x2d\xd5\xe4\x8b\xf7\x66\xd9\xff\xd0\xbc\xcf\x87\xf9\xb2\xc7\xc6\x78\x04\x11\x99\xd1\x8a\x96\x9c\x64\x82\xc2\xc6\x62\x06\x0c\x30\x6d\x9c\x23\xf3\xcc\xec\xb6\x2e\x48\x8c\xe0\x27\xa6\xf8\x2f\x89\xc0\x9d\x50\xcb\x42\x14\x58\xb1\xfe\x6c\xb1\xec\xed\xa0\x9f\xdd\xc3\x27\x6e\x78\x2d\xab\x3a\x43\xaa\xd1\x5b\x7c\x03\x37\x6b\x5a\x68\x7c\xf4\x6c\x29\x78\xbb\x1e\x0e\x8c\xa3\x5b\x53\x15\x40\x4c\x43\xfa\xf9\x3d\x6f\x65\xd9\xa1\x8b\x8f\xf2\x2c\xe6\xb3\x6e\x1e\x85\x24\x33\xa0\xdb\x7a\x32\x46\x26\xe8", 188, { 0x32, 0x70, 0x9f, 0xcf, 0xca, 0x08, 0x40, 0x64, 0x9c, 0x92, 0xf1, 0x9d, 0xf0, 0x45, 0xa3, 0xf3 } },
|
||||
{ "\x4d\xb5\x68\xa9\xe3\x5e\x00\x99\xf9\x68\xe5\xe0\x06\xac\x80\xc9\x5b\xda\x23\xb1\x2d\xb9\x29\x1a\x40\x8b\xaa\xdf\x32\x8e\xdb\x82\x62\x9f\x01\xa1\x7b\xfa\x10\x88\xa1\x1c\xe4\xdf\x36\xc9\x1b\x84\x49\x2a\x8d\x74\x9b\x0e\x69\xe2\x50\x51\xed\x6a\x2f\x5a\xc1\x5f\x96\xbd\xf1\x40\xfd\x02\x85\x4a\x24\x7d\xbf\x27\xdc\x5c\xf1\xc4\x6f\xbf\xf8\x40\xae\x01\x59\x00\x95\x16\xf6\xdf\x9c\x0d\x6c\x83\x9d\xb4\x0c\xcb\x5c\x5a\x75\x64\xb8\xaf\xcb\x7b\x6d\xc8\x96\x8c\x84\x3f\x39\x59\x58\x78\x0c\xf7\x45\xfe\x19\x02\xee\x0b\x70\xf1\x2b\x26\x27\x84\x8e\xe7\xf2\x5a\x90\xd6\x5b\x9f\x5d\x72\x9e\xe2\x39\x4d\x23\x04\x8d\x54\x98\x4c\x92\x2d\xaa\x98\x99\xb9\x61\xaf\xf4\xb9\x16\xb1\x85\x8c\x11\xaf\xe1\x16\xc3\x57\x1f\xbd\x9c\xc8\x43\x8d\x8a\x84\x42\x7b\x10\x83\xb2\xc7\xfe\x64\x10", 189, { 0xcd, 0x2f, 0x08, 0x67, 0xde, 0x29, 0xd6, 0xbf, 0xf2, 0x95, 0x3e, 0xe6, 0x88, 0x73, 0x70, 0x43 } },
|
||||
{ "\x7a\xd3\xbf\xad\x0f\xab\x95\x35\x2e\xe6\xe9\xdd\x93\x58\x68\x29\x0e\x26\x43\x57\xa3\x43\x1e\x6b\xd1\x87\x20\xd8\xf0\x69\x2b\xc8\xb3\x59\x25\x08\xce\xbd\x75\x93\xb1\x85\x8a\xba\x71\x6d\x95\xec\xc8\xcf\x57\x28\x33\x22\x14\xfc\x39\x13\xa7\x38\xcc\x3e\xaf\x34\xc8\x89\xe7\xbb\x98\x1d\x94\x93\xf8\x02\x17\xaa\xd5\x56\xa2\xdf\x50\x2a\x07\x69\xe1\xf9\xac\xe8\x98\xc6\x9b\x06\x7f\xd1\xb6\xca\x1c\xf5\x08\x79\x13\xa1\x36\x29\xe7\x71\x14\xe3\xe1\x68\x53\x74\x09\xcc\x59\xd0\x51\x9f\x29\x24\xd2\xb5\x81\x77\x2d\x77\x03\xfc\x14\x32\x8b\xf6\xe1\x1c\x9f\x48\x63\xe5\x04\x98\xba\xf6\x6d\x1f\x58\x4a\x4f\x11\x27\xe5\xd0\xa3\xc9\xf4\xdd\xbd\xfb\x83\x5a\x3e\x13\xd5\x75\xe6\xa8\x63\x14\xe5\x50\x74\x6c\xfd\x84\x55\xb3\x56\xa0\x36\xed\xde\x07\xa1\xe3\x5a\x64\x97\x33\x0e\x0b\x49", 190, { 0x41, 0x35, 0xb4, 0x71, 0x1c, 0xe2, 0x04, 0x6c, 0x09, 0x30, 0x9e, 0x23, 0xaa, 0x6f, 0x9c, 0xed } },
|
||||
{ "\x80\x05\x7d\x70\xc9\xfe\x0a\x49\xd8\xf3\x91\x31\xd1\x47\x63\xd8\xea\x8b\x46\x25\x39\xed\x95\xa6\xa8\x3d\x85\xb2\x06\x9d\x82\x1e\x38\xc5\xb8\x98\x8d\xf0\xad\xa3\x2f\x67\x0b\x2f\xb4\xa8\x7c\xd4\xd4\x33\xae\xab\x36\xf0\x76\xc9\x63\x40\x10\x59\xdc\x9e\x84\x55\x46\xf2\x25\xe1\xc3\x72\x34\x44\x5d\x35\xa1\x83\x9c\x56\xf1\x9c\x37\xc1\x3b\x5c\xe7\x9d\x4c\xdd\x56\x56\xea\xa0\x37\x45\x36\x43\x6f\xff\x2a\xdf\x70\x37\x42\x00\xa7\x51\x38\x42\x0b\x84\xe7\x84\xd6\xaa\x51\xcc\x51\xa7\xbc\xb7\xc7\x74\xf7\x9b\x9b\xc7\xba\x3b\x76\x61\x2b\x25\x98\xf3\x7d\xac\x50\xae\xb3\x7e\x87\x66\x83\xe1\x76\x61\x55\x8e\x78\xc2\x6a\x2a\xf9\x8d\x1a\x5d\x8e\x56\x36\x91\x1f\x8b\x8c\x49\x3f\x5a\x88\x1b\x9c\x40\xf7\x4c\x92\x30\xe7\x06\xda\x5c\xab\x38\x5f\xa2\xfb\x0a\x31\x96\x37\xfc\x92\x28\xcc", 191, { 0xb0, 0x0c, 0x4f, 0x1c, 0x01, 0xbc, 0x03, 0x95, 0xe7, 0x9b, 0x96, 0x28, 0xa3, 0x74, 0xc6, 0x15 } },
|
||||
{ "\x9a\x2e\xf2\xaf\xde\x68\x21\x07\x22\xd0\xfd\xe7\xc0\xb0\x16\x39\x48\xc6\x0d\xb6\x5d\x0b\xfc\x11\x2c\xb2\x83\x34\x8a\x2c\x70\xa1\xa9\x68\x0a\xfb\x77\x19\xfa\x9e\x94\x2f\xd7\x68\xed\x67\x4c\x9b\xfa\xfe\xe8\xdb\x90\x81\x82\x51\x63\xc0\x47\xf2\x1c\xe0\x62\xda\x13\x90\x46\xd2\xaa\x54\x9b\xf1\x45\xfd\xc3\x5e\xe9\x39\x07\x33\x70\x46\x63\x7d\x66\xc2\xea\x60\x84\x9f\xd7\x57\xc7\x32\x32\x9a\x2b\x6a\x1c\x98\x09\x1d\xb7\xa3\x0a\x7e\xb4\xac\xc7\xab\x7a\x23\xff\x63\xf0\x00\x74\xd5\xe7\xe0\x62\x93\x27\x47\x9d\xa6\x14\x04\x46\xbb\xfd\xb2\x29\x7a\x02\x5a\xb6\xf7\x9f\x36\x9a\x41\xd9\x91\xfa\x18\x03\xca\x4c\xbd\x2d\x77\xd1\xe1\x2a\xa5\xb3\xbf\x3d\x3e\xb7\x45\x60\x84\x9e\x6d\x30\xb9\x1e\xab\x78\xe1\x78\x7f\x58\x9f\xb6\x2a\x11\x3c\x83\x7d\x70\xc7\xa6\xcc\xd5\x56\x1d\x02\xe0\x6a", 192, { 0xfd, 0xf1, 0x42, 0x20, 0xf2, 0xc8, 0x59, 0xfc, 0x92, 0xf4, 0x19, 0x99, 0x56, 0x5e, 0x8c, 0xc3 } },
|
||||
{ "\xd2\xce\xb7\x71\xfc\xfc\xf5\x64\x15\xde\x32\x91\x73\xe8\x2b\x73\x86\x5c\x8e\xbd\xad\x1a\x65\x76\xb5\x99\x1c\x3d\xee\xf3\x30\xae\xec\x1a\x76\xdd\xd7\x28\x06\xff\x6f\xd5\xc2\x29\xa1\x02\x86\x30\xbe\x72\xee\xaf\x5e\x98\xbe\x26\xd0\x8a\xf2\x3f\x3c\x15\x63\x2d\x58\xeb\x13\x2d\xc3\xf8\x15\x2e\x01\xd3\x1c\x8d\x14\x4f\x9e\xf9\xb3\x30\xa4\x76\x2a\xfa\x31\x7d\xcd\xe5\x4c\x40\x1a\xee\xac\x0a\x6a\x07\x00\xc5\x54\x6f\xd8\x96\x9f\x1c\x33\xa3\xe1\x54\xa6\xf4\xb8\x5a\x25\x77\xa4\x46\x71\x1d\x80\xee\x1e\x23\x9b\x00\x40\x6b\x77\x32\xb2\x08\x1d\x90\x02\xd9\x1b\xf4\xfc\x4c\x1c\x94\xd1\x44\x22\xb5\xe4\x15\x62\x7e\x32\xac\xbc\xe7\x5b\xcc\xd5\xd0\x51\x73\xd3\x2e\x9c\x5b\xb4\x60\x47\x9c\x4b\xa0\x6b\x6e\xd9\x94\x55\x0d\x44\x04\x57\xb5\xf6\xa7\x28\xcd\x55\x16\xf8\x20\xda\xe2\x15\x46\xd0", 193, { 0x88, 0x74, 0xaf, 0x07, 0x77, 0x96, 0x60, 0x6a, 0xa4, 0xf8, 0xd3, 0xfe, 0x51, 0x45, 0xb1, 0x39 } },
|
||||
{ "\xc1\x33\x21\xab\xe3\x5b\x83\x03\x63\x73\xed\x2b\xd9\x66\x72\x72\x0c\xef\xbb\xf6\xc4\x07\x23\x20\xbe\xe9\x02\xbf\xb9\xbe\x08\xc4\xae\xeb\xbf\x98\x1c\xf3\x32\x16\x81\x09\xac\x28\xe5\x36\x99\x01\x8f\x23\x8a\xf4\xdb\x84\x54\xf0\x24\x21\x57\x99\xdb\x82\xdc\x03\xb9\x37\x98\x0d\x11\xc1\x4e\x58\x3e\x21\x90\xe3\x3c\xfa\xa5\x44\x53\x65\x86\x85\xee\x51\x03\x99\x8a\x95\x03\x7a\xca\x94\xe8\xe0\xa7\x8c\x11\x9f\xc4\x7b\x79\x9e\xdf\xae\x7c\x6f\x64\xe7\xba\x90\x1c\x2a\x14\x3d\x02\x24\xd4\xf0\x36\x39\xe9\x77\x0b\x29\x4f\xaf\x3b\x5d\x8d\xe2\x3a\xd4\x58\xbb\xa7\xa5\x55\xe2\xdf\x30\xfc\x38\xac\xe5\x98\xb0\x1b\xb0\x6b\xc8\x6b\x00\xee\xa3\x21\x73\x35\xc5\x39\x20\x71\x6a\x77\x80\x90\x83\xdb\xf9\xff\x4e\x32\x09\x8f\x91\xc9\x0b\x75\x72\x3d\xa9\x6b\xf6\x6e\xdf\xf5\x14\x92\xa7\xbe\x75\x65\x47", 194, { 0x4a, 0x49, 0xa4, 0xc0, 0x34, 0x27, 0x8d, 0x1e, 0x19, 0x41, 0x7c, 0x92, 0xdc, 0x85, 0x81, 0xc3 } },
|
||||
{ "\x21\xcb\x7e\x33\xc3\xcb\xbd\xa0\x5d\xc8\xe1\xa6\x97\xee\x36\x10\x10\x17\x6b\xc4\x7a\x4d\x82\xc9\xe3\xdd\xe0\xfa\x0e\x14\x84\x46\xff\x99\x54\xa1\x96\x66\x93\x8b\x53\x65\x70\x3b\x38\xa3\xb7\x68\xcc\x33\xaa\xb3\x3b\xa2\xeb\xb4\x9b\x12\x90\x9f\x49\xf5\x59\x93\x72\x68\xfd\x7f\xae\x29\xa0\xb1\xc6\x37\x62\xfc\x96\x05\x11\x86\x0e\x5a\xfe\x2c\x52\xc8\xed\x92\x01\xc6\x26\xca\x93\x6c\xa8\x9f\xdc\xcb\x7d\x80\xad\xe7\x29\x04\x9a\x53\x3c\x1e\xd5\x67\x07\xde\x39\x1f\x6b\xe1\x63\x93\xcd\x57\xfb\x0f\x25\xaf\x11\xce\x36\xe1\xa1\x58\xd8\x57\x39\x75\x71\x79\xb2\xcc\x82\xd4\x19\x1d\x5d\xe6\xb2\x18\xf5\x88\x12\xd8\xce\xf8\x6b\xff\x13\x82\xe5\x6e\xc6\xcb\x27\xa1\x11\xba\xf4\xa6\xbc\x04\xf2\xb8\xb8\x52\x87\x7c\xd8\x10\xdc\xd7\x9f\xd4\x03\x6a\x34\x69\x35\xab\x72\x78\x34\xa1\x1c\xd2\xcf\x3c\x2e", 195, { 0x9c, 0x25, 0x37, 0x70, 0xb4, 0xce, 0x2c, 0x7d, 0xff, 0xd2, 0xda, 0x7d, 0x85, 0x7e, 0x25, 0xe8 } },
|
||||
{ "\x5c\x84\x4e\x4e\x98\x3f\x2a\x61\xcc\x41\xd8\x3a\xd1\x1c\xf1\x6e\x79\xda\x1d\x43\x9e\x3e\x27\xc7\xc3\x22\xba\xfc\x6a\xff\xbb\x31\xf2\x8b\x42\x6c\x29\x7d\x35\x03\x76\x6c\x83\x4a\x9c\xd5\xfb\x66\x2c\x3c\xc6\x40\x8a\x69\x87\x95\x99\xd3\x0e\x2b\x06\x1b\xb3\x1e\x2e\xaf\x55\x59\xad\x8f\xef\x20\x84\x2c\xd3\xc9\xe6\x6c\x87\x8b\x9f\xcb\x39\x6e\x22\x9b\xdf\x62\x2d\x6c\xef\x6c\x1b\x86\xb8\xfb\xc6\x93\x5c\x59\x16\x5a\x6a\x3d\x2b\xa6\x1c\x7d\x23\x45\x2a\xe0\x88\x2c\x48\x11\x59\xb8\x43\xb0\xb3\x0f\xb4\x83\x1c\xa5\x5e\xca\x6c\xda\x2a\xb0\x59\xc1\xbc\xdd\x9d\xfc\xb1\x28\xc6\xc3\x78\x6a\x9a\x03\xca\x6e\x24\xa3\xc7\x04\x5f\xe1\xae\x35\x7e\xdb\x39\x90\xd6\x2a\x93\xa3\x69\xa9\xf7\x86\x10\x53\xe6\x91\x44\x4a\x04\x2d\x89\xf4\x90\xc8\x77\x40\x7e\xe2\x66\x07\x33\x45\xb5\x8d\xdd\x51\xb7\x26\x6c\x75", 196, { 0xf4, 0x1a, 0xd3, 0x01, 0xe5, 0x69, 0x44, 0x94, 0x9b, 0x60, 0x1d, 0x3d, 0xbc, 0xc8, 0x4a, 0x94 } },
|
||||
{ "\x3b\xf5\x30\xba\xb7\xd0\x10\x79\x11\x3f\x64\x2d\x09\xa4\x70\x63\x45\x74\x7e\xce\xfa\xa3\x97\x77\x35\x1e\xdd\x11\xc4\x72\x88\x6a\xc3\x8a\x7b\xfe\xc6\x95\x82\xa6\xa0\x06\x2b\x6d\xce\xb5\x3e\x83\x83\x23\xda\x4b\x51\xda\x2d\x8f\x71\xf3\xcf\xd3\xaf\xb2\xbc\xc7\xf5\x4b\xec\xd6\x72\xc8\x91\xdb\x66\x02\xec\xf3\x8d\xcc\xcc\x6d\x25\x30\xa5\xde\x9e\xd1\x49\x52\xde\x6f\x45\x9d\x2d\x89\xdb\xcf\xc4\x1d\x97\xc5\xed\x8b\x90\xdc\xd6\x98\x3d\xc1\xf8\x8e\xf1\x64\x1f\x80\xf4\x0b\x15\xaa\x40\x83\xef\xf7\xd5\x71\xf3\x9d\xb9\xc6\x24\xe4\x90\x50\x6d\x04\xd3\x6e\x66\x2b\xb0\xdc\xc5\x9d\x7e\xac\x64\xf6\xdb\x56\xea\x8b\x65\xe6\x19\xef\x11\x53\xb4\x91\x2b\xf0\x0b\x82\xea\xfc\x24\x55\xaf\x54\x88\x20\xda\x48\xa7\x9e\x49\x8a\xe8\x76\x6f\x42\x51\x97\x0c\x3f\xd0\xba\x8e\x49\x24\x09\x04\x92\x6b\xde\xbb\x4a\x48", 197, { 0xe0, 0x17, 0x3a, 0x13, 0x7d, 0xcc, 0xf3, 0x56, 0x2a, 0xf8, 0x56, 0x04, 0xdb, 0xcf, 0x6b, 0x4a } },
|
||||
{ "\xa4\x77\x52\xb0\xda\x4f\x08\x52\x36\x26\x41\xa1\xe6\xc2\x55\x7f\xf1\x8a\x53\x87\xbc\xe0\x55\xf7\xa9\x19\xef\x39\xda\x15\xc1\x0c\x13\x80\x2c\x53\xbe\xa4\x21\x7a\x07\xe8\x15\x81\x27\xe8\x11\xa7\xbf\x32\xe5\xb3\x5a\x9b\x7c\xe1\x15\x3d\x4b\x68\x5b\x0e\xe4\xa4\xc8\x1d\xa7\xe5\x2f\x6b\x97\xd4\xb7\x63\x4a\x7c\x20\xf7\xfa\xfc\x23\x59\xba\xc8\xf8\x53\xc2\x97\xf1\x44\xeb\xed\x44\xb8\x36\x45\xe6\xa2\x86\xda\x92\x38\x6e\x12\xe8\x6b\x25\x88\xb3\x02\x96\xb4\x43\x52\x94\x39\xf9\x9c\x2b\xcc\xe1\x03\x12\xbc\x79\x28\x3c\x21\x90\x64\x8d\xa5\x4a\xa1\xaa\xea\x40\xd6\xe9\x97\xc4\x1d\x68\x02\x42\x72\x39\x7b\xc2\x0a\xbb\x33\x89\x4d\x04\xc8\xdf\x72\x7a\x6e\xec\xb6\x81\xbb\xbc\x39\x4e\x0f\x62\x75\xda\x9d\x38\x5b\xf3\x1b\x44\x0c\x6c\x02\xb6\x31\x75\x82\x8d\xf7\x05\x06\x5a\xaa\x73\x5f\x1d\xed\x25\x8f\x4b\x93", 198, { 0x1b, 0xae, 0x3b, 0x86, 0xbc, 0x4d, 0x77, 0x02, 0x5a, 0x90, 0x72, 0xf2, 0x23, 0x18, 0x3b, 0x53 } },
|
||||
{ "\x5f\x35\xf1\x1e\x3d\x90\xf2\xd2\xbc\x31\x6c\x74\xf2\x42\x39\xa4\x5e\x6c\x92\xd4\x5a\x6a\xcd\xe4\xad\x28\x47\x5c\x3d\x97\x5c\x45\xe1\x10\x93\xa4\x55\x62\xd7\x94\x46\x7a\xe0\xff\x8e\xae\xb1\xf9\x7a\xa6\x3a\xb9\x46\xe7\x1d\x34\xaa\xfd\x8d\x57\x8d\x45\x53\xe1\xd8\x54\xeb\xdc\x66\x07\xcb\xb6\x17\x28\xc3\x00\x04\xba\x7f\xc2\xcc\xe2\x2a\x78\x0d\x72\x2d\xae\xef\x12\x15\x33\xda\x0d\x93\xfd\x47\xb6\x9c\x99\xb4\x75\xb1\x4c\xb1\x71\x39\xcc\x18\xdb\x0a\x94\x5a\xd5\x06\xe8\xf3\xfe\xe2\x65\xff\x9c\x02\x44\xe7\x64\x80\x2b\x34\xe8\x4c\xaf\x84\x9e\x6d\x6b\x99\x88\x66\xb6\x8f\x85\xb3\x03\x26\x34\x73\xda\x3d\x81\x1f\x6f\x60\xcd\x78\xdc\x78\xbe\x7f\x00\xa1\xa0\x9e\xf3\x19\x76\xe4\x25\x53\xa2\x6e\x12\x2b\x2c\xe1\xa3\x35\xb2\x13\x25\x2e\xed\xc9\xde\x94\xdb\x9b\x51\x51\x8e\xf4\x10\x93\x91\x36\x39\xb7\xf2\xfa", 199, { 0xa3, 0xff, 0x9e, 0xb2, 0xc4, 0x17, 0xce, 0xca, 0xb4, 0xda, 0x08, 0x92, 0xb0, 0x6b, 0xf7, 0x47 } },
|
||||
{ "\x8e\x63\xf1\x75\x35\xb3\x43\xf6\x08\x8a\x03\x8b\x9a\x0b\x36\xc4\xc8\x20\xf9\x8f\xf7\x37\x4a\x42\xef\x0d\x6f\xb8\x53\xa2\x06\x92\xbc\x4c\xaa\x9f\x72\xe8\x3f\x56\xc6\x2b\xdb\x80\x0f\x16\x51\xf2\x3f\x88\x5b\x78\x21\xed\x63\xce\x31\x15\xee\xc8\x17\x1f\xa6\x91\xc2\x94\x02\x10\x1e\x90\x94\x66\x71\x1a\xef\x94\x57\x95\x32\x3a\x58\x50\x36\x7a\x23\x38\x50\xfb\x6a\xad\xc3\x09\x59\x71\xc5\xda\xb3\xbd\x2c\xec\x8c\x6e\xb5\x89\x9d\x5c\xf1\x6c\x47\xcb\xcd\x7e\x27\xfb\xbc\xb9\x52\xda\x83\x2e\x2d\xda\xa0\x21\xec\xdd\x58\x52\xa5\x4b\x5c\x57\x10\x46\x17\x24\xdd\xf5\x97\xad\xb2\xfd\x15\xa2\xc0\x0e\x22\x59\x01\x99\x71\xca\x10\x9f\x3b\xb3\xa4\xa5\x52\xdc\xaa\xc4\xc6\x75\xff\xdd\x2e\x9b\xc7\xe9\x94\xf9\x6d\x6e\xff\x8b\x37\x0d\x9d\x7e\x84\x38\x8d\x34\xa5\x02\x47\x63\x56\x0f\xa9\x5d\xd8\xaa\x9e\x6a\xac\xf5\x6d\x51", 200, { 0x6c, 0x74, 0x72, 0x4a, 0xa1, 0xeb, 0x2f, 0xe2, 0x8e, 0x27, 0xa4, 0xd0, 0xba, 0xf2, 0xf5, 0x30 } },
|
||||
{ "\xed\x3b\x9c\xf6\x4b\x62\x7e\x1d\xa0\x7c\x60\x4d\x30\x7c\x4c\xcf\x82\x05\x78\xd6\xd5\x5e\x4e\xb8\x41\x82\x19\x5a\x6c\x55\x49\xab\xe5\xf0\x63\x47\x20\x1d\x88\x3b\x0e\xde\x9f\xe8\x59\x28\x22\x00\x39\xad\x82\xae\xf6\xd7\x38\xd2\xfa\xd0\x69\x6a\x92\xbe\x35\x0c\x41\x0c\x9d\x8f\xc1\xe4\x0e\xca\x97\xb9\x8e\x74\x51\x00\x82\x2a\x5f\xfe\x19\x90\x8c\xbc\x59\x8f\x17\x18\xc4\xbc\x72\xf6\xa6\xd8\x96\x93\xfe\x74\x01\xfa\x07\xad\x4d\x8f\x62\x15\x6e\xc8\xe1\xb2\x88\xfc\xf2\x20\x6b\x53\xa6\xd1\xac\xde\x5d\x75\x61\xc0\x10\x75\x78\x89\x3b\x98\xb4\xa3\x65\xc9\x46\xe5\x4d\xf0\x04\x45\xb3\xfc\x48\xaa\xc0\x02\x68\xe0\x12\x7f\xcd\xa5\x68\xb9\xb2\xe0\xe7\x44\x7b\xf1\x07\xa1\xaf\x23\x1d\x01\x94\x3e\x85\x27\x66\x3a\x6b\x6b\x33\x0e\x36\xda\x56\xa5\x93\x7b\x8e\xf2\x19\xad\xba\x1a\x9e\xac\x33\xd0\x16\x32\xc6\xbf\x22\x3a\x4c", 201, { 0xfc, 0xfb, 0x80, 0xef, 0x32, 0xd8, 0x1e, 0x33, 0xb0, 0x18, 0xbb, 0xfe, 0x11, 0x1f, 0x3a, 0x1f } },
|
||||
{ "\x20\x3d\xdf\xe8\x6b\x7e\x63\xdd\x2a\x0a\x4c\x0a\xe8\x1a\xa9\x02\x49\xa5\x73\xcc\x33\xaa\x0e\x34\x2a\x1c\xef\xcc\xba\x69\x57\x82\x0d\xa9\x3d\xdf\x9c\x60\x49\xda\x02\xf0\xfd\x57\xec\x9e\xee\x3f\x2d\x3e\x30\x3c\xee\x7e\xd1\x11\x03\xcd\x7b\x95\x58\xe6\x3d\x4a\x8a\xfd\x63\x9e\x92\x84\x81\xbd\x9c\x9a\x8f\x11\xf6\x11\x2e\x57\x24\x1a\x09\x5f\x10\x8f\x57\x60\x5e\xdd\x7c\xf5\xde\x8c\xcf\xb8\x1b\x6d\x77\x7a\x10\x5f\x6e\x1c\xfa\xbd\xa7\x0d\x49\x68\x4c\x60\xb0\x6c\x20\x88\x5b\x51\x04\xb4\x40\x01\x95\xc1\x8f\x51\xf2\xe0\x43\x2d\x9b\xc6\xda\x65\x75\x89\x21\x0e\xea\x1e\x29\x96\x2d\x6c\x56\x68\x9b\x0c\x95\x38\x3d\xa0\xad\xeb\x6a\xcd\xaf\x26\x89\xd6\x88\x72\xf5\xd6\xb5\x09\xf9\x9a\x15\x40\xfa\x19\xda\x90\xb4\x90\x99\x42\x9c\x3e\x82\xb7\x65\xb9\xa9\x51\x9f\xec\x82\x02\x79\xae\x6c\x6f\xa7\xff\x64\xc0\x5f\xe1\xda\x07", 202, { 0xc3, 0xe1, 0xb0, 0x79, 0x72, 0x94, 0x8c, 0x0f, 0xa0, 0xfa, 0xa3, 0x43, 0x20, 0xc6, 0x93, 0x87 } },
|
||||
{ "\x7d\xd1\xa0\x4a\xc6\xe0\xff\x2e\x49\x73\xe4\x42\xe1\x93\x38\xe6\xd8\xf2\x4d\xd7\xa6\x7b\x74\x58\xd7\x94\xab\xfd\x0a\xf3\x73\x17\x15\x1a\xc0\xb7\x46\x70\x0a\x61\xc5\xfe\x81\x4f\x15\xc3\x5d\x5e\xb9\xb4\x53\x99\xf3\x53\x23\x61\xa7\xea\x4e\x36\x5f\x64\xe6\x24\x68\xc9\x7d\xcc\x19\x54\x3f\x0e\x33\x33\x1c\x50\x64\xdb\x1d\x6e\xe6\x05\xd8\x3e\x44\x48\xff\xbe\x3d\x54\x12\xdc\xc1\xc8\x35\xe2\x18\xb1\x1c\x7d\x22\xa0\x22\x68\xb9\x67\x79\xba\x32\x6f\x7c\xc8\x03\xb9\x21\xb8\x7e\x6f\x8a\xa3\xbc\x26\xba\x66\x95\xb3\x64\x06\xcb\xa7\xdf\xbd\x46\x68\x37\xa5\x7a\xed\x5d\x00\xe4\x15\x7e\x22\xb4\xa5\x71\xfb\x85\xdd\x49\x45\x47\xb5\x0a\x46\x3e\xb9\x79\x42\x23\x7e\x0c\x81\x68\xc0\x01\xf8\x99\x19\x8b\x97\xde\x60\x26\x2f\x9d\x9c\x0c\xfd\x3c\xa4\xc0\xd7\x04\x54\xc7\xf1\x21\x6e\x76\x4c\xc6\x0a\xe7\xbd\x6d\xbb\x05\x96\x3c\x40\xc7", 203, { 0x8d, 0x91, 0xba, 0x03, 0xb1, 0xc8, 0xaa, 0x70, 0xf9, 0x6c, 0x1c, 0x25, 0xa2, 0x93, 0xa9, 0x8d } },
|
||||
{ "\xf3\x83\xe4\x7a\xa2\x62\x73\x36\xb0\x88\xd9\x72\x8c\x16\x58\xb4\xdb\xa1\x65\x61\xd7\x56\x20\xb2\x64\x39\x6f\xc7\xb1\x86\xb6\xd6\x87\x38\x34\x7c\x32\xa7\xfd\x34\x08\x4c\x90\xe5\x9a\xa1\x14\x95\x77\x23\x34\x3c\x97\x79\x93\xb3\x6b\xaf\xee\xcb\x7f\x9b\xcd\x7a\xc8\x60\xe6\x31\x90\x10\x0e\x49\xfb\x6d\xdc\x9b\x35\xc8\xdc\x2e\x3a\x0b\x6d\x0b\x41\xd2\x38\x2d\xc6\xb3\x4d\x95\x32\x9e\xdc\x79\x2a\x60\x8c\x9c\x71\x42\x7b\xb9\x7b\xce\xd3\x19\x8f\xb1\x05\x44\x97\xbc\xa5\xd4\x87\x05\xe2\x65\x68\x2a\xa0\xa8\x00\xb5\x34\x97\x20\x9b\xbb\xc3\x8a\xdf\x17\xc8\x7c\x54\x88\xe3\xdd\x7f\xe3\x9a\x03\x9a\x71\x99\x1f\xb5\x66\x9d\x46\xf8\xfb\x89\x1c\x03\x2b\x96\x1f\x76\x08\xa8\x8d\x8c\xb7\xbb\xf3\xe2\x0e\x7c\x54\x56\xc8\xf4\xf2\x0b\x63\x5f\xbc\x88\x97\x1b\x53\x00\x72\xbc\xbb\xac\x14\x3c\x9b\x54\x05\x50\x30\xee\x2e\xd5\xd4\x5d\x7b\x69", 204, { 0xf3, 0x73, 0x23, 0x57, 0xe5, 0x6b, 0xc8, 0xaa, 0x91, 0xf1, 0x46, 0x79, 0x25, 0xaa, 0x4f, 0x9f } },
|
||||
{ "\x27\x5a\x0a\x17\xd7\x70\x10\x2a\x12\x21\x49\x22\x85\x26\x19\xc5\x0f\xd4\x44\x4c\x07\x9a\x47\xbe\x26\xa7\x51\x5b\x13\xa8\xe1\x2e\x8a\xaf\xfd\xc6\x28\x2f\x0c\xfe\xd5\x24\x51\xf7\xce\x50\x04\x27\x4d\x9f\x0e\x8b\xd8\xac\x62\xf8\x23\x5c\xf3\x8f\xa3\xa8\x55\x4f\xb1\x79\xf4\xc5\x56\xac\xeb\xde\xb9\x35\x82\xdd\x22\x5f\x47\x67\xaa\x31\xc7\xbb\x82\xed\xe9\x00\xdc\xb2\xe8\xb7\x79\x41\xeb\x50\xd0\xdc\x43\xd8\xd8\x4a\x40\xcf\x72\xf8\xb0\x18\x76\x39\xf5\x09\x59\xae\xc2\xa2\x78\xc1\x72\xdb\x03\x4b\x05\x16\x89\x56\xb7\xb4\x1b\xfc\x3f\xc4\x20\x6e\xa1\xd5\xb5\x11\xb0\xec\xbe\xc2\x24\x91\x8e\x3a\x53\x04\x2f\x8d\x90\x8d\x4e\xcd\x1d\xf1\xc6\xcb\xcd\x00\xc7\xfd\x3b\x4c\xa3\x7b\xa1\xf4\x35\x24\x56\x9e\xee\xdd\xe6\x83\x7d\xf9\xcf\xa3\x1a\xb5\xd6\x1a\x70\xda\x04\x8b\x25\x85\x41\xb8\x07\x03\x8b\x34\xd4\xd6\xd3\x2f\xa6\xd5\x74\x71\xf9", 205, { 0x12, 0xe3, 0xc8, 0xd7, 0x9f, 0xe5, 0x62, 0x5e, 0xc1, 0x04, 0xed, 0xd2, 0x54, 0xf5, 0x06, 0xd8 } },
|
||||
{ "\x6f\x51\x62\x5a\x10\x89\x45\xae\x9c\xda\x85\x1d\x18\x8f\x28\x99\x68\x27\x60\x0f\x33\x84\x40\x28\xe2\xcc\x8c\xbc\xc8\xe0\xa9\xd4\x5c\x77\xb3\x5a\xa1\xd6\xad\x5f\xa6\x2e\xd3\x09\x29\x92\x0c\x17\x57\x93\x7c\x13\xaf\x7a\x35\x13\x04\x21\x0d\x2b\xa1\x6e\x8a\x72\x86\x6d\xfa\xaf\xd1\x09\xa0\xa1\x38\x67\x08\xe8\xb3\xe0\x7c\x93\x37\x98\x8f\x47\x9c\xbf\xd6\x08\xa0\x64\xb7\xa7\x04\xf1\x59\xc8\xd4\x47\xbb\x8f\xc4\x77\xe0\xe7\xb6\x19\x28\x6f\x58\x4d\xbb\x01\xeb\x4c\x1e\xdf\x1e\xa9\xe7\x7c\x18\x2a\x8d\xe5\x95\x3d\x59\xca\x28\x19\x79\x2d\x9e\x72\x33\xa6\x83\xd8\x37\x50\xbe\xad\x0d\x54\x57\xc1\xad\x10\x5a\x8c\x2d\xe3\xd3\x07\x95\x97\xf8\x27\xce\x6c\x66\xf7\xb9\xbd\x84\x51\x5d\x51\x04\x38\x38\x41\x88\xd5\xb6\x81\x61\x0d\xbf\x0c\x72\xbb\x6b\xb0\x33\x8f\xd1\x73\xd1\x82\xfd\xa1\x73\xf5\xff\x73\x98\x65\x20\x5e\x9c\xcd\x30\xf5\x5a\x99", 206, { 0xa3, 0xaf, 0xd7, 0xe6, 0xa2, 0xce, 0x1a, 0x98, 0x7a, 0x71, 0xe1, 0xab, 0xf9, 0xce, 0x37, 0xb6 } },
|
||||
{ "\xfb\x7b\xea\x42\xda\x09\x8b\x8a\x65\x58\x9c\x56\x46\x2c\xc5\x23\x29\x5e\x33\x26\xcf\x84\x00\x04\x42\x3e\xb0\x2b\x23\x20\xd7\xcb\x1f\x37\xd9\x75\x80\x3a\xca\x4e\xe0\x4f\x73\xef\xf8\x76\x76\xdd\x96\x96\x89\xa0\xad\x22\xde\x82\x86\x68\xa3\xe6\x15\x76\xa5\x42\x66\xa9\x10\xba\x36\xd3\x51\x5a\x9e\x08\x1c\xf0\xea\x06\x89\x84\x88\x3e\x59\x75\x1c\x83\x57\x32\xb1\x4e\xda\x91\x09\xab\x67\xcf\x15\xc4\x73\x25\x80\x08\x45\x03\x65\xf8\xfa\xec\x22\x8e\xa3\xed\x44\x4a\x89\xbb\xa1\xda\x90\x68\x85\x65\xb9\xc2\x04\x74\xc1\x48\x6f\x7d\xe7\xca\xe1\x0e\xcb\x9c\xf9\x93\x72\x76\xa2\xc4\x66\xeb\x0d\xad\xfa\x84\xc0\x5b\xab\x79\xc8\x20\xa2\x0b\x0a\x84\x57\x81\xb8\xc8\x4f\xbc\xdf\x17\x05\x79\x1c\x4c\xe7\x23\x6f\x5a\x77\x53\x27\x5c\x92\xe5\xfd\x3a\xce\xb8\x3d\xf4\xfc\x01\x1f\x8e\xcd\x4c\x34\x99\x90\x11\xfc\x59\x19\xef\x94\x98\xbe\x88\x8c\x06\x7b", 207, { 0x35, 0xc8, 0x5d, 0xea, 0xdd, 0x9b, 0x4e, 0xe1, 0x1d, 0x35, 0x19, 0x7e, 0x3c, 0xe6, 0xb8, 0x29 } },
|
||||
{ "\xf8\xd7\x4b\x35\xf2\xdc\xab\x1b\x79\xa9\x55\x29\x39\x47\x48\xc6\x80\x28\xe3\x8e\xdc\xbd\x07\x2a\x51\x24\xea\x5a\x37\xff\x7b\x14\xae\x60\x6d\xc6\xbf\xe0\xe3\xb8\x11\xcf\xb6\x8d\x45\x85\x66\xe8\xee\xd7\x9a\x2c\x30\xa5\x55\x5b\xf4\x91\xb8\x20\xc5\xca\x6e\xe8\x4a\x06\xb7\x2a\x60\x8e\x15\xc8\xd4\x73\x8d\x8d\xba\xde\x9a\xd6\x6c\x85\xb4\x4e\x22\x3a\x77\xd2\x2b\x9d\x74\x73\xc6\xf2\x91\x99\x9f\x0d\x1d\x44\xe9\x6a\x74\x6e\x14\x59\x4b\x8d\x2c\x56\x99\x35\xce\x77\x23\xd9\xc7\xfe\xa2\xb1\x4a\x0e\x92\xb8\xce\x7b\x9a\xcd\x82\xba\x93\xf9\x6e\xf7\x36\xd0\x27\x46\x67\xf0\x2e\xf1\x18\xa7\xe7\xf0\xdb\xb1\x31\x76\x08\x1e\xa6\xa8\x87\x52\x70\x68\x3b\x26\xc6\x50\x0c\x2d\x02\xbb\x8e\x11\x61\xfd\x53\x1b\x56\xb2\xca\xd1\x8b\x34\xd2\xb9\x75\x26\xdf\x3c\x92\x2d\xc7\xa6\x42\xbf\x2a\x4a\x40\x13\x7c\xc2\xbb\x38\xb1\x54\x15\x42\x83\x71\x37\x9f\x63\x57", 208, { 0xdf, 0xbc, 0x18, 0xbe, 0xc2, 0x94, 0xd5, 0x70, 0x1c, 0xe7, 0x30, 0xe9, 0x86, 0xc7, 0x7f, 0x08 } },
|
||||
{ "\x8f\x87\xfa\xd6\xa7\x92\x5a\x2f\x63\x63\xc6\x17\xd7\x82\x1a\xdc\xc2\x48\xd8\x9f\xab\xf3\xd1\xbf\x97\xd9\x6d\x57\x64\xba\x97\xdd\xc6\x2e\x47\xeb\xdb\x3d\xad\x1a\x6c\x0d\xf7\x0a\xc2\xb6\xbf\x7f\x23\x32\x14\xa6\xe8\x70\x24\x75\x3c\x87\x83\x30\x73\x07\x1a\x07\x04\x6c\xaf\xdd\x25\xac\x0c\x23\x01\xf0\xcf\xe3\x99\x5f\xce\xd9\x34\x15\x24\xbb\x84\x32\xdc\x9a\x57\x0f\x39\x60\xf6\x8c\xa0\x79\x1e\x85\x23\x8f\x98\x63\xab\x6d\x77\xce\xc1\x05\xee\x80\xf9\x8d\xcb\x35\xfb\xc3\x94\xbf\x2f\x52\x3d\x35\x05\x4d\x83\x4b\xde\xd8\xe7\xbd\x9a\xe6\x4a\xe6\xbf\x1c\x22\x6d\x42\xd4\x56\x1e\xf6\x3f\xbc\xd7\x8e\xa2\x2c\x99\x50\xc1\x41\xbe\x59\x59\xac\x4a\x87\xc6\x34\x59\x06\xc5\x4e\xb8\x7a\x54\x54\x90\xc6\xb6\x65\x3d\x77\x92\xda\x3e\xd1\x3b\x60\x45\x74\x0b\xb7\x6d\xa9\xe8\x06\x8b\x4f\xe8\xd8\x9c\x5c\x11\xb7\x5e\x12\x39\x63\xfc\xc1\x0c\xaf\xe1\x32\x2c\xf9", 209, { 0xb0, 0xbf, 0x87, 0x74, 0x91, 0x48, 0xb8, 0x57, 0xf4, 0xbb, 0xfa, 0x00, 0xec, 0x90, 0x0a, 0x39 } },
|
||||
{ "\xae\xb7\x73\x44\x46\xcd\x54\xf4\x06\x6b\x5f\x25\x12\xea\xe3\xa8\xcb\x90\xad\x9a\x5c\xba\xef\xa3\x74\xa6\x3c\xc8\x0e\xda\xb0\xee\x6b\x35\x2d\xec\x22\x90\xc0\x4b\x4e\x11\x21\x9d\xe5\x0c\x59\x77\x28\x95\x7e\x0c\x36\xa6\x9a\x67\xbc\xe9\xaa\x44\xc7\x24\xc2\x8c\xba\x3f\x4e\x6c\x5b\xf2\x73\x11\x07\x0f\x93\x01\x06\x69\xef\x19\xf9\x60\x68\x1f\x70\x0a\x5e\x03\x98\x00\xb9\xb7\x11\xc2\x06\xa8\xde\xc8\xb9\xd7\x76\x26\x91\x99\xf7\xda\x19\xe7\x7a\xb6\x4a\x63\x81\xe4\x4e\xe8\x8d\x1b\x5f\xcc\xcd\x5d\xce\xb5\xf0\x6a\x20\x14\x1c\xc5\x52\x43\xf7\x60\x3e\x37\xe2\xe6\x16\xe2\x45\xa5\x0c\x28\x05\x17\x14\x7b\x12\x0b\xc1\x15\x1e\x75\x4c\xd1\x68\xce\xb4\xa7\xb6\x29\xff\xc2\x61\xd4\x9e\x40\x8a\xa7\xee\x85\x6b\xec\xdb\x3c\xc8\xeb\x9f\xec\x83\x10\xa8\x32\x4f\xbb\x98\xa1\x7d\xa4\x66\x33\xf2\xe9\xa2\x6a\x3a\xb6\xd5\x07\xb5\x90\x06\x66\xef\x3e\x59\x74\x0e\x54", 210, { 0x3f, 0x07, 0x92, 0x47, 0x77, 0x40, 0x22, 0x89, 0xaf, 0x63, 0xa4, 0x03, 0x20, 0xa2, 0x2a, 0x9e } },
|
||||
{ "\xd3\x4e\x64\x5d\x38\x78\x24\xa4\x15\xb7\x32\x9f\xda\x8c\x13\xf9\x1f\x4d\x04\x3b\x07\xe1\x26\x16\xc2\x17\xd6\x4f\x2c\xa4\x1b\x47\x93\xb7\x39\x26\x96\x3b\x62\xa4\x28\xa8\x8c\x74\xb4\x86\x5e\x4d\x5b\x80\x44\x95\x58\x21\xa2\xac\x85\x2d\x24\xd3\xf7\x9e\x34\xb8\xc3\x3a\x85\x9f\xe4\xcd\xcc\x2e\x35\x09\x8f\xd5\x98\xf6\x15\xd8\x39\x17\x7d\xfa\xed\x1b\xeb\xc8\xb4\x3c\xdd\x7f\x5d\x38\x9c\x9b\x49\xea\xcd\xfd\x47\x85\x27\xb7\x9f\x6c\x3f\x77\x2a\xb0\x7f\x8f\x9e\x26\x35\x9d\xe8\x24\xc7\xdc\xb2\xd9\x05\x05\x04\x46\x97\xe3\x06\xdd\x95\x72\xe3\xb4\x35\xb3\xca\x66\x9f\x0f\x0e\x86\xdd\x65\x6e\xc1\xee\xb2\x6e\x8f\xf9\x5c\xe4\x95\x9f\x1b\x8f\x9b\x69\x84\xe0\x25\x61\x34\xdd\xb0\xbc\x95\x1b\x8b\xb4\x50\xe9\x4f\x74\x4f\x8c\xfc\x2d\x6d\xa4\xb1\x46\xbd\xad\x07\xb0\x74\xa1\x0b\x57\x74\xbb\xd7\xb4\x76\x57\xcc\x7f\xd2\xf5\x6e\x82\xee\x5d\xdc\x89\x41\xdc\xea\x76", 211, { 0xb4, 0xe4, 0x99, 0x88, 0x69, 0xa4, 0xd3, 0x42, 0x48, 0xfd, 0x35, 0x33, 0xd4, 0xa3, 0x66, 0x48 } },
|
||||
{ "\x03\xac\xdd\x71\x73\x72\xc2\x3c\xc4\xe0\x6b\xa4\xa5\x7b\x07\x13\x6c\x77\x5d\x43\xde\xbe\xa5\x0d\x9d\x0f\x03\x5f\x2e\x43\xa1\x4c\xa6\xab\x67\x3e\xf1\x96\x5a\x47\xbf\xef\x8e\x94\x0c\x02\xc9\x02\x4a\x5f\xb6\xcb\x2c\xd7\xc3\x59\x11\xa3\x98\x3b\x0c\xa5\x33\x35\x8c\xc6\xa4\x71\xad\x7e\x62\xd4\x1a\x72\x49\x6c\x9c\x37\x31\x05\x44\x34\x2c\xdb\x31\xa6\x5b\x69\xff\xbe\x6d\x60\xcc\xe5\xb6\xb3\xe8\x1f\xe8\xcf\x18\x8d\x70\xe8\x87\x0c\x6f\x6f\x4a\xfc\x53\xa0\x8e\x1b\x12\x37\x61\x8f\x03\x42\x19\x02\x59\x12\x65\xe7\x3c\x4b\xee\xdc\x85\x1b\xa9\x28\x16\x87\xbc\x63\xd4\xe1\x0a\x35\x43\x56\x5d\x36\xbc\xa3\x2f\xf5\x4d\xe8\x15\x15\x2d\x95\xc9\x91\xda\x81\xd2\x1f\xd1\x19\xd2\xb2\xea\xb5\x6c\x1a\x4d\x06\xcf\xc7\x14\xac\xe4\xab\x7f\xe4\x10\x3d\xce\x5f\xa6\x99\xbf\x2d\xec\xc4\xa4\xd8\xc8\x0e\x20\x8e\x08\x90\x7e\x76\x4b\xd5\xad\x23\x8e\x95\xdc\x26\x57\x9d\xae\xbd", 212, { 0xba, 0xe8, 0x47, 0x79, 0xba, 0x43, 0xe2, 0x04, 0xf1, 0x5a, 0x99, 0xb4, 0x4d, 0xf6, 0x3b, 0x7c } },
|
||||
{ "\x78\xca\x1a\xaa\x80\x33\xe3\x1f\xc4\x67\xae\xd5\x05\xcb\xc5\x3c\xbe\x26\x67\xcd\x0d\x38\xc9\x7b\x3b\x84\xae\x48\xea\x2f\x9e\xf3\xda\x01\xc6\xce\x57\x88\x6b\xae\x43\x5b\x0c\xfd\xbc\x7c\x14\xe9\x69\xd7\x39\xbf\x66\xe7\x74\x52\xc9\x78\x9d\x95\xd1\x87\xa2\x49\xab\x45\x63\xcf\xe0\x3a\x2e\x1f\x5e\x87\xd2\xd1\x20\x44\x62\x59\x7d\x08\x88\x50\x0b\x86\x83\xed\x2d\x54\xbe\x92\x40\xc7\x0e\x83\x5e\xfb\x88\xb1\xcd\xef\xfd\xb5\x08\xcd\x14\xd8\x67\x46\x02\x4e\x6d\x1c\xe8\x84\xae\xb9\xc8\x8f\x5b\xfd\x25\xc3\x6c\x15\x37\x65\x68\x86\xc8\x78\xd4\x4a\xae\xb3\x36\x11\xe5\x94\xc4\xa8\x48\x8e\xae\x77\xec\x5e\x05\x24\x1a\x7c\x46\x56\xe6\xac\x87\x94\x70\xb3\x3d\x4b\xb7\x27\xa8\xee\x15\x60\xdc\x38\x5b\x8b\x6c\x8d\x89\xdd\xb4\x7e\x2a\xe3\xc3\x6c\x4a\xf8\xe3\x43\x15\xd1\xc7\x68\x0e\x32\x51\xae\xe8\xc3\xfd\x81\x05\xfd\xed\x25\x88\x3f\x91\x19\x19\xfd\xf2\x95\x35\x17\x9c", 213, { 0x36, 0x5a, 0x4c, 0xec, 0xc3, 0x99, 0x8e, 0x50, 0xdb, 0xee, 0x2e, 0xc0, 0x07, 0x66, 0x78, 0x82 } },
|
||||
{ "\x33\x2e\x48\x26\xaa\xc6\xb5\x5f\xb4\x64\xa5\x17\x12\xf1\x50\x87\xa6\x52\xd0\x5e\xbd\x82\x34\x69\x6f\x4a\xb4\xdd\x1f\xa0\xfe\x44\x1e\x9a\xaf\x02\x6c\x0d\xdd\x83\x9e\xc7\xd1\x04\xdb\x64\xd2\xfa\x00\xd1\x1c\x22\xe4\x5b\xf0\x26\xb5\x73\xc5\xe9\x81\x00\x9c\x70\xd1\x61\x71\x6c\x70\xfe\xcd\x68\x49\x89\x78\x8b\x6e\xd7\x4c\x0b\x35\x55\x26\x2f\x7d\x28\xf5\xfe\x0e\xe5\xf4\x89\x1e\xea\xf4\xd2\xf0\x57\xd2\x58\x97\xac\x09\x40\xd9\x01\x60\x21\x2f\xdc\xc4\x6c\xe8\xb2\x30\x77\x6c\xfd\xc8\x24\x9e\xf6\x06\x32\x5b\xf0\x0b\x20\x20\x51\x17\xb9\xc8\x2d\x14\x41\x72\x80\x4d\x3a\x81\x08\x3c\xd3\xbd\xbd\x80\xee\x96\xee\xed\xcd\x89\xfa\xbe\x58\x9c\xa7\xe5\x0d\x03\x22\x83\x84\xe5\x93\x74\x9e\x38\x5c\x01\x4a\xc8\xef\xb9\xf3\x57\x49\x59\x89\xdf\x0f\xe8\x2b\xf3\x43\xe0\x6e\x43\xa3\x86\x4d\x3e\x9e\x5b\xad\xd2\xf4\xab\x8b\x4f\xe9\x42\xc4\x69\x25\x3e\x80\x5c\x2b\x00\x3c\x2a\x74", 214, { 0x94, 0xb3, 0x23, 0x0b, 0x78, 0xb0, 0xe5, 0x34, 0x86, 0x5b, 0x43, 0xce, 0xc8, 0x6b, 0xc9, 0x2e } },
|
||||
{ "\x3c\x73\x00\x28\x30\xe9\xb7\x78\xf2\x94\x76\x9a\xe1\x27\x74\x62\x3d\x3c\xdb\x7a\xd3\x1d\xc8\x3e\xd1\x2e\x6f\x36\xb8\xfb\x5c\x31\x6f\xda\xd4\xfa\x73\x3d\x5a\xba\x2c\x96\x4d\xea\x5b\xe7\xae\xf2\xb0\xe5\x00\x63\x78\xc8\x48\xce\x74\xb2\x34\x3f\xc5\xb9\x58\x59\x03\x93\x93\x0f\x6c\xdd\x90\xfc\x39\x08\x69\x60\x0c\xe0\x65\xb8\x86\xba\xe2\xf9\xf6\x3a\x4e\x68\x2c\xbe\x4f\x19\x6b\x6b\x03\x02\x7c\xd2\x61\xbb\xdf\x3e\xbe\xd4\x1d\x9c\x6c\xd2\x39\x08\x7d\xc8\x45\xf0\xa5\x8f\x10\xe7\x3d\xa2\xfd\x08\x64\x98\xef\x05\x40\x3e\x60\xcb\x62\x50\x91\xd3\x48\xd4\xdc\x08\xfc\x14\x25\x50\xd9\x36\x6f\xba\x6d\x79\x8a\x42\x7a\x0e\xea\x43\x17\x91\x94\x7a\xf4\x22\x31\xb2\xba\x25\x45\x12\x91\x92\x79\xff\xbb\xf9\x14\xaf\x5d\x16\x88\x4c\x5e\x0c\x29\xc0\x68\x42\xf8\x23\x0c\xd7\x9e\xbf\x02\xc3\x74\xbc\x8e\x8b\xbf\x6d\xfd\xa0\xf9\x35\x4f\x55\x4a\x17\xef\x7c\x16\xda\x9d\x9c\xb0\xd5\x6c", 215, { 0xa5, 0xbf, 0x5d, 0x7b, 0xd6, 0x14, 0xfe, 0x55, 0x13, 0xa2, 0x41, 0x76, 0x5d, 0xa5, 0x45, 0x8d } },
|
||||
{ "\xd0\x2c\x5c\xe7\x3f\x51\xc7\x4f\x33\xad\x1b\x00\xd8\xc3\x58\xf2\x93\x60\x5f\x5a\xfd\x0c\x7d\x70\x7b\x9b\x98\x4c\x7b\xe3\xf4\xea\x4d\x87\xa3\x4c\x9b\xf2\x87\xbe\x87\x60\x05\x35\x60\x16\x48\xd1\x00\xb2\x2f\x82\xc4\x9d\xd4\xc6\x29\x9c\xba\x90\x00\x86\x92\x45\x4d\x10\xaa\xdf\xc2\xc4\xf3\x34\xd3\x10\xad\x51\x76\x7b\xb1\x00\x79\xf2\x5b\x6a\x7f\x41\x12\xd5\x98\x9d\x75\x8d\x7c\x5e\x23\xe1\x64\xc9\x27\x45\x86\x0b\xfe\x95\x2b\x43\x47\x79\x6e\xb6\x07\xe3\x93\x26\x95\xb5\x01\x3c\x28\x80\xdd\x22\xfb\x68\x45\x2d\x1a\x23\x26\xb8\xcd\x20\xbb\x0c\x9e\xc4\xa2\x7b\x07\xcf\x9c\x8c\xbd\xdd\xe1\x50\x93\x09\x1e\xd3\x0d\xac\x0d\xae\x82\x43\xae\xba\xec\x6f\x27\xdf\x50\x15\x35\x0a\xc4\xa5\x4e\x3d\x22\x78\x55\xc0\x48\x53\xf9\x75\x08\x09\xab\x49\xb3\x3c\x3a\xc6\x3d\x43\x0c\xc6\x0d\x28\xfb\x42\x64\xc8\xc9\x49\x67\x1d\x42\x0c\xca\x99\xed\x16\x1b\xa8\x6e\x98\xa8\x58\x7b\xe2\x0f\x15", 216, { 0x59, 0xfe, 0x50, 0x4c, 0xbb, 0x58, 0x09, 0xb1, 0x1b, 0xce, 0xbc, 0x3c, 0x1d, 0x12, 0xfc, 0x29 } },
|
||||
{ "\x79\xee\x60\x8d\xb2\x17\xf0\xb2\x35\xe7\xbd\xde\x4b\x0d\x79\x10\x91\x6d\x35\x54\xb7\x52\xab\x41\xd4\xbf\x28\x9c\x63\xe3\x14\x1b\xde\xaa\x1f\x43\xf5\x70\x0a\x72\x6b\xd0\x0f\xf9\x8e\x9b\xef\x61\x51\xe5\x96\xcf\x07\x39\x6c\x82\xbe\xec\x3a\x78\x36\x8f\xb7\x30\x7d\x7e\xaf\x8b\x28\x95\xcf\xcc\x2f\x02\x0f\xbe\x66\x36\xbc\xf5\x94\xf6\x21\x2c\x32\x8e\xd1\xce\xc1\x24\x94\x90\xc8\x2a\xec\x3b\x69\xed\x42\x87\x9f\x4b\xb2\x23\x17\x81\x70\xd2\xa7\x22\xd5\xaf\x6f\x24\x0a\x91\x8b\x15\x50\x89\x72\x6b\xe9\x88\xee\xf8\xa6\x1e\xb8\x7c\x0e\x5d\xaf\x55\x28\xdc\xb5\x51\xe6\xd7\x26\xa4\x2e\x74\xf6\xf5\x85\x20\x66\x92\x5a\x18\x63\xc4\xed\x04\x7b\x3e\xda\xbd\x7c\xaf\x46\x2f\xab\x77\xa5\x5a\x9e\x76\x25\x73\xb7\xff\xba\x27\x3d\xeb\xc7\xff\x18\xca\x66\xde\x29\x35\x54\xa8\x44\x3f\x7c\xfd\xcb\x0a\x1e\x23\xe8\x75\x9c\x02\x66\xf3\xe1\x48\x2d\x77\x6e\xad\x58\x8b\x02\x51\xf5\x80\xe6\x41\x58", 217, { 0x46, 0x60, 0x93, 0x1b, 0x8d, 0xd0, 0x21, 0x38, 0x27, 0xd0, 0x23, 0xfe, 0x9a, 0x06, 0xe0, 0x3f } },
|
||||
{ "\xc0\xd2\x18\x1c\x3f\x7f\xc2\xb7\x10\xca\x5c\xb9\x14\x82\x37\xa1\xcd\xce\xfc\x5c\x50\x3e\xe9\x5b\x59\x6c\x39\x4f\x79\x4e\xa2\x84\x6a\x1c\xf8\xd7\x83\xd8\xef\x56\x46\x7f\xfd\x72\x17\xca\x5e\xe3\x08\xa1\x31\x19\xcf\x1d\xc0\x5a\xd9\x38\xdd\x7c\x77\x14\x67\x41\x37\xe4\xec\x4a\x4e\x7b\x68\xba\x30\x6f\x2c\x68\x42\xea\xda\xc0\xa7\x0d\x8d\x37\x37\x00\x15\x68\x8e\x9a\x60\xd0\x40\xaa\xf4\x23\x2a\xe0\x98\x48\xe4\x5b\x13\xf8\x52\xd0\x0c\xee\x5a\x53\x10\xcc\xb0\xc6\xb2\x8a\xcc\xdb\xcd\x9b\xfd\xc7\xe5\x9e\x97\x85\xac\xbd\x48\xc3\xa0\xa6\x89\x6d\xd1\x24\x30\xd5\xc1\x59\x22\x7c\x64\x9a\x25\x80\x46\xe7\xd3\xa1\xcc\x05\xaa\xf1\x92\x3a\x41\x18\xf4\xa5\x95\x41\xa8\x37\x82\xa5\x88\x52\x4d\xb2\x6e\xfc\x5e\xd7\x39\xc0\x0b\xef\xec\x21\x8f\x47\xf5\xbc\x19\x4e\x8a\xf9\x01\xd8\x2f\x6d\x15\x0e\x55\xd0\x12\xf6\x1c\x96\x2e\x9b\x39\x2c\xd2\xd9\xf3\xd0\x65\xc7\x47\x0d\x44\xc1\x2c\xd2\xce\x10", 218, { 0xf3, 0xa4, 0xbf, 0xef, 0x5b, 0x96, 0x17, 0xce, 0x45, 0x37, 0xa1, 0x87, 0x6e, 0x17, 0x10, 0x65 } },
|
||||
{ "\xf1\x2e\x9b\x39\xc2\xab\xcc\xdf\x49\x44\x7d\x55\x70\x03\x57\xc4\x45\x3b\x43\xf5\xf7\x5f\x39\xbc\xfd\x7e\x36\x02\x56\x5c\x4c\x6d\xeb\x2e\xd3\xae\x10\xf1\xbd\x66\x29\x67\x07\xb6\x69\xaf\x4c\x62\xb6\x80\x74\xa1\xa9\x02\x89\x83\xb1\x49\xaa\xff\x57\x6e\x18\x98\x9c\x4c\x6e\xac\x7e\xd4\xed\x59\x99\x0e\xf5\x0c\xeb\xac\x90\xa7\xb0\x4c\x29\x4e\x6c\x4b\x5a\xcf\x07\x40\xe3\xac\x12\x1c\xb6\xc5\x27\xdc\x2e\xa6\x6f\xe8\x60\x6b\x3e\x0c\x8a\x4c\xd8\x10\xa9\xc9\x57\xf5\x26\x73\xa4\xcf\xb0\x54\xa3\x3a\x25\xfc\x6b\x7a\xa9\x29\xb2\x33\xda\x12\x48\xc1\x1a\x50\xba\x35\x0b\x6a\x17\xed\x19\xfb\xcf\xcf\x30\x82\xb6\x22\x8f\xc6\x28\x08\xb4\xe4\x47\x9c\x77\xf6\x60\xa4\x33\x62\x6c\xf3\x1f\xbc\xb2\x5e\xba\x59\x8a\x58\x65\x71\x3c\x2d\x0a\xf0\x06\xd8\xfa\xd9\x3c\x81\xd5\x57\x8a\x96\xa2\x62\x55\x84\xff\x0a\x40\x12\x72\x64\xcb\x5a\xdd\x0e\x15\x66\x10\x5f\xc2\x63\x79\x30\xf7\x84\xf6\x42\x82\x76\xcb", 219, { 0xcd, 0x28, 0x77, 0xaa, 0xac, 0x2a, 0xed, 0x44, 0x22, 0x6b, 0x47, 0x34, 0xb0, 0x26, 0xb4, 0xb3 } },
|
||||
{ "\x4a\x17\x7b\xaf\xa0\xb6\x26\x01\x80\x28\xb2\x18\xfa\xa7\xfe\xb7\x7c\x9d\x29\xa0\xfa\x85\xc6\x3f\xb7\xee\xbc\x87\xb3\x9e\xbd\xdb\xb1\xd3\x61\x22\xe4\xa5\xde\xfd\x35\x87\x66\x15\x34\xec\x1d\x8d\x98\x06\xb6\x97\x74\xa9\xa9\x22\xf9\x4e\x13\xb1\xe2\x34\x29\x47\x80\xa1\x5a\x7e\x62\x47\x01\xb8\xa0\xc1\xc4\x6c\xc4\x3c\x8c\xa2\x56\x33\x21\x7a\x03\x52\x60\xe6\x69\x7c\x1c\x77\x82\xe8\x8f\x55\xaa\x66\x7b\x49\x4e\xc0\xe2\xf4\x33\x3b\x5e\x23\x60\x3d\x1e\x3a\xaa\x08\x7d\xcc\xda\xa4\x40\x4d\x7c\xdb\x6c\xdf\x47\x5e\xc2\x48\x24\x06\xd9\x05\xdd\x34\xd6\x78\x63\x59\xc9\x3c\xbc\x91\xa7\x99\x87\x6a\xe0\x13\x2d\xc4\x9d\x1d\xa6\xd0\x98\xeb\xe5\x3a\x97\x65\xe1\x63\x86\x37\x41\xc7\x30\x05\xa4\x7e\x9a\xbc\x8a\xde\xfc\x04\xe2\x3d\x5d\xd1\x30\xd4\xc9\x19\x5a\xbf\x32\xa0\x10\x20\xe1\xee\xd7\x64\x97\x63\xb0\x9e\x44\x61\x69\x0f\x63\xa7\x7f\xc7\xf0\xbe\xae\x64\x07\x8b\x18\xf9\x1b\x05\x0d\x0b\xcf\x01", 220, { 0x95, 0x6d, 0xe2, 0x53, 0x57, 0x08, 0xe7, 0x97, 0x5e, 0xe4, 0x9d, 0xac, 0x5c, 0x77, 0xf2, 0xd4 } },
|
||||
{ "\x7d\xb5\x74\x2a\xf7\xeb\x20\x0c\x5d\xdb\x67\x4f\x27\x6f\xb9\x00\x50\xef\x58\x0b\xe0\xc4\xf3\xc5\x17\x57\xe4\xa6\x33\x18\x03\x14\xdf\x9b\x25\x5a\x38\xdc\x35\xb7\x7c\xa3\xec\x93\x51\x03\x30\xcd\xb0\xfc\x07\x2f\x6c\x40\x36\x03\x63\x13\x7a\xbf\x3f\x4b\x62\xdb\xe9\x77\xc7\xc3\x8c\x1c\xe9\xe8\x41\x1a\x28\xf1\x5c\x2e\x5c\x10\x52\x91\xd1\x6f\x46\xbd\xe2\xc8\x2f\x4f\x30\x14\xa6\x08\x80\x5b\x51\xed\x2f\xaa\xe8\x8f\x52\x23\xe1\x65\x6e\x2e\xbc\x55\xd0\xce\xed\x51\x8b\x0e\x61\x1e\x0c\x99\xae\x30\x5b\x69\xdc\xb2\xf0\x98\xca\xa2\x30\x52\x3f\x18\x83\xec\x8e\xa6\x12\x0d\xe5\xdb\x22\x0a\x32\xe2\x08\x50\xb1\x48\xc8\xfa\x17\xdb\x4e\x83\x54\xad\x48\x95\x09\x38\x9e\x00\x86\x9b\x8f\xc6\x7e\x03\x69\x53\x4a\x25\xe5\xca\xd6\xe7\x1d\x7a\x2c\x1e\x2a\x6f\x9b\x72\x5e\x25\x83\x5e\x1b\x58\xc0\x54\x4e\xf7\xb1\xfd\x8c\x36\xe4\x9e\xc7\xc2\x60\x96\xac\x10\x8e\x04\x9d\xcf\xc4\x85\x46\x7c\x6f\x1b\xde\x13\xdd", 221, { 0x6d, 0xbe, 0xd8, 0x8e, 0x62, 0x40, 0x88, 0xb8, 0xf7, 0x63, 0xda, 0xce, 0x3a, 0x5f, 0x47, 0x0f } },
|
||||
{ "\x29\xfc\xe3\xa5\x9b\x13\x7b\xb3\x22\x8c\xc0\xf4\x9d\x7e\x20\x9a\x93\x0d\xe1\x0c\xdd\x5c\x93\x6e\x61\x30\xa4\xc8\xf8\x22\x12\xd5\x71\x80\x3b\x6b\xaf\xc2\xd0\x81\xed\xa4\xe8\xe2\x22\xe4\x31\x6d\x80\x9a\x41\x06\x16\x2f\x0a\x1d\x95\xfb\x6c\xd9\x2f\x7f\xe5\xe0\x9b\x3c\x63\xc5\x35\x2e\x3a\x0f\x43\xe8\x31\xe2\x53\x4d\xb7\x4d\xc0\xe8\x33\x2f\x53\xe9\x79\xc6\x05\xbd\x58\xd6\xe2\x48\x50\x72\x0a\xc2\x61\x6a\xd2\x2b\xfe\x51\x07\x6c\x21\x29\x52\x0c\x78\xad\xb7\x8b\xbd\x3b\x38\x5f\x23\x5d\x96\x88\xec\xf3\x37\xd2\x17\xfe\x23\xa7\x37\x0b\x28\x8e\x5f\x3a\x1e\x44\x3a\xe9\x45\x75\x37\x02\xca\x17\xe1\xdf\x69\x64\x4c\xd5\x2c\x72\xab\x64\x51\x70\xff\xf9\x49\x7f\xea\x5d\xdd\x2a\xa2\xbe\x6b\x84\x01\x58\x4f\xdd\xb8\xc0\x5d\x20\xa4\xcd\x8a\xcc\x39\x23\xaa\x8d\x1b\x5d\x53\x76\xcb\xd6\xe1\xde\x7e\x15\x93\xd4\x0a\xd3\xd3\x40\xf9\xa9\x93\x97\xc0\x5a\xd3\x3a\x09\xbb\x3f\x6c\x2d\x3b\xf4\xee\xbe\x13\x63\x39", 222, { 0x19, 0x9e, 0x3f, 0xa3, 0xf4, 0x23, 0x12, 0xaa, 0x16, 0x04, 0xf8, 0xc9, 0x22, 0xd4, 0x39, 0x69 } },
|
||||
{ "\x3f\x0b\x4e\x57\xf7\xe5\xf0\x5f\xda\x6b\x3a\x8b\xa8\x10\x37\xf8\x12\x45\x90\xf9\x16\x5b\x2c\x17\x6c\x10\xef\xa9\x18\xb8\xa4\x0c\x20\x09\xf5\x80\x58\x83\x97\x9f\x59\x7a\x82\x7b\x90\xc2\x5e\x52\x72\xf5\xfa\xf0\xcd\x63\xf5\xa2\x3a\x97\x7f\xd2\xaf\x82\x3a\x44\x31\x47\x3a\xec\xa6\xa2\x2b\x69\xc8\xf6\x92\x22\x36\xf1\x2c\xfc\xa5\xde\x72\xb5\x33\x86\x3e\xe0\xdc\xc4\x87\x7d\x05\xa4\x48\x34\x36\x37\x80\x2e\xe5\xf6\x52\x91\x6d\xd0\x4c\x96\x1e\xd3\xc4\x48\x6d\x73\x5e\xda\x4c\x79\xab\xa5\x95\x8a\xec\xbe\x9f\x52\xf4\x31\xf3\x4e\x2b\xdc\x19\x34\xaf\xe9\x8b\xff\x94\xe9\xcb\x9a\x4c\x8a\x90\x28\x22\xf5\x1c\xee\xe0\xc6\xa9\xde\x91\xa9\x01\xc1\x61\x8d\x2d\x00\xa0\x88\x45\x0e\xe5\x47\x67\x75\x4f\x30\xc2\x7c\xe7\x16\xd2\x72\x21\x98\xa6\x9b\x82\x17\x5c\xb4\x5b\x51\xaf\x23\xb3\x9f\xa7\xc0\x43\xc7\x6f\x3a\x9a\x7f\x43\x27\x61\x7f\x88\xac\xb9\x41\xf5\xc5\xc0\x58\xef\x32\x33\x6a\xf3\xff\x2d\xcc\x2d\xae\x0e", 223, { 0xbc, 0xe6, 0x12, 0x5a, 0xda, 0xbc, 0x5a, 0x1b, 0x21, 0xa2, 0x7a, 0x18, 0x4b, 0x6a, 0x4b, 0xd2 } },
|
||||
{ "\xb8\x25\x02\x77\x2d\x99\x6b\x71\x64\x65\x09\xad\xea\x9e\x5e\xe6\x5f\xbf\x95\x63\xc9\xfb\x69\x98\x95\xb1\xb4\xec\x2c\xfe\x95\x96\x2e\x6c\x3c\xa0\x4e\xc7\x55\x0e\xca\x10\x0e\x18\x85\x8b\xc7\x92\xc2\xf3\x55\x6d\x7f\xce\xf3\x56\x6c\xdb\xc6\x7c\x87\xa7\x0c\x6f\x55\x3f\xe0\x24\xbe\xff\xac\x15\x86\x89\x2b\x85\x64\xd2\x19\xe1\xc1\x56\x7a\x42\x0e\x6b\x84\x0f\xc2\xb3\x2b\xc0\xef\xac\x47\xbd\x80\x62\x63\x64\x11\x43\x24\x2a\x6b\x13\x54\xd8\x9a\xf6\x8a\xf7\xad\xab\x78\x47\x0a\xd8\xd1\x68\x6b\x7f\xd5\x9c\x79\x90\x7a\xa4\x03\x99\x38\xc6\xdb\x99\x71\xf0\x4d\xf2\x7c\xf7\x3d\x7c\x4d\xf8\xdc\xb6\xc2\xdf\x07\x17\x8c\x06\x3c\x82\xb8\xf5\x39\xd9\xd9\x48\x33\xa9\xd4\xae\xb0\x03\x48\x0d\x01\x6a\x98\xc3\x60\xe8\x96\x08\xa2\x3b\xcd\x6f\x98\x2d\x6b\x8b\x08\x01\xc9\xae\x43\x09\x99\xcd\x63\x55\xab\x7f\x23\x85\x5c\x24\x5b\xc0\x9b\x23\x16\xbd\x99\x4b\x51\xfe\x0d\x5b\x53\x1d\x21\x9d\xa4\x3f\xfc\xad\xab\xa5\xed\x57", 224, { 0xcf, 0x7a, 0x97, 0xcb, 0x19, 0xd8, 0x74, 0x61, 0x6c, 0x4b, 0xe9, 0xa4, 0xa7, 0x52, 0x11, 0x02 } },
|
||||
{ "\xe7\x61\x30\x9e\xca\x25\x61\xd9\x2d\x37\x7a\xf9\x74\x80\x8a\xe5\x40\xc4\xf5\x06\xca\xed\x62\xde\xe3\x80\x45\xd3\x85\x31\x08\x0a\x14\x91\xd8\x6f\x37\xe5\x0b\xd0\x4e\x13\x29\x29\x8f\xb6\x9e\xfb\xc0\x50\xfa\xd5\x93\x9f\xe2\xf4\x99\x08\x97\x06\xe4\x30\x20\x0b\x3e\xaa\x17\x54\xff\xca\x0e\xae\x8f\x98\x9c\x98\x79\xe1\x07\xaf\x27\x67\x8f\x2b\x40\x38\x55\x82\x9b\x1c\xe7\x2a\xde\x27\x69\x7c\xb7\x6f\x61\xb4\xb7\xd8\x1e\x15\xc6\x0b\xc6\x29\x47\x85\xfb\x26\xc9\xcb\x29\x6c\x66\xbc\x6f\x2b\xbc\xff\x28\x22\x85\x9a\x15\x82\xd6\xa4\x29\xf1\xf1\x13\xf0\xaa\xc6\xaf\x9c\xc1\x0d\x28\xad\x84\xf9\x42\x3c\xfe\x99\x2e\xe5\x95\xd0\xf5\x4f\xd3\xef\x0d\x5a\x41\xec\x0e\xe3\x6f\x42\x7e\x36\x11\x64\xc8\x11\x44\xdf\x4c\x51\xee\x0b\x90\x3c\x42\x6d\x93\x6a\x63\xac\x42\x50\x20\x2e\x04\x6a\xde\x4f\x70\x05\x93\x3e\x1e\xa6\xee\x73\x9b\x1a\x95\xd0\x76\x1b\x86\x54\x77\x9c\x9e\x76\xf0\xb2\x38\x24\x2b\x1e\xee\x57\x02\x7b\x7b\x52", 225, { 0x73, 0x28, 0x7e, 0x73, 0x4a, 0x07, 0x8f, 0xf9, 0x54, 0x98, 0x66, 0x8b, 0xe6, 0x28, 0x69, 0x5a } },
|
||||
{ "\x8e\x01\xc1\x78\xf7\xf3\xe5\xc8\x6b\xab\x98\xf6\x2a\x40\x71\x27\xbd\xd1\x76\x48\x46\x71\xba\x0b\xf3\xaf\x20\x7f\x8d\xc0\x3d\x4a\x2d\x4b\x5c\x86\x0d\xd1\x9b\x36\x7c\xb7\x32\x64\xeb\xf2\xd4\xd8\x25\x4e\x2e\x76\x9c\x5b\x8c\x35\xde\xf4\x9b\xb8\x27\x6d\x49\x8a\x0f\x58\xc8\xfb\x64\xf4\xb2\x91\x12\x34\x47\x2d\x3f\x67\xd1\xbc\x74\x88\x28\x96\xf5\x24\x52\x76\x31\xe4\x42\x16\x54\xb6\xc1\x67\xfa\x9c\x6a\x6a\xff\x11\xcf\xae\x72\x13\xba\x66\xa8\xd2\x8e\x26\x6c\xf3\xcb\x3a\x54\x81\xb0\xa3\x2f\x71\xfa\xaf\x9a\xd0\xcb\x34\xb2\x8b\xa6\x69\xe3\xdb\x97\x60\xdf\x4b\x6f\x24\xab\x67\x2d\x6b\xd3\x03\x79\xf8\xbe\x25\x49\x90\x1c\x90\xa6\x96\x7b\xed\x89\x45\xf9\x98\xdf\x8a\x14\x05\xac\x7c\x9d\xce\x4c\x79\xcc\x5a\xd4\xde\x6c\x2b\x96\x62\x37\xc3\xc3\x10\x3c\x34\x2b\xdf\x7c\x43\x21\xef\x95\x38\x7a\x62\x96\x45\xb4\xd5\xf1\x90\x32\x7a\x8e\xdf\xa5\xd3\xfc\xdf\x87\x0d\xc2\x11\xc1\xf7\xd4\x52\x6d\x9d\x21\x05\xb5\x85\x49\xdf", 226, { 0xd2, 0x88, 0x52, 0x3d, 0x56, 0x8c, 0x3e, 0x43, 0xc1, 0x91, 0x26, 0x52, 0x1f, 0x00, 0x34, 0x9b } },
|
||||
{ "\xda\x85\x6c\x4e\x51\x3f\x1e\x87\x08\x3b\x76\x2b\xc6\x9f\x46\x95\xb0\x8d\x65\xc2\xe7\x19\x27\xde\x4f\xe6\xee\x67\x6b\x5c\xda\x00\x64\x88\x9c\xd4\x29\x8f\x68\xa5\xaf\xd0\x08\x70\x59\x96\x0e\xbf\x74\x76\x22\x8b\xd9\x4b\x79\xcb\xb5\xcc\x66\x9d\x66\xc7\x0a\x10\x7b\xfc\x28\x8c\xde\x99\x13\xdf\x0e\x4d\xc8\xe4\x84\x0a\x18\xd2\x37\x5c\xfe\x1e\x3b\x61\x0f\x0e\x85\x64\x0f\xdc\xc9\x1a\x9f\x83\x84\x78\x14\x28\x16\x2f\x64\x28\x07\xc6\x3a\xba\x6a\x52\x29\x41\x5e\xd3\xfc\x31\xb1\x2e\x2c\x9b\xa0\xc3\x6b\x56\xba\xaa\x5d\xcc\xe2\x8f\x66\x5e\x73\x27\x9e\x75\x7e\x4e\xe1\x26\x2e\xbf\x04\x81\x4d\x6f\x22\x77\xdf\x86\x14\x65\xec\xfb\xfe\x41\x5c\xca\x06\x60\xfa\xd5\x20\xe1\x9b\x55\x05\xba\x58\xfb\x43\x5d\xf6\xa7\x6d\x06\x67\xc4\x72\xa4\x6a\x3e\x0b\x61\x4d\x21\x4e\xd0\xd2\xcf\x60\xb2\x30\xdd\x47\x65\x30\x8c\xde\xea\x78\xdf\xe1\x91\xe5\x5d\x28\x43\x11\x65\xf1\x6c\xf4\x29\x56\x83\xa6\x49\xdd\x37\x42\x0c\x2e\x37\xe7\x3d\xdf", 227, { 0xcd, 0x4e, 0x87, 0xb7, 0x10, 0x56, 0x56, 0xa0, 0x13, 0xe5, 0xbd, 0x06, 0xe2, 0x8d, 0x82, 0xf9 } },
|
||||
{ "\x9e\xd8\xa0\x6c\xfa\xc3\x10\x42\xf8\x1f\x36\xfa\xad\xae\xe8\xa3\x83\x22\x1b\x38\xbe\xdc\x86\x31\xaa\xcf\xd6\x35\x63\x83\x87\xec\x40\x36\x66\xf3\xdd\x1d\xa0\xe9\xc4\xc8\x85\xa6\xb8\xa3\xdf\x8c\x9d\x98\xe9\xf5\x07\xd2\xee\xcb\x5d\x9d\x80\x37\xaa\x69\x51\x72\x00\xee\xb1\xb7\x89\x69\xa4\x59\x2b\x04\x9f\xf0\xd7\x53\xdf\xaf\x6f\xfa\x66\xd1\x51\x6d\x94\x32\x85\xd0\x5e\xfa\x7f\xfd\x2d\x74\x91\xa3\x55\xfd\xf0\x8b\x30\x17\x60\xf6\xd7\x9d\x7f\x23\x7c\x11\xac\xed\x67\x11\x92\x90\x8b\xe9\x54\x8c\xc4\x41\x57\xa2\xb0\xf7\xa6\xfb\x27\x08\x06\x68\x58\xa7\x97\xc4\x81\x70\x24\x76\x4a\xb6\x07\x13\xbf\xf8\xbc\x20\xe9\x73\x00\xf5\x08\xd1\xa5\xbc\x6e\xff\xf5\x99\xfa\x1c\xc1\xe4\x30\x8d\x05\x91\xf2\x2d\x39\xb1\xdd\xa2\x36\x11\x43\xcb\xc3\x00\xc0\x55\xbc\x2f\x7b\x6d\xde\xb1\xfb\x8f\x31\x21\xa3\x7d\x12\xe2\xcc\x4c\xdc\x81\x7d\x99\x33\x38\xc9\xd8\xed\x8c\xc6\xcc\x9c\x15\x25\x13\xbc\x5e\x73\xd9\x76\xe2\xeb\xad\x0f\x37\xf5\x70", 228, { 0x19, 0xfd, 0x74, 0x3f, 0xff, 0x64, 0x2f, 0xff, 0xfa, 0x16, 0xbb, 0xd2, 0x16, 0x92, 0x6c, 0x7b } },
|
||||
{ "\xf0\x47\x3f\x69\x52\xb8\x77\x76\x86\x6d\xa2\x5e\xde\x26\x1c\x41\x3b\x43\x2c\x30\x34\xa6\x43\xd9\xe0\xb5\xd2\x5b\x41\x7f\xc5\x38\x4d\xf6\x9f\x68\x9a\x5a\x33\x8a\xa5\xb7\xfc\x36\xbe\x85\x1a\x6d\x94\x6d\xe9\x32\x59\x2b\x40\x32\x91\x8e\x43\x9e\x7d\x9d\xe6\x1a\x1e\xd4\xfe\xcd\xe8\x8c\x05\x99\x05\x78\x6a\x65\x42\x4b\x93\x95\x9a\x77\x70\x9b\x5d\x11\xbd\xa7\xfd\xd0\xd4\x7a\x75\x35\x2c\x58\x57\xc4\x72\x1c\x70\x70\x42\x65\x19\x14\x82\xee\x1d\x1e\x5b\xfc\x42\x46\xd5\xf0\x76\x7c\x0f\xfc\x98\xe0\x17\xf2\xdf\xeb\x6c\x38\xeb\xab\x0d\xd8\x66\x2b\x3d\xb4\x56\xf1\xd6\xd7\x03\xa0\x47\xe6\x7f\xbe\x2c\xb5\xd7\x90\x88\xf6\xd5\x22\xa2\x0c\x6e\x63\x79\xfd\xcf\x6c\xe4\x86\xff\xe1\x4b\x49\x30\x70\xfc\x22\xa8\x77\x2b\x97\x47\xc2\x89\x6d\xb4\x71\x7f\x57\x28\xf8\x07\xca\xd6\x41\x27\xec\xf6\xec\x0c\xaa\x6d\xb6\xbf\xe9\x1b\xf7\x86\xd4\xc0\x45\xd9\x54\x8b\x37\xff\x9e\x41\x44\x46\xe5\x07\xc9\xdb\x31\xcc\x29\x4b\x48\x55\x0e\x97\xc8\xe6", 229, { 0x8d, 0xe4, 0xe9, 0x8c, 0x60, 0x20, 0x2e, 0x6e, 0x67, 0x30, 0xe5, 0x90, 0xee, 0x49, 0x57, 0x5d } },
|
||||
{ "\xce\xed\x56\x8a\xea\x09\xf1\x00\xb0\x28\x60\x42\x00\xa4\xca\xb2\x2b\x31\x64\xe4\xf7\xb2\x44\x02\xbf\xb9\x55\xe0\xb7\x9a\x63\x9d\x4e\x2a\x56\xf2\xac\x19\x7c\x1a\x5b\xe9\xff\x5e\x02\x8a\x75\x3c\x4b\x94\x96\x33\xe6\x20\x09\x2e\xa7\x44\x57\x8b\xcb\x28\x01\xc6\x58\xc9\xac\xc6\xa2\x4a\x7a\xc4\xe9\xf2\x75\xd4\x20\xc7\x25\x12\xc9\xc4\x41\x6a\xfb\xb9\x82\x03\x85\xc0\x92\x49\x2d\x57\x24\x95\x11\x1f\x1d\x7c\x2f\x30\xef\xb1\x00\x17\x07\x97\x3f\x6d\x5d\x67\xc7\x15\x28\xfb\x9a\x11\xb4\x35\xfe\x01\x4b\x0e\xc1\x3a\x50\x3f\x9e\x7f\x6c\x85\xb8\x5f\xdf\x95\x43\x2a\xf8\x9c\x42\x91\xa0\x71\x6a\xd9\x10\x5a\x26\xbc\xa3\x78\xb4\xdc\xc5\xd0\x6c\xe4\x0b\xf6\x21\x3e\x5d\x58\xa0\x6a\x4e\x24\x56\x02\x8c\xd7\x0e\x47\x73\x64\xd7\x66\xbc\xfd\x03\x4d\x52\x80\x4c\x25\x45\x81\x12\x6b\xd7\xf0\xc0\xae\xb4\x67\x4c\xe7\x3f\x13\xdc\x70\x08\x3c\x86\xa3\x5a\x72\x30\x10\xf0\x56\x97\x5a\xc7\x02\x6b\xae\x0e\x16\x96\xe1\x3a\x60\x9d\x26\x36\x27\x1f\x69", 230, { 0xe1, 0x2d, 0x4d, 0x4e, 0x25, 0xde, 0x0e, 0xf5, 0xcb, 0x99, 0x33, 0xe3, 0x45, 0x90, 0xf0, 0x1f } },
|
||||
{ "\xb8\x14\x7b\x4a\xaf\xbe\x8f\xb9\xd8\xd0\x9b\x2a\x70\xd9\x43\x75\x04\xb0\xb3\x4e\x64\x82\xdd\x5c\xb6\x7a\xde\xf7\xa6\x0b\x7e\x83\xbb\xdd\xd6\x64\xc5\x51\x0c\x9c\x72\xb3\x3a\x08\x01\xfb\x6d\x34\x0e\x40\xc9\xd6\x8b\xba\xca\xee\xcf\x72\xa5\x78\xc8\x88\xcd\xca\x4d\x21\x91\x90\x8e\xeb\xe2\x62\xad\x4e\x33\xff\x65\x30\x79\x29\xe8\x65\x52\x1c\xc7\xb2\x42\xac\x0b\x7c\x18\xfa\x61\x12\x6f\xd2\x71\x94\x50\xa5\x4f\x7e\xf5\x1e\x0a\xd5\xa8\x62\x63\xec\xca\xe9\x98\xd3\xf0\xf4\x5d\x5d\x28\xaa\xec\xcd\x59\xd3\x33\x1c\xc8\x30\x2c\xea\xb7\x74\x4b\xff\x28\xe3\x10\x7c\xbf\x86\xbc\xa2\xc5\x08\x20\x3e\x49\x31\x90\xb0\x61\xfc\xf7\x97\x8e\x56\x05\x1c\x3d\x76\x83\xd7\x6a\xd3\xc6\x61\x5f\xc7\x42\x77\x9b\xbe\x36\xc7\xcd\x1a\x85\x5b\xff\xa7\xa5\x9f\xd0\xb6\xb0\x10\xda\xd8\x98\x83\x32\x38\x78\x0f\x0d\x96\x05\x99\x7f\xdc\x23\xfa\x5f\x5e\x94\xcf\x47\xb3\xcb\xdc\xb8\x2a\xdf\x1d\x5a\xeb\x9b\x6b\x60\xac\xb2\xc8\x0a\x0c\x0f\x47\x44\x90\x4b\x9b\x6c", 231, { 0xfc, 0xbf, 0x92, 0xda, 0xc4, 0x1d, 0xb9, 0x19, 0x4f, 0x37, 0xa0, 0xbf, 0x95, 0xd0, 0x48, 0x08 } },
|
||||
{ "\x37\x38\x3a\x31\xbb\x9a\x2d\x97\x67\xf5\x77\x16\x90\x82\x1f\xe2\xb1\x3b\xdc\x46\x27\x15\x5d\x2a\x85\x4e\x32\xb3\x95\xdc\x5a\x09\xec\x05\x69\x34\x29\x0c\x56\x1f\xca\x09\xdf\xbf\xaa\xd2\x99\x4d\x1b\x15\x98\xaf\x9c\x88\xb6\xf5\x37\x37\x84\xfe\x7a\xfc\xcb\x3b\x0f\x0d\xbd\x8b\xfa\xaf\xbd\x46\x6f\x09\xc8\x56\x4e\x13\x7e\x7f\x3c\xad\xd1\xbe\x5f\xcc\x49\xcf\xb5\xcf\xf1\xc9\x12\xf0\xe1\xe5\xb4\xd6\x69\x5c\x84\x46\xd7\x6e\xec\xfa\xe6\x7e\x4f\x8a\xc3\x5a\x29\x87\xbd\x99\xc5\xa7\x88\x1e\x95\x1a\x2d\xb9\x31\xfb\x92\xec\xef\xe2\xa1\xca\x1b\x96\x18\xfb\xd3\xe0\xed\xdd\x82\x7a\x5c\xc5\xf7\x26\x8e\x63\x21\xdc\xe7\x43\x69\x1b\xed\x70\xac\x61\xd0\x33\xd4\xb6\x9a\xf9\x12\x62\xf4\x52\xb9\xbe\x92\x16\xba\x28\x3c\xa2\xb8\x10\x7a\x40\xc7\x2f\xdc\xa5\xc6\xd8\xe3\x93\x56\x66\x8f\x9f\x76\xd5\x86\x0d\xbd\x6d\xde\xd7\x33\x99\x87\xcd\xcb\xd6\x58\xd6\x81\xc7\xb4\x54\x0c\x65\xd9\xa5\x41\x53\xc5\xc6\x04\x4f\xc5\x13\xeb\xc5\x9b\x2a\x70\x7e\x4b\xed", 232, { 0xfb, 0xcb, 0x4a, 0x19, 0x4e, 0xcd, 0x8d, 0x1e, 0x33, 0xad, 0xf0, 0x88, 0x02, 0xf2, 0x49, 0xb6 } },
|
||||
{ "\xd3\x75\x82\xa5\x8a\xca\xa4\x44\x66\xd0\x70\xc3\x44\x41\x52\xaa\x6c\x91\x46\xae\x89\x5f\x64\x74\x45\x08\x0c\x74\x81\x56\xae\xf9\x2e\x56\x36\x44\xcb\x47\x13\xd0\x7b\xae\xe3\xb1\xc2\x87\xbd\x16\xdc\x96\x1a\xed\xba\xdb\x60\xa5\x99\x23\x0d\x0f\x41\xbb\x7c\x5e\xd8\x40\x57\x4d\x60\x92\x9a\x5f\xd4\xe7\x3f\x42\xda\xfb\x8c\x4d\x24\x65\xf5\x28\x69\x05\xae\x8b\xfc\x9a\xd2\x1f\x06\x70\x29\x80\x65\x36\x99\x64\x1f\xee\x2c\xd5\x84\xfd\xba\x9a\xe0\x62\x33\xb4\xda\x03\x8b\x04\x6d\x23\x42\x0a\x80\xf1\x8f\xc8\x23\x3a\x28\xc5\x68\x3d\xb1\x2d\xdc\x9f\xbf\x15\xa1\x75\x87\xdd\x29\x7f\x27\xae\x91\x75\x91\x23\x98\x78\x10\x05\x3a\xab\x78\x2e\xed\xdb\xee\x8e\x77\x59\x51\x4c\x6a\xe9\x44\x04\x3d\xd3\xda\x2f\x09\x16\xdc\xa0\xdd\xbc\xb9\x2b\xbe\x49\x0b\x60\x3e\x4d\xc2\x75\xb7\x19\xef\x42\x25\x8e\x2f\x65\x9d\x11\xb2\x85\x6e\x9a\xe7\xb4\xd3\xec\xc6\xee\x51\xdf\xb9\xbe\xb3\xd9\x28\x00\xa0\x5b\xa0\xc1\xd6\xb7\x9f\x42\x05\xe0\xfe\x1c\x4a\x5a\xfb\x7d\x46", 233, { 0x6f, 0xa3, 0x9b, 0x06, 0x9a, 0x45, 0xa7, 0x4c, 0x93, 0x2a, 0xae, 0x07, 0x2f, 0x79, 0x54, 0x7f } },
|
||||
{ "\x50\xe2\x90\xdb\xc4\x58\xfb\x83\xe0\x44\x82\x4c\x6c\x5a\xc9\x74\x59\x45\x36\x9c\x7a\x71\xf5\xac\x52\x72\x15\x44\x08\x14\xcf\xda\x77\x00\xe7\x75\x62\x07\x2c\x05\xc5\x0e\x19\x5c\x46\x96\x9e\xcd\xca\xe7\xf8\x60\x25\xd9\xbd\xaf\xe9\x3f\xf4\x60\x5f\xf0\x60\x3f\x94\x73\xde\xf6\x8a\x46\xe4\x6c\x90\xcb\x29\xb8\xac\xd0\x63\xc1\x34\xba\x2c\x74\x7c\x4d\xfe\xa0\xa9\x1a\x5d\x71\xa4\x85\x14\x87\x2a\x71\x97\xb2\x01\x8b\x87\x4c\x45\x30\x55\x33\xe1\xfc\xfe\x62\x19\xf0\xf4\x2c\x43\x3f\x1d\x14\x96\xb5\xf4\x4b\x1a\xc4\xce\xc7\xbf\x2d\x37\xfc\x8a\x48\x7b\x39\xea\xef\x40\xa2\x29\x0d\x50\xc6\xfe\xbe\x75\xdc\x3f\x23\x7d\x9f\xb3\xc6\x5d\xc3\x05\xa4\x72\x12\xd5\xdb\xe2\x28\xe9\xf1\x21\xc7\x81\xbe\x90\xd8\xc8\xf8\x40\xff\x66\x59\xd4\xd9\x32\x6f\x83\xd5\x05\x00\x3d\xac\xaa\x17\xe5\x7e\xf1\xaf\xbd\x8b\xe3\xfb\xe0\x8a\x0f\x50\xe8\xa9\x03\xb0\xaf\x22\xd7\xf4\x33\x77\xe3\x95\x93\x4a\x90\x17\x36\xdb\x4c\x12\x0b\x1e\x97\xde\xea\x78\x3b\xda\x19\x16\x98\x59", 234, { 0x10, 0x62, 0x10, 0x20, 0x9a, 0x5a, 0x01, 0xcb, 0x7e, 0x58, 0x93, 0xef, 0x8a, 0x77, 0xe5, 0xb3 } },
|
||||
{ "\xeb\xea\x1d\x2a\x84\x43\xd3\xc3\xb7\x08\x13\x09\x10\x91\x58\xbf\xed\x23\x2f\x88\xc7\x05\x4b\x9a\x8f\x43\xb5\x01\x33\xff\x20\x8d\x3f\x6e\x5a\x5a\xa0\x76\xdf\xfa\x85\xe2\x88\x41\x5e\x40\x61\xac\x06\x58\x97\x6e\xfd\x49\x90\x19\xce\x41\x15\xe6\x90\xd8\xaa\xa1\x87\x0a\xff\x33\xea\xcf\x7f\xcd\xbf\x59\x05\xaf\xe3\xea\xae\x92\x26\x4f\xc9\xb8\x92\xfc\xeb\x8e\xcc\xc5\x20\xfa\x94\x37\x3c\x47\x67\x91\x4f\xab\x44\x62\x36\x71\x8b\xc0\x4e\xc7\x00\x22\x44\x26\xef\xdb\x08\x59\x6a\x34\xe0\x2d\xae\x24\x99\xb4\xa4\xae\xd8\x35\x83\xd7\x8e\xb3\x92\x43\x8a\x18\x0b\x6b\x28\xff\x1b\x7d\x27\x1b\x07\xd1\x98\x46\x68\x03\xf3\x2a\x97\xb1\x44\x86\x23\xd2\x82\x1e\x7f\xb1\x00\x42\xb9\x86\xfd\xf8\x65\xaf\x56\xc8\x98\x90\x5b\x25\x10\x04\xbe\x73\x71\x7e\xa7\xb9\xaa\xc1\xe5\xe5\x76\x38\x40\xb6\xff\xf2\xea\x4a\x9d\x3e\x14\x44\xbb\xdf\x9c\x99\xda\xed\xe3\xf8\xaf\x48\xbd\xd4\x68\xb9\x82\x0f\x0d\xa6\x41\x44\x01\x72\x14\xb1\xa7\x6f\x8f\xbf\x21\x81\x52\x30\x33\x50\xbe", 235, { 0x58, 0xde, 0x89, 0x88, 0x29, 0xd3, 0x62, 0xe9, 0xc9, 0x41, 0x78, 0xc1, 0x0e, 0x4c, 0x32, 0xc6 } },
|
||||
{ "\xe4\x46\x29\xc4\x48\x89\x72\xd9\x5c\x32\xc8\x06\x5e\xe2\xb7\x1b\x18\x27\x15\x03\xc3\x1b\xfb\x33\x97\x29\x61\x3d\xf0\xef\x55\x81\x1e\x3f\xd8\x02\xc9\x40\x55\x56\xff\xb2\xbf\xb8\xdc\x4f\x45\x38\xd5\x4c\xb5\x11\xa1\xff\x6b\x1b\xc4\x9a\xf3\x57\xb9\x15\x43\xa8\xbb\x2a\x8e\xa1\x30\x7a\xc6\x79\xb3\xcd\xb1\x1b\xbc\x77\xa7\x5a\xee\xd5\xe5\x42\xfd\xf7\x91\x8a\x3a\x58\x4b\x25\xbd\xc8\x6c\xf7\x2e\x6b\xde\xa5\x30\xda\x98\x85\x6a\x67\xb4\xb5\x32\x7d\x2e\x47\xd8\x26\x3b\x9a\x8d\xa7\x44\xc4\xef\x46\x7e\x2b\x32\x2c\x27\x33\xec\x64\x5e\x11\x7c\x03\x9f\xbe\x18\x62\xdb\x08\x73\x87\x30\xc2\x07\xa2\x4a\x1c\x04\xb3\x55\x0d\xd5\x49\x9e\xec\x4b\x64\xc5\x1f\x68\x7c\xa1\xea\xca\x9b\xb0\x69\xb3\xa5\x39\x99\xb1\xb8\x00\x90\xee\xae\xa5\xcd\x16\xbf\x9a\xaa\xe0\x44\xbf\xee\x3c\x96\x9c\x7f\x17\x15\x3a\x34\xce\x44\x9e\xc9\x2d\x12\xe3\xec\x22\x34\xf3\x74\x02\xad\xe2\xb1\x77\x6f\xe7\xde\x06\x1b\xf7\xb3\x39\xe5\x00\x17\x6d\x93\xbf\xf3\x3a\xa4\x3e\x22\x7a\x8d\xee\x84", 236, { 0x74, 0xb2, 0x77, 0xc9, 0x12, 0x1c, 0x72, 0xf0, 0xb8, 0x7a, 0x7e, 0xee, 0xce, 0x93, 0x97, 0xe0 } },
|
||||
{ "\xf8\x1f\x5c\x32\xb7\x04\x93\xcb\xdc\x68\x0f\xed\x39\xb4\x59\xc0\x76\x75\x44\xac\xde\x5b\xc2\x2a\xc3\x5e\x63\xb8\x8f\xfb\x6c\xe6\x69\x9c\x90\x8e\x80\x16\x4e\x21\xf7\x4c\xe6\x1b\x6d\xf1\xf9\x98\x28\x6a\xbc\x01\xdd\xd1\xd8\xdf\x1e\x16\xe2\xd0\x60\x40\x72\x96\xa8\xd1\xe2\x4d\xd2\x48\xa5\xb5\x7e\xc0\x41\xad\x97\xb6\xea\xc1\x81\xe8\xbd\xda\xdf\x58\x95\x14\xfe\x70\x8e\xad\xe1\x3f\x14\x18\xe9\xe1\xa6\x31\x21\xfd\x2d\x8c\x24\x68\xf3\xe6\xab\xe8\x42\xbd\xb7\x13\x9a\xfc\x57\x55\x8d\xce\x17\x0f\x3b\x93\x05\xdd\x66\xf0\x61\xf0\x31\x01\xe0\x9a\x7a\xaa\x9d\xe9\xd0\x0b\x9d\x6a\x13\x11\xfd\x0f\xa7\x29\xba\x2b\x54\x10\x1d\x99\xbe\xc6\xc1\xfd\x7b\xa1\x42\x22\xd6\x7e\x84\x83\x20\x12\x9d\xe5\xad\x5e\x60\x21\x72\x41\x87\x00\x39\x27\x7c\x3e\x7e\xe0\xc4\xb1\xea\x8b\x09\x83\x69\xb1\xc2\x9b\xea\x6e\x81\x1b\xb2\xc9\xd8\x02\x5e\x25\xe9\xf0\x73\xd1\x89\x0a\xa3\xba\x11\xf4\x9f\x40\xc1\xfb\x93\x25\xd0\x55\x43\xa2\x14\x7f\xc0\x94\x4a\xc6\xc6\xd3\x03\xe2\xb5\xa4\x2c", 237, { 0x3d, 0xd8, 0x41, 0x6f, 0xd4, 0x1f, 0x87, 0xc7, 0x02, 0x20, 0x21, 0xd6, 0xeb, 0x2d, 0xd3, 0xc7 } },
|
||||
{ "\xbc\x2a\x44\x38\x51\x3a\xa4\xec\xae\x4b\x35\xc6\x1b\x8e\xd9\x0b\x54\x1c\xf8\x6c\xf2\xac\xb4\x54\xe9\xef\x34\xd1\x2a\x88\x1d\x1c\x69\xab\x1f\xc6\xf9\x51\xab\x81\xd3\x15\xc3\x89\xb5\xaf\xe9\xad\x67\x0a\x39\xfe\x19\x03\x93\x12\xe8\xc0\xf0\xf5\x7f\xab\xd6\xae\xda\x0a\xe6\x69\x26\x3d\x93\x46\xc4\x93\xed\xbd\x6d\xc8\x9b\xab\x6f\x1f\xe7\xfe\x16\x18\xf4\xfa\x26\xcf\x0a\x25\x84\xf1\x12\xd5\xf4\x5b\x1d\x54\xfc\x51\x1e\xad\xe8\x57\xb8\x16\xe7\xaf\x32\xf9\x53\x70\x88\xa1\x0e\x40\x9b\x7e\x07\xae\x88\x14\xdc\x2e\x15\x86\x9a\xb2\x47\xbb\x9f\xe1\x12\x2a\xa1\xf6\x28\x48\xc7\x38\xf3\x8b\xf5\x11\x9d\x19\x25\xce\x4c\x12\xf0\xf2\x6c\x77\x2d\x37\x24\xb5\xb0\x22\xea\xd2\x34\x42\x32\x33\x53\x05\x41\x07\xb1\x36\x21\x54\x39\x16\xad\x9c\x7f\x16\xcc\x2b\x45\x2f\xba\x00\x19\xdf\x82\x56\x1b\xc1\x88\xcd\xdd\xc7\x42\x3a\x63\x16\x07\x08\x49\x7d\x00\x49\x04\x93\x3b\x5d\x41\x6d\xde\x3d\x69\xf9\x78\x65\x46\xfb\x73\x5c\xbf\xa1\xa6\xe1\xbf\xc4\x07\xb4\x34\xbe\x7d\xfd\x34\xe2", 238, { 0xe4, 0xf0, 0xa4, 0xab, 0x6f, 0x2a, 0xdd, 0x87, 0x83, 0xbb, 0xc7, 0x5c, 0x71, 0x24, 0x8f, 0x1b } },
|
||||
{ "\xd4\x5d\x39\x9c\xca\x90\x8d\x26\x46\xbc\xc1\xe4\xa8\x58\x57\x5e\x3b\xbc\x7f\xd7\xc7\x41\xfe\x8e\x44\x14\x2b\x91\xa9\x9c\x14\x38\xe1\x85\xbd\x45\xdf\x69\x88\x96\xc9\x1b\xb0\x84\x4f\x8f\xef\xdc\x1f\x69\x40\x78\x71\x20\xbf\x79\xbd\xcf\xac\x22\x8d\x98\x8e\x54\x6c\xb5\x74\xa2\xfe\x1d\x57\x10\x29\xcf\x9b\x6d\x71\xbd\xb4\x4a\x62\x58\xe5\x96\x26\xb4\x24\xd7\x36\x58\x1a\x07\x2d\xa5\x46\x09\xb8\xe1\x41\xc6\xaa\xde\x1c\xe9\x2c\x4b\xe5\x33\x12\x97\x49\x7b\x48\x7d\x53\x46\x6b\x31\x53\xff\x74\x25\xda\xd3\x8f\x78\xe1\x2b\x0a\xfc\x09\xc7\x69\xe2\xfc\x74\x96\x04\xf3\x69\x35\xcf\x52\x44\x16\xcb\x6e\x9c\xc4\xc9\x6e\x42\x3a\xa8\x4f\x19\xb5\xc3\x01\x8f\xa5\xfa\xaf\xb7\xbd\x5c\x1c\x05\x29\x6e\x29\xa5\xdf\x1b\x73\x78\x0f\x37\x19\xac\xb4\xb1\x9b\xf6\x4c\x55\xdd\x6f\xa4\x3c\x4b\x08\xcd\xd1\x17\xab\x2b\x80\x9e\xf0\xab\xfc\xe9\x79\x14\x2d\x50\xeb\x77\xb5\x38\x89\xc1\x1e\xfc\x6e\x6f\xa2\xe9\x67\x60\x95\x64\x6b\xc6\x73\x27\xb8\x36\x82\xa8\x8b\xe0\x24\x9a\x7b\xd8\xbb\x8c", 239, { 0x70, 0xdd, 0xb0, 0x46, 0x25, 0x38, 0xe4, 0xdd, 0x2a, 0x78, 0x64, 0xf0, 0x7b, 0xdc, 0x71, 0xa8 } },
|
||||
{ "\x72\x92\x38\xb0\x49\x6d\x43\xb7\xff\x66\x01\xd7\x96\xed\x84\xee\x8b\xd4\xd5\xc0\xf0\x64\x96\x5d\x27\x8a\x57\x9e\x3d\x2f\x78\xcd\xe0\xa5\xb6\x64\xff\x3d\x53\xee\xfc\xf5\xe6\x0a\x90\x4e\xbc\x8f\x3c\x3c\xea\xc9\x68\x37\xf1\xe0\x1a\x6f\x0c\x59\x54\x1c\x18\xb6\x0a\xf3\x20\x39\xbe\xb4\x85\xc7\xba\xe0\xc6\xe7\xea\x89\xf2\xe9\x53\x41\xa7\x23\x34\x34\xc5\x57\xb7\x52\xb5\x30\x54\xa4\x4f\xeb\xc3\xc0\x6d\x13\x9b\x58\x0a\x64\x8c\xec\x15\xd1\x35\xa0\xd8\xa2\xa3\x28\x00\xb5\x68\xdf\x48\xe4\x53\xf7\xc6\x87\xd1\xcb\xd2\x10\xdf\x51\x8f\xd5\xab\xab\x17\xeb\xc7\xdc\x47\x2d\x08\x98\x24\x5c\x01\x34\xe8\x60\x17\xbc\xad\xad\x41\x23\xb5\xc1\x5f\x95\x54\xc9\x33\xe9\x7a\x64\x00\x32\xe1\x7f\xbd\x74\xcf\x5f\xf6\x74\x88\xbd\x40\xa9\x54\x0b\x57\x4e\x28\xd5\xd6\x99\xf4\x43\x91\x05\x88\xbb\x92\xcc\x24\xa3\xaf\x71\x9a\x44\xc5\x79\x22\xca\x93\x39\xba\x67\x35\xcb\x38\x98\x3a\x1a\xee\x80\x65\x1d\xf8\x70\xfd\x21\x24\x88\xd1\x3e\x7f\x76\xcc\xeb\x78\x5d\x30\xae\xb3\xd2\x72\xec\x6d\x00", 240, { 0x77, 0xeb, 0x85, 0x90, 0xee, 0xde, 0x0a, 0x48, 0x59, 0x1f, 0xe2, 0xa5, 0xa9, 0x24, 0xea, 0x47 } },
|
||||
{ "\xb2\xde\x87\xeb\xd6\xa4\x31\xd1\x42\x74\x34\xad\x36\xeb\xdb\xd5\xc3\x84\x7f\xc3\x6b\x26\xae\xf0\x54\xd7\xf8\xdc\x29\x8f\x55\x2b\x8e\x27\x36\xe9\x3d\x70\x26\xee\xc2\x60\x1d\x5d\xcf\x68\x62\x46\x3d\xe1\x19\x6b\xa0\xa4\x70\x20\x85\xb8\x62\x4b\x4a\x26\x27\x8b\x9a\xe9\x39\x76\x85\x02\x02\xfa\x38\xa7\x27\xe4\x5d\x9b\x6b\x7f\x12\x99\x41\x55\x7e\xea\xf3\x11\x16\x16\x68\x84\x6b\xb7\x95\xc6\xac\x69\x83\x75\xc0\xdd\xf8\x19\xf8\x0d\xc5\xa8\x75\x8a\xac\x25\x16\xf1\xeb\x62\x1b\x7c\x69\xe7\x5b\xb4\x7c\xeb\x1e\x44\x55\x7f\x98\xe9\x09\xca\x03\x86\x3c\x6f\x57\x54\x6c\x0b\xa9\x37\xd7\xda\x1e\x2b\x0a\x79\x8a\xdd\x08\xc6\xa9\x56\x13\xe3\xf8\xd2\x1a\x5a\x31\xaf\xbe\x5a\x62\x81\x02\x20\xa9\x42\x8f\x71\x8e\xa7\xa2\x43\xfd\x8d\x93\x7c\xde\x92\x03\xd2\x53\xc1\xa0\xd1\x8d\x65\x97\xfb\x4b\xfe\x98\x09\xf1\x52\x7f\x50\x41\x9a\xa4\x3f\xb8\xdd\xc0\x04\x87\x5b\x7a\x4f\x2c\x1f\x8d\x2f\xad\xb8\x98\x18\x71\x01\x83\x05\xbb\x1b\x88\xba\xc3\x7c\xe5\x23\x73\x21\x1d\xd8\xbb\xdf\xe5\xc2\x91", 241, { 0x54, 0x10, 0x15, 0x52, 0x9c, 0x0e, 0x89, 0x84, 0xd4, 0x90, 0xfc, 0x2a, 0x5b, 0x5e, 0xf2, 0xed } },
|
||||
{ "\xd7\xb2\xd7\x89\x08\xdd\x01\x0c\xff\x6f\x1c\x38\xa9\x8f\x1e\x54\x49\x85\x52\xee\x84\x6a\xbd\x93\x9a\x6e\xa1\x2b\xaf\xc6\x1f\xee\x47\x30\xf7\x07\xd1\x24\x6c\xc3\x5a\x99\x43\x76\x62\x70\xe9\xeb\xcc\x81\xb4\x85\xee\x41\x42\xf6\xc9\x0d\xfe\x9b\x52\x15\xc1\x73\xef\xe7\x94\xbb\xfd\x97\x94\x27\x8e\x89\xee\xbe\x30\xdb\x0a\x52\xe8\x71\xc5\x9b\x3e\x9e\xd6\xf0\x72\x6b\x52\xa1\xcc\x88\x4a\xf3\x11\xcd\x92\xb9\x11\x6b\x9d\x8b\x5e\xb3\x84\xa6\x17\x83\x25\x60\xe2\x49\x68\x46\xf8\xb5\x9d\xd4\x59\xff\x01\xcf\x21\xd2\x60\x43\xf3\xd4\xd4\x15\x91\xd2\xab\x44\x8e\x8d\x67\xc0\x1a\x1b\xde\xe7\xfd\xfc\x82\x98\x9f\xba\xbb\xf6\x43\x3b\x70\xbb\x54\xa7\xa5\x36\xd8\xf0\x3e\xe2\x01\x02\xe2\xa5\xe2\x89\xfb\xa2\x3f\x59\xd9\xbb\x7d\x7f\xf6\xa6\xb8\xe2\x54\xaa\xf3\x94\x03\xf7\x6a\xbb\xbf\xa0\x04\x16\xb5\x36\xe5\x2e\x66\x02\x1f\x1c\xa5\xde\x88\xf1\xba\xb0\xa6\xc5\xa9\x84\xc7\x5f\x8d\x45\x2e\x7e\x1d\x18\x67\xc2\x50\x56\xbc\x3a\x1d\x24\xc0\x8b\x5c\xb0\x08\xb9\xc8\x09\xfa\x95\x25\x9b\xbd\xc3", 242, { 0x58, 0x95, 0xff, 0xfc, 0x90, 0xfc, 0xfe, 0x6c, 0x68, 0xf7, 0x0c, 0x90, 0x74, 0x06, 0x60, 0xaa } },
|
||||
{ "\x7e\x46\x50\x67\x88\x1b\xb7\x6c\x23\xb3\x4f\x70\xfe\x2b\x43\x4f\x59\xbf\x17\x4b\xe6\x02\x61\xd5\xc9\xb7\x98\xfb\xbf\x50\x05\x6d\x5a\x00\xd6\x2d\x6a\x7f\x51\xd3\x78\x5a\x26\x7a\x6c\xf4\xdd\x4b\x4e\x1d\x6e\xa3\x29\x4c\xef\xe4\x0b\x7c\x68\xd5\x2a\xa1\xc2\xb7\x21\xc6\xde\xe5\x57\xc5\xc3\x26\x81\xa2\xef\x93\x3d\x84\xce\x1f\xdf\x50\x49\xc8\x49\xe3\x75\x59\xf3\xec\x6c\xd9\x0b\x65\x39\x94\xb6\xac\xed\xc3\x74\x42\xce\xda\xa1\x1e\xaf\x6f\x17\xaf\x5b\xc2\xf1\x6d\x2b\xed\x6b\x1b\xb7\xa9\xe5\x9b\xa9\xba\x06\x6d\xad\xf8\xfd\xc6\x84\xfc\xe3\x49\x38\x63\x3d\x64\x6a\xc2\x9d\x4a\xc7\x26\x67\x88\x99\x46\xb1\x46\x7a\x48\x44\x1d\x23\x2c\xc0\x8f\x62\xd9\xdb\x27\x2a\xc2\xc9\x2e\xc4\x35\xb8\x07\x24\x40\x73\x28\x56\x40\x26\xb5\x17\x07\x41\xbb\x80\xa9\x75\x05\xdd\xe3\xdb\x9f\x9c\x29\x34\xe5\x61\x4b\x4b\x46\x37\xc3\x77\x9b\xe0\x9d\x3c\x1e\x4d\x03\x11\x08\x29\x64\x3d\xcb\x8f\x41\xdb\xe9\xdd\x94\xfc\x6f\xa0\xdd\xeb\x12\xae\xca\x8b\xe4\x53\x82\xdd\xb3\xa3\x8e\x9e\xff\xef\x64\x0d\x95\x52", 243, { 0x55, 0x8a, 0xc2, 0x51, 0x47, 0xe1, 0xcc, 0x16, 0x28, 0xb4, 0x10, 0x71, 0x27, 0x29, 0xa8, 0xba } },
|
||||
{ "\x92\xcb\xcc\x6b\x83\xda\x5b\x25\xf1\xc8\xd6\xb1\xe8\xe5\xc3\x95\x73\xaf\x5d\xde\xe5\x4f\xe4\x71\xc5\x3c\x9f\x80\x57\xfe\x70\x18\xc3\x0d\x12\xd6\xe5\xd8\xf1\xba\xb0\xe1\xa5\x13\x3f\x05\x0d\x9a\x7a\xd9\x04\x9b\x61\x30\xc3\x4e\xf8\xba\xd3\x44\xcf\xc7\xac\xfd\x2d\x29\xef\x96\xd9\x36\x3d\x9f\x84\xec\xb2\x0b\xd6\x30\x02\x41\x13\x2f\x2e\x4f\x6a\xe5\xe2\x3e\xda\xbc\x6e\x80\xc1\x4c\x5f\x86\x03\x41\xba\x6e\xd3\x5a\xd4\xda\x21\x8e\xd1\xdc\xa0\x49\xb7\x0d\x73\xd4\x2e\xbd\x73\xd2\xd6\x44\x1f\xe6\x45\x77\x21\x72\x9b\x36\x79\x7b\xc4\x23\x48\xa8\x4a\x6d\x3b\x69\xd4\xca\x92\x35\x40\x83\xcc\xeb\x58\xa9\xf1\x5a\x33\x65\x7c\xdc\x2b\x6d\xe2\x1d\x76\x93\xc3\xf9\x63\x77\xac\x84\x33\x5d\x87\x23\x92\x19\xa0\xd7\xb0\x27\x54\x9a\x01\xd7\x58\xe2\x8d\xa5\xa3\x42\xf4\xa7\xf9\x30\x02\x1f\x16\xe1\xeb\x30\x73\x50\x23\xae\xb7\x5e\xdc\x0e\xbd\x14\x1d\x7c\x3e\x04\x7c\x0c\x1b\xcd\x78\x08\x4a\xbc\x75\x68\x5a\x8f\x54\x5f\xa4\x56\xae\x12\x10\x73\xae\x64\x81\xc0\x88\xec\xde\xcf\x9a\x08\xbe\x4c\x1d\x0b", 244, { 0x25, 0x5e, 0xd3, 0x6f, 0x90, 0x16, 0x46, 0xa9, 0xa0, 0x75, 0x89, 0xa0, 0xd2, 0x74, 0x1b, 0x84 } },
|
||||
{ "\xaf\x7f\x88\x91\x24\xee\x81\xf4\xf8\x20\x80\xd7\xa3\x7b\x03\xdf\xf8\x4f\x68\x82\x98\xec\x6a\xf7\xf7\xed\x3a\x4d\x08\x98\x39\x98\x88\x5d\x50\x46\xe4\x7c\xed\x8f\xc8\xc4\x9a\x0b\x46\x76\x3b\x5d\x9f\x48\xe4\x0d\xb0\x85\x55\x74\xfb\x51\x13\xd0\x51\x0b\x24\x77\x1a\xcb\x66\x29\x41\x0b\x8c\x7e\xbe\x61\xb6\x7e\xc1\x6a\xac\x4f\x78\xc3\xb8\x09\x7d\x31\x1d\xa6\xdf\xe0\x37\x15\xcb\xc9\x30\x6d\xd8\x2c\x5c\x3e\xec\x3d\x32\x04\xcd\xdb\xe8\xb5\x48\x7b\xaa\x7a\xf8\x23\x76\x7a\xb3\x93\x97\xd1\x97\x7e\xbb\x9f\xac\xf5\xb3\x3d\x36\xe5\xc8\x8b\x9a\xb7\xb4\x65\xea\x15\x44\x34\x0f\xcd\x88\xa0\x92\xce\xb3\x63\x07\x4e\x96\x39\x16\x0e\xb4\xf4\x27\xb5\x01\xab\xa9\x59\x3c\x12\x00\x1d\xe6\xe6\x09\xf4\xdd\x7f\x4b\x84\x9a\x87\xbb\x25\x04\xc9\x2b\x08\xee\x23\x51\x75\x34\x96\x70\x2c\x6d\x7c\xa5\xed\x4d\xd9\xd0\x13\x9a\xc9\x1d\x5c\xc9\x19\x2e\xc4\x35\xf2\xe7\x8e\xfb\xb1\xd5\x64\x74\xd2\x3c\x96\x50\x0a\xbb\x7e\x4b\x73\x9e\x04\x8f\xe2\xc0\x3e\xa6\x54\x1b\x2f\x1a\x87\xee\xb0\xac\xa6\x89\x6d\x2d\x1c\xb8", 245, { 0x5e, 0xd5, 0xdf, 0xa5, 0xd4, 0xe1, 0xeb, 0x5b, 0x7e, 0x24, 0x12, 0xa1, 0xd3, 0x55, 0xba, 0x11 } },
|
||||
{ "\x06\xfb\x8a\xca\x55\x1c\xd3\x3d\xcf\xf0\x54\x07\x03\x96\x31\x83\x40\xde\xcb\xf7\x54\xe6\x4e\xbe\x6e\x53\x66\x17\x25\x2e\x11\x88\x92\x58\x8f\xf0\x97\xab\x77\x28\x43\xaf\xe4\x55\x4e\xf6\xcc\xce\xbf\x15\x70\xa4\xad\x3f\xef\xd2\x21\x7f\xf6\x02\x1b\x92\x92\xfa\xac\x5e\x26\xa1\x40\x13\x78\xb2\xfe\xdd\xe5\xfc\x48\x43\xb5\x53\x5d\x1f\x89\x17\x1e\x3a\xf1\x5e\xee\x83\x1a\xc1\xb2\xec\xa5\xc0\xf7\xe2\x92\xd3\x33\x67\x5b\x0e\x24\xcd\x1d\x6f\x55\x10\xf1\xc7\xbf\xd1\x5a\x43\x8c\xeb\xd6\x97\xf7\xb4\x97\xc6\x4f\xd2\x4c\x90\x19\xb7\x18\x77\x55\xba\xa4\x70\xd9\xd3\x50\x23\xda\xf3\x84\xdf\x8a\xfe\x25\x1e\xdb\x66\x24\xaf\x61\x65\x30\x86\x55\xd7\x8b\x1c\xb5\xb1\xfa\x84\x89\x22\xd6\x0c\x41\x44\x40\x8c\x3b\x7f\x72\x4e\x60\x7b\x30\x99\xee\xbf\x5c\xdc\x50\xeb\xa9\x74\x29\x8e\x68\x1a\x6f\xa5\x7e\xec\xb4\xb1\x77\x16\x81\x73\xb3\x1d\xdb\x47\xbe\xc8\xe7\x1a\xbe\xab\xa9\x0a\x05\x51\xe8\x99\xc7\x05\x2e\x8c\xe5\x3d\xeb\x66\xe7\xa4\xb9\x7c\x09\xc3\xbb\xb5\x6c\x4b\x1e\xe0\x6d\x01\xc1\xb2\x13\x46\xf1\x5a", 246, { 0xf1, 0x29, 0xb7, 0xfb, 0x81, 0x56, 0xef, 0x46, 0xb7, 0x0b, 0xc5, 0xc2, 0xbe, 0xbe, 0xb5, 0x5b } },
|
||||
{ "\xa2\x42\x4d\xc3\x4c\xad\xc9\x66\x07\x39\xce\xc9\x7a\x9f\x7d\x97\x11\x45\x14\x5d\x30\x89\x6a\xdf\x83\xad\x94\x15\x74\x5f\xaa\xc5\xb6\xe3\xa3\xbe\xfe\xdf\x5d\xae\xd2\xc3\xba\xa1\x7a\xd3\xe4\x16\x12\xd2\xb0\xbf\xc1\x4c\x20\xd6\x04\x81\x03\x17\x24\xe9\xb7\x5e\xc6\x68\x0f\xdd\xa1\x10\x4f\xf9\x4a\x8d\x54\xc2\x2b\x31\xd1\x0d\x92\x9d\xb3\x30\xe5\x08\xa6\x5a\xf4\x2f\xb1\x8c\x67\xd9\xfd\x38\x56\x06\xb3\x74\xf7\xb4\x03\xdb\x72\x4d\x40\x01\xd1\xb0\x28\x90\x13\xda\x42\x04\x60\x31\x60\xff\x56\x6d\x44\x49\x81\x23\x5f\x68\xea\xf0\xb4\xd8\xc6\x3e\xdc\xe8\x4f\xb6\x22\x31\xb0\x42\xce\xb3\x1a\xbd\x7f\x8d\xf4\x3a\xb1\x59\x2f\xee\x5f\x22\xb7\xbb\xc2\x02\x05\x59\x37\x5d\xd1\x23\x3e\xb4\xe5\x7c\x9e\x26\x0d\xdc\xa7\x8a\x2b\x7b\x90\x21\x67\x98\xfe\xfb\x83\x66\xa6\xe9\x4c\x94\x09\x1b\x2c\x77\x5e\x55\xdd\xd7\x8e\xd2\x38\x53\x59\xb5\x2c\x71\x96\x28\xca\x46\x97\x14\x7c\xbe\xaa\x7b\x56\x89\xbc\x75\x84\xa3\x19\xc5\xe3\x7d\x4f\x17\xad\xcd\x30\xd8\x4c\xef\xf5\xb2\x4f\xf6\x7f\xa3\x7a\x54\xb9\xb9\xf7\x21\x1a", 247, { 0xca, 0x55, 0x81, 0x7c, 0x31, 0x59, 0x07, 0x16, 0xf7, 0xce, 0x7f, 0x9d, 0xf9, 0xbc, 0x6d, 0xb1 } },
|
||||
{ "\x6c\xab\x0b\x47\x97\xa4\xdb\xd5\x15\xae\xa0\x2c\xf4\x05\x7a\x87\x59\x24\x05\x17\xf0\xbc\x5f\x47\x0d\xc0\xd8\x1b\x64\x9d\x35\xb2\x61\x87\xa1\xea\x25\xef\x31\x22\x1e\x11\x12\x1a\x42\xa9\x52\xf7\xe8\xc5\x47\x64\x43\xb6\x9f\xd2\x7b\x20\x06\xdf\x6a\x31\x6e\xd5\xf0\xee\xfe\x49\xf3\xa9\x99\xe4\xf6\x8f\x09\x3e\x55\x5e\xc8\xe6\x1a\x33\x6b\x7e\x7f\x81\xac\x03\x01\x1e\x12\x2b\x1e\x77\x3f\xe7\xab\xe4\xd5\x08\xd4\x16\x06\xfe\xb0\xad\xb8\xbb\x7f\xe6\x51\xb5\x84\x72\x24\x0b\x79\x62\x77\xbf\xb4\x3d\x30\x21\xd4\x34\x1c\x4d\x27\x6d\xdc\xcb\x9c\x7b\x6d\x54\x5f\xef\x52\xb4\x17\x08\x60\xcb\xb8\x85\x26\xad\x05\x9b\xf7\xe9\xa6\x03\x95\xe7\xe1\x2a\x7b\x6a\xf8\x8c\xc7\x36\x1f\x1b\xc2\xcb\x19\xd9\x0d\x4f\x6e\x85\x6b\x89\x4b\x71\x25\x09\xf6\x72\x1e\x66\xec\xf2\x73\xa0\x98\x20\xce\xa4\xb2\x46\x48\xed\x32\x3a\xf8\x47\xf0\xee\x1d\xae\xda\x23\xe3\x56\xd1\x3a\xd6\xc4\x20\x2b\xe0\x19\x99\x8e\x00\x6f\x4e\xd7\x8a\x5c\xe9\x9f\x14\x94\xa9\x1d\x04\xab\xf9\xb3\xb4\xf7\xaf\xa5\x3f\x93\xde\xe4\xeb\x81\x58\x09\x33\xe7", 248, { 0x1c, 0x9e, 0x80, 0x30, 0x66, 0x3c, 0xf5, 0x9d, 0x8e, 0x03, 0x83, 0xcf, 0x5c, 0x89, 0x97, 0x74 } },
|
||||
{ "\xc3\x5d\x6f\x7a\x56\x15\x22\xf8\x31\x9b\xe0\xcf\x57\x07\xda\xdb\x49\xac\x08\x4d\x3f\xcf\xf1\xa7\x05\x73\x1a\xe3\x71\x50\x09\xb3\x7d\xe1\xf4\xe4\x05\x9c\x0b\xdc\x1e\x3d\x5f\x42\x10\x3c\x6d\xbc\xf2\x5d\x4b\xd3\xe1\x66\x6e\xf4\xdc\xea\x16\x90\x3f\x44\x56\x62\xda\xa0\xc3\xd0\xae\x33\xb9\x6b\x43\x8a\x45\x91\xa9\x00\xb2\x32\x09\x4a\xb3\xaf\xe6\x2c\x2a\xde\xf6\x4e\x93\x2a\x97\x29\x10\xd8\xf0\x1c\x11\x64\xa5\x9b\x9f\x0a\x36\x87\x46\x60\xf5\x98\x9d\x20\xa2\xf6\x73\x04\xa4\xe7\x98\xca\xe6\xa3\x45\x57\x4c\x44\x29\xf8\xd1\xd9\x10\xc3\x3f\x9a\x32\x1c\x89\x35\x16\x53\xc8\x47\x21\x6b\xd0\xe6\xbf\xf6\x6f\x5b\x2d\x1c\x42\xed\xe0\xba\x33\xd8\x95\xa6\x92\x5d\xf6\x11\xcf\xf3\xe6\x06\xd2\x9b\x69\x0f\xf7\x51\x33\xf6\xa9\x9e\xcc\xa9\x9a\x4b\x5c\x37\x9c\x30\x19\xf7\x1f\x2a\x49\xc7\x48\x2a\xf6\x72\xaa\x6a\x2e\x2b\xa3\xbb\xf4\x36\x55\xfb\xc7\xa6\x40\xa2\xcc\x41\x79\x7b\x9a\x7f\x89\x6f\xa2\xb1\xe5\x7c\x39\x3f\x05\xc5\x44\x0a\x22\xc4\x7f\xf0\x91\x9b\x6a\x6d\xb7\x87\xd0\x5e\xa8\x75\xf5\xe1\x61\xaf\x5b\x59\x9d", 249, { 0x41, 0x95, 0xad, 0xac, 0x33, 0xb1, 0xf3, 0x9e, 0xa2, 0x05, 0x82, 0x08, 0xb3, 0xc7, 0x1d, 0xbc } },
|
||||
{ "\xaf\x31\x8e\x57\x14\x59\xf1\xde\xb2\x14\xfd\x8e\xc4\x4d\xb8\x30\x3c\x7f\x59\xf0\x3b\x43\x03\xf7\x9d\x79\xaf\xa5\xab\x13\x29\x6c\xf4\x79\x31\x4c\x35\x9c\xc2\xe6\x75\x9b\x6f\x40\x2e\x0b\xe8\x14\xa5\xe7\x9c\xd5\x5b\x14\x79\x3f\x9c\x8e\xce\x99\x34\x35\x52\x8a\x41\x2e\x3e\x95\x24\xf7\x95\x33\x91\x0b\x84\x8c\xc6\x2e\xe3\xd1\xd9\x56\xdb\x39\x29\x36\xa2\x95\xf6\x68\x62\x92\x0d\x35\x39\x8b\x9c\x04\x59\x09\x24\x5e\x4e\xd8\x8c\x9a\x60\xc6\x51\x2a\x0e\xfb\xdb\x80\xbb\xf0\xeb\x9e\x65\x0e\x31\x39\x8f\xe3\xfb\x89\x41\x03\x07\xb0\x26\x79\x79\xc4\xd3\xe9\xe8\x7b\x27\x43\x92\x72\xcd\x26\xb0\x1a\xde\xcf\xe5\x3f\xa4\xbc\xcf\x36\x7a\xe1\xc0\xa3\xcf\x86\x87\xe4\x49\xbb\x67\x1e\x05\x79\x29\xe2\xfd\x57\x4d\x7b\x83\xe5\x5c\xd6\xea\xa9\x59\x0e\x43\xb4\x56\x94\x45\xdf\x22\xf8\x46\xa7\x20\x56\x66\xa2\x33\x5f\xcb\x9d\xd5\x03\x06\x55\x47\xb8\x94\xce\xe3\x6a\x81\x52\x8d\xff\x27\x09\x48\x85\x15\x32\xe4\xfb\x0b\xfc\xd5\xb9\x21\x03\x20\x7d\x06\x6a\x6e\x12\x66\x91\x43\x9e\x65\x73\x48\x89\x49\x9f\xc4\x06\x34\xd1\x29\x3f", 250, { 0xc2, 0x69, 0xc7, 0x4f, 0x4c, 0x81, 0x48, 0x5e, 0x87, 0x0f, 0xfb, 0xfe, 0xda, 0xfa, 0xa7, 0x72 } },
|
||||
{ "\x0e\x2d\xcb\x21\x81\x17\xab\xc1\x1e\xb1\x72\x69\x9d\xf2\x79\x44\x41\x60\x05\xa1\x5a\x6a\x90\xe7\xe4\x64\x42\x16\x4d\x1f\x7f\xf5\x54\x24\x9a\xde\x0d\x8d\xa7\x22\x01\x81\x6d\x1a\x72\x4a\x7a\xcb\xbb\x15\x51\x35\xd6\x45\xbf\x38\xf8\x73\x4c\x24\x57\x06\xcc\xdc\x0b\x6c\x15\xa5\x12\xf2\xca\x90\x6e\x46\x56\x82\x69\x86\xf5\xdd\xf9\x04\xec\xcd\x3e\x99\xd9\x31\x27\xa3\x25\x23\x35\x9c\x95\x26\x58\x58\x00\xeb\xf5\xdb\x1b\xc0\x09\xd4\x70\x96\x67\xba\x6d\xad\x1d\x82\x99\xde\xf5\xfa\xe1\x84\x17\xc5\x11\x08\xcc\xf3\x5e\x08\x5d\x3c\x20\x24\x1a\xda\x9d\x65\x76\x00\xff\x49\x4f\xfa\x68\x6f\x4c\xe2\x1c\xdb\x60\xfc\xdd\xe7\x6b\xaf\x54\xc7\xff\x21\xab\xb7\x3f\x6d\x37\xc3\xe4\x84\x53\x32\x59\x9d\x48\x90\x06\x5a\x68\x57\xab\x79\x3a\x3a\xe2\x33\xcf\x0d\xc6\x34\x33\x54\xb3\x38\xff\x66\x23\x3f\x0c\x3d\xb7\x6c\x42\xdd\x57\x80\x8e\x5f\x70\xed\xf2\x9a\x5c\x9a\xb6\x6c\xe0\x33\xbc\xaa\xce\x29\xf1\xa2\xcb\x4d\xdf\x49\x2b\x04\x60\x06\xf8\x28\x6e\x1a\x12\x7c\x15\xaa\x70\xc9\x89\x6a\x84\x99\x54\xe8\xbd\x8f\xa7\x72\x26\x61\xd2", 251, { 0xdd, 0x00, 0x50, 0x61, 0xae, 0x25, 0x19, 0xe0, 0x00, 0x24, 0x84, 0x43, 0x02, 0x6f, 0x1c, 0xd4 } },
|
||||
{ "\xa5\x2c\x74\xcf\x94\x7c\x13\xf9\x91\x0b\x4b\xda\x9b\x2f\x65\x21\x64\xeb\x01\xb3\xfd\x48\xcb\xd8\x20\xde\xdd\x96\x1a\x72\xb1\x1b\x53\xb9\xc1\x53\x7b\x3b\xbd\x9a\x53\x53\x68\x8b\x15\x53\x10\xf7\x81\xc4\xa8\xf2\x86\xca\x83\x07\x89\xa6\xaf\x8b\x54\x56\xec\x0f\x9e\x57\x48\xef\x33\x8a\x58\x07\xc0\x34\x15\x86\x3d\x20\x50\xda\xf7\xdf\xd3\xcb\x39\x30\x16\xa4\x96\x7a\x9b\x8b\xd6\x76\xe7\xf2\x7b\xe9\x1d\x26\xee\x8f\x38\x05\x4b\x14\xe4\xcc\xc6\x3b\xfa\x0e\xb8\x22\x96\xc1\x4a\x9c\xd7\x73\xbc\xbe\x33\x9a\x53\x76\x74\x08\xdd\x54\x53\x7d\xe2\x6c\xaf\x57\x69\x54\x6a\x64\x64\x49\xe1\xd8\xb9\x6e\x06\x5a\xed\x34\x1b\x38\x6f\xd5\x0c\xbc\x7f\xf9\x6a\x96\xb9\x7c\x00\x78\x42\x47\x14\xc1\x8d\x5b\x3b\x51\xcb\xec\xd9\x7b\xed\xaa\x35\x18\x57\x1a\x35\xb8\x22\x23\xba\xf4\x0e\xa5\x9a\xdf\x03\x44\x36\x9b\x42\x43\xb8\x07\x2d\x8a\xeb\x96\xaf\xca\xb7\x3b\x49\xb7\x37\x80\xba\x74\x79\xb6\x4b\x0d\xd1\x47\xb4\x1d\xda\x27\xae\x90\x0b\x69\x16\x83\xf1\xee\xbb\x48\x0e\x38\xc4\x85\x4e\x5c\xc1\x7c\x22\x16\x4c\x65\x3c\xf7\x5b\xf7\xe5\xb9", 252, { 0x93, 0x1d, 0xc4, 0x3f, 0x9e, 0x01, 0xe4, 0xa0, 0xba, 0x31, 0x17, 0x62, 0xb1, 0x71, 0x07, 0x29 } },
|
||||
{ "\x26\x05\xfe\xb3\xaf\x45\x91\x67\xf3\x2d\x13\x39\xab\xf7\x38\x3b\xbf\xc3\x73\x23\x48\xda\x09\x5e\x40\x10\xd1\x3d\xc9\x44\x8a\x4e\x16\x02\xd9\xc6\xfa\x47\xdd\x19\x0b\x64\x70\xac\x72\xfb\xfd\xa2\x52\x26\xf9\xd3\xd3\xb8\x00\xdb\xca\x9b\x8c\x4e\x07\x58\x54\x09\x3a\xb6\x3f\xa4\x82\x79\x03\x03\x94\x4b\x5f\x0c\x84\xb9\xf1\x73\x33\x54\xb4\xb0\x56\xf8\x1a\x12\x1e\x29\xc2\xed\x89\x99\xd7\xef\x45\xc6\x04\x91\x3c\xc0\x17\xa9\xc1\x08\x31\x1c\x55\x94\xa7\xb0\x15\xf0\x79\xff\xc4\x7e\x6d\x87\x71\xde\xc7\xdf\xc5\x68\xa6\x04\xeb\xd6\xfe\xd2\x1c\xff\x2d\x8e\xc6\xbe\x3c\xa0\x58\xf1\xb5\x5e\xac\x9d\x1c\x03\x12\x2f\x0b\xbe\xf5\xdd\xed\xe7\x2d\x2b\x57\x4c\xe0\x8a\xfe\xaa\x15\x1b\x59\x37\xd7\x91\xd4\x5c\x02\x34\xad\x80\xad\x01\x6f\x00\x34\xef\x09\x3b\xe0\x4c\x8b\xc9\x35\x46\x7c\xcb\xd9\x86\xda\x5d\x1c\xf7\xaf\x28\x28\xa5\x4c\x15\xc6\xc0\x25\x1c\xca\xbf\x48\x3a\x1d\xa1\x7b\x81\x65\x4e\xf2\x49\x53\x1c\xaa\x84\x88\x6f\x65\x30\x25\x78\x42\xe5\xee\x1e\xf8\x8e\x19\xf9\xaf\x34\xb9\x7a\x7b\xf6\xc2\x29\x75\x15\xb8\x07\x78\x2c\xf9", 253, { 0x52, 0x78, 0x7c, 0x98, 0x49, 0x6b, 0xa5, 0xff, 0x30, 0xbc, 0xb9, 0x58, 0x43, 0x67, 0x74, 0xff } },
|
||||
{ "\x12\x75\x7c\xa3\xe7\x74\x65\x23\x81\x28\xf1\x5b\x1f\x2d\x8b\x6f\x44\xe0\xcd\x2d\xd8\xdb\x77\x16\x6c\x0b\x7b\x0d\x9b\x70\x34\x9b\x8c\x71\xb7\xdd\x93\xda\x42\x0b\xf7\x73\xd2\xa5\xce\x3e\xd1\x3c\x05\x4c\xeb\xda\x7c\x3c\x01\x0f\x4e\x51\x37\x99\x2e\x2f\x28\xaf\xed\x32\x39\xea\x18\x6b\x0b\xd0\xbd\x39\x0a\xff\x4e\x7f\x22\xf3\x9f\x87\x92\x74\x0a\x73\xd8\x9f\xb2\x5b\xcc\x8e\xe4\x08\xc9\xa7\x99\x4c\x06\x7e\x18\xfc\x02\x68\xb8\x8c\x1e\x9d\xc3\x45\x44\x08\x77\x25\xc5\xaf\x26\x53\x41\xba\x7d\x3d\xbf\x22\xe1\x50\xdd\xf7\xf5\x53\x21\x4d\x38\x61\x6d\xc4\xcc\x81\x91\xb3\x51\xe3\xfb\xf1\xf0\xba\x89\x3f\x74\xb0\x7f\x55\x92\x0a\x94\x88\x49\x5a\x27\x14\x64\xdb\x8f\x0c\x1d\x6c\x90\xdb\xdc\x2c\xe9\x76\x1d\xae\x09\x20\x6f\xd9\xe2\xd9\x98\x5f\xd7\x64\xd6\xd8\xcf\xf4\x40\x7a\x6b\x72\x4b\x77\x54\x6d\x69\xf4\xad\x9f\xcc\xa1\xa8\x18\x49\xf9\x34\x0a\x57\x18\xd4\x30\x36\x34\x8b\xdb\x2c\xb9\xf4\x9a\xea\x05\x6e\x85\x0e\xbd\x73\x26\xc2\xca\x0a\x05\x81\xf4\x53\xcf\xfa\x19\x40\x22\x0d\x09\x63\xf8\xf2\x01\xe1\xad\x79\xc3\x86\xae\x6b\x4e", 254, { 0xce, 0x3c, 0x1c, 0xb0, 0xc1, 0xd5, 0x9a, 0x1f, 0xad, 0x95, 0x57, 0x98, 0xc6, 0x74, 0x61, 0x10 } },
|
||||
{ "\xf3\xc0\x10\x3f\xf2\xea\xca\xc4\xea\x01\xdf\x39\x6d\xce\x54\x61\xef\xdd\xf4\x42\x92\xe5\x70\x9d\x1c\xcf\xa0\x08\x0a\x65\xe8\xaa\xbe\x98\xb6\x93\xd3\x6d\x27\xb5\x91\x86\xc9\x83\x7c\x49\x7b\x25\x07\xaf\x71\x55\x66\xab\x54\xd9\x81\x34\x86\x9d\x04\xf1\x83\x6c\x93\x80\x63\x4b\x1b\x64\x7b\x72\x44\x89\x24\xe8\x02\x74\x93\xba\x4b\x0b\xe7\xd7\xe3\xfe\x42\x8b\x53\xd1\x0e\x96\xf8\x88\x61\xe9\x37\xee\x7b\xfc\xce\x81\x6c\xce\x46\xfd\xd3\x7a\x84\x83\xc1\x73\x7f\x66\xbb\x5c\x0c\x93\xde\x86\xd6\x9a\x1d\x07\x69\x5d\xa6\x73\x6d\x54\x64\x3a\xef\x7a\x9d\x9e\xdb\xd7\xba\x4f\x86\xab\x27\xa4\x68\x34\x51\x78\xe7\x1c\xcc\x9f\x4e\x83\x97\x04\xdc\xa4\x77\x61\xf9\x26\x7f\x99\x84\x01\xb1\xb5\x47\x0b\xbf\x79\x8c\x1f\xea\xa2\xc9\xe8\x0c\xbf\x76\x4f\xb1\xa9\xff\x7f\x5f\xa1\xd5\x91\xf6\x04\xa0\xd9\x32\xad\x8f\xcc\x4e\xe7\xcf\x8c\xc3\x0d\x19\x12\x2f\xc1\x66\xf7\x50\xc5\xbe\xdf\x2f\x79\x2e\x83\x59\xf1\xd8\x59\x48\xb2\x24\xe1\xe1\x0a\x15\x8e\x17\x09\xb6\x50\xad\x1f\xb3\xba\x18\x54\x03\xd5\x82\x1e\xc3\x80\xeb\xe2\x1f\x82\x6a\x0a\x69\x2e\x92", 255, { 0xbb, 0x05, 0x2f, 0x98, 0xc3, 0x43, 0x0a, 0x44, 0x7d, 0xae, 0x93, 0xea, 0x0a, 0x81, 0x4e, 0x3a } },
|
||||
{ "\xbf\x4b\xb1\xf0\x43\x19\xfc\xb0\xee\x40\x48\x5f\xc3\xdc\x4a\xca\xaf\x65\xf5\x06\x5d\x88\xe7\x89\xb8\x14\x71\x76\xfe\x0b\x46\xf6\x7e\xd9\xbf\xc1\xee\xa1\xc8\xbd\x6b\xb2\x6b\xbd\x0d\x18\xf7\x6a\x26\x4f\xcc\x3f\x18\x13\xc6\xae\xd0\x53\x44\x60\xe3\x43\xd4\x9a\x43\x91\x7c\xbb\x9d\xaf\xa7\xe1\x53\x4f\xab\xac\x11\xed\xf3\x1a\x0e\x85\xce\x92\xe1\x66\xd3\xfc\xfd\x1f\xee\x0d\xcb\x95\x0c\xa0\x63\x36\x5f\x40\xe6\x48\x4e\xc2\x7a\x5b\xfd\x0f\xe3\xdd\x74\x00\xbb\xcc\x6e\x62\x4e\x86\xc0\x18\x14\xbc\x64\x60\xcb\x85\x22\x2e\x31\x8f\xda\xb4\x5b\x70\x70\x03\xb5\x1a\x54\xcb\x97\x6d\xac\x3e\x7f\xe7\x21\x13\xf1\x77\x43\xa7\xe8\x6f\x9a\x3e\xf7\x97\x4a\x66\x01\x5d\x62\x7c\x91\x2a\xc1\x48\xd7\xd1\xa5\xc4\x40\x21\xd1\xfa\xb1\x9a\x5b\x0b\x5f\x3c\x0f\x4b\x4d\x7a\x83\x8a\x63\x4e\xb9\x6e\x28\x66\x6a\xfc\x1d\x7c\xf5\x35\xb5\xc3\xe4\xdd\xf4\x7d\x16\x57\xa2\xa9\x8f\xab\x2c\xda\xd9\xaa\x18\x23\x14\x29\x23\x2f\xa1\x69\xf9\x6d\x67\x97\x91\x68\xc0\x6e\x22\x34\x04\xfa\xc5\x04\xb0\x78\xa8\xd9\x32\x5a\xec\x55\x53\x66\x1d\xae\x41\xfe\x4b\xbe\x38\x7a", 256, { 0x64, 0xe1, 0xfd, 0x82, 0x3c, 0xe4, 0x10, 0x8b, 0x41, 0xca, 0x5d, 0xff, 0xed, 0x9f, 0x47, 0x22 } },
|
||||
|
899
cmdline/parity.c
Normal file
899
cmdline/parity.c
Normal file
@ -0,0 +1,899 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "parity.h"
|
||||
#include "handle.h"
|
||||
|
||||
/**
|
||||
* Pseudo random limits for parity
|
||||
*/
|
||||
#define PARITY_LIMIT(size, split, level) \
|
||||
size ? size + (123562341 + split * 634542351 + level * 983491341) % size : 0
|
||||
|
||||
/****************************************************************************/
|
||||
/* parity */
|
||||
|
||||
block_off_t parity_allocated_size(struct snapraid_state* state)
|
||||
{
|
||||
block_off_t parity_block;
|
||||
tommy_node* i;
|
||||
|
||||
/* compute the size of the parity file */
|
||||
parity_block = 0;
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
struct snapraid_disk* disk = i->data;
|
||||
|
||||
/* start from the declared size */
|
||||
block_off_t block = fs_size(disk);
|
||||
|
||||
/* decrease the block until an allocated one, but part of a file */
|
||||
/* we don't stop at deleted blocks, because we want to have them cleared */
|
||||
/* if they are at the end of the parity */
|
||||
while (block > parity_block && !block_has_file(fs_par2block_find(disk, block - 1)))
|
||||
--block;
|
||||
|
||||
/* get the highest value */
|
||||
if (block > parity_block)
|
||||
parity_block = block;
|
||||
}
|
||||
|
||||
return parity_block;
|
||||
}
|
||||
|
||||
block_off_t parity_used_size(struct snapraid_state* state)
|
||||
{
|
||||
block_off_t parity_block;
|
||||
tommy_node* i;
|
||||
|
||||
/* compute the size of the parity file */
|
||||
parity_block = 0;
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
struct snapraid_disk* disk = i->data;
|
||||
|
||||
/* start from the declared size */
|
||||
block_off_t block = fs_size(disk);
|
||||
|
||||
/* decrease the block until an used one */
|
||||
while (block > parity_block && !block_has_file_and_valid_parity(fs_par2block_find(disk, block - 1)))
|
||||
--block;
|
||||
|
||||
/* get the highest value */
|
||||
if (block > parity_block)
|
||||
parity_block = block;
|
||||
}
|
||||
|
||||
return parity_block;
|
||||
}
|
||||
|
||||
int parity_is_invalid(struct snapraid_state* state)
|
||||
{
|
||||
block_off_t blockmax;
|
||||
block_off_t i;
|
||||
|
||||
blockmax = parity_allocated_size(state);
|
||||
|
||||
for (i = 0; i < blockmax; ++i) {
|
||||
tommy_node* node_disk;
|
||||
int one_invalid;
|
||||
int one_valid;
|
||||
|
||||
/* for each disk */
|
||||
one_invalid = 0;
|
||||
one_valid = 0;
|
||||
for (node_disk = state->disklist; node_disk != 0; node_disk = node_disk->next) {
|
||||
struct snapraid_disk* disk = node_disk->data;
|
||||
struct snapraid_block* block = fs_par2block_find(disk, i);
|
||||
|
||||
if (block_has_file(block))
|
||||
one_valid = 1;
|
||||
if (block_has_invalid_parity(block))
|
||||
one_invalid = 1;
|
||||
}
|
||||
|
||||
/* if both valid and invalid, we need to update */
|
||||
if (one_invalid && one_valid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void parity_overflow(struct snapraid_state* state, data_off_t size)
|
||||
{
|
||||
tommy_node* i;
|
||||
block_off_t blockalloc;
|
||||
int found = 0;
|
||||
char esc_buffer[ESC_MAX];
|
||||
|
||||
/* don't report if everything is outside or if the file is not accessible */
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
blockalloc = size / state->block_size;
|
||||
|
||||
/* for all disks */
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
struct snapraid_disk* disk = i->data;
|
||||
tommy_node* j;
|
||||
|
||||
/* for all files */
|
||||
for (j = disk->filelist; j != 0; j = j->next) {
|
||||
struct snapraid_file* file = j->data;
|
||||
|
||||
if (file->blockmax > 0) {
|
||||
block_off_t parity_pos = fs_file2par_get(disk, file, file->blockmax - 1);
|
||||
if (parity_pos >= blockalloc) {
|
||||
found = 1;
|
||||
log_tag("outofparity:%s:%s\n", disk->name, esc_tag(file->sub, esc_buffer));
|
||||
log_fatal("outofparity %s%s\n", disk->dir, file->sub);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
log_fatal("\nYour data requires more parity than the available space.\n");
|
||||
log_fatal("Please move the files 'outofparity' to another data disk.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void parity_size(struct snapraid_parity_handle* handle, data_off_t* out_size)
|
||||
{
|
||||
unsigned s;
|
||||
data_off_t size;
|
||||
|
||||
/* now compute the size summing all the parity splits */
|
||||
size = 0;
|
||||
|
||||
for (s = 0; s < handle->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
|
||||
size += split->size;
|
||||
}
|
||||
|
||||
*out_size = size;
|
||||
}
|
||||
|
||||
int parity_create(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size)
|
||||
{
|
||||
unsigned s;
|
||||
data_off_t block_mask;
|
||||
|
||||
/* mask of bits used by the block size */
|
||||
block_mask = ((data_off_t)block_size) - 1;
|
||||
|
||||
handle->level = level;
|
||||
handle->split_mac = 0;
|
||||
|
||||
for (s = 0; s < parity->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
int ret;
|
||||
int flags;
|
||||
|
||||
advise_init(&split->advise, mode);
|
||||
pathcpy(split->path, sizeof(split->path), parity->split_map[s].path);
|
||||
split->size = parity->split_map[s].size;
|
||||
split->limit_size = PARITY_LIMIT(limit_size, s, level);
|
||||
|
||||
/* opening in sequential mode in Windows */
|
||||
flags = O_RDWR | O_CREAT | O_BINARY | advise_flags(&split->advise);
|
||||
split->f = open(split->path, flags, 0600);
|
||||
if (split->f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* we have a valid file handle */
|
||||
++handle->split_mac;
|
||||
|
||||
/* get the stat info */
|
||||
ret = fstat(split->f, &split->st);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/**
|
||||
* If the parity size is not yet set, set it now.
|
||||
* This happens when expanding the number of parities,
|
||||
* or when upgrading from a content file that has not split->size data.
|
||||
*/
|
||||
if (split->size == PARITY_SIZE_INVALID) {
|
||||
split->size = split->st.st_size;
|
||||
|
||||
/* ensure that the resulting size if block aligned */
|
||||
if ((split->size & block_mask) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in preallocated size of parity file '%s' with size %" PRIu64 " and block %u .\n", split->path, split->size, block_size);
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
ret = advise_open(&split->advise, split->f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
for (s = 0; s < handle->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
close(split->f);
|
||||
split->f = -1;
|
||||
}
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
static int parity_handle_grow(struct snapraid_split_handle* split, data_off_t previous_size, data_off_t size, int skip_fallocate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
(void)previous_size;
|
||||
|
||||
/* simulate a failure for testing limits */
|
||||
if (split->limit_size != 0 && size > (data_off_t)split->limit_size)
|
||||
return -1;
|
||||
|
||||
#if HAVE_FALLOCATE
|
||||
if (!skip_fallocate) {
|
||||
/*
|
||||
* Allocate real space using the specific Linux fallocate() operation.
|
||||
* If the underline file-system doesn't support it, this operation fails.
|
||||
*
|
||||
* Instead posix_fallocate() fallbacks to write the whole file,
|
||||
* and we cannot use it as we may need to initialize a multi terabyte
|
||||
* file.
|
||||
*
|
||||
* See: fallocate vs posix_fallocate
|
||||
* http://stackoverflow.com/questions/14063046/fallocate-vs-posix-fallocate
|
||||
*
|
||||
* To work better with Btrfs, use as offset the previous allocated size.
|
||||
* Otherwise Btrfs will count as space needed even the already allocated one.
|
||||
*
|
||||
* See: Massive loss of disk space
|
||||
* https://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg66454.html
|
||||
*/
|
||||
ret = fallocate(split->f, 0, previous_size, size - previous_size);
|
||||
|
||||
/*
|
||||
* In some legacy system fallocate() may return the error number
|
||||
* as positive integer, and in this case it doesn't set errno.
|
||||
*
|
||||
* Detect and handle this case.
|
||||
*
|
||||
* See: Fix fallocate error return on i386
|
||||
* https://sourceware.org/ml/libc-hacker/2010-04/msg00000.html
|
||||
*
|
||||
* See: [PATCH XFS] Fix error return for fallocate() on XFS
|
||||
* http://oss.sgi.com/archives/xfs/2009-11/msg00201.html
|
||||
*/
|
||||
if (ret > 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
errno = ret;
|
||||
ret = -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
} else {
|
||||
errno = EOPNOTSUPP;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fallback to ftruncate() if the operation is not supported.
|
||||
*
|
||||
* We get EOPNOTSUPP if the operation is not supported, like in ext3/ext2
|
||||
* or ENOSYS with kernel before 2.6.23, because fallocate is not supported
|
||||
* at all.
|
||||
*
|
||||
* See: man fallocate
|
||||
* ENOSYS - This kernel does not implement fallocate().
|
||||
* EOPNOTSUPP - The file system containing the file referred to by fd does not support this operation
|
||||
*/
|
||||
if (ret != 0 && (errno == EOPNOTSUPP || errno == ENOSYS)) {
|
||||
/* fallback using ftruncate() */
|
||||
ret = ftruncate(split->f, size);
|
||||
}
|
||||
#else
|
||||
(void)skip_fallocate; /* avoid the warning */
|
||||
|
||||
/* allocate using a sparse file */
|
||||
ret = ftruncate(split->f, size);
|
||||
#endif
|
||||
|
||||
if (ret != 0)
|
||||
log_tag("split:grow:%s:%" PRIu64 ": failed with error %s\n", split->path, size, strerror(errno));
|
||||
else
|
||||
log_tag("split:grow:%s:%" PRIu64 ": ok\n", split->path, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int parity_handle_shrink(struct snapraid_split_handle* split, data_off_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = ftruncate(split->f, size);
|
||||
|
||||
if (ret != 0)
|
||||
log_tag("split:shrink:%s:%" PRIu64 ": failed with error %s\n", split->path, size, strerror(errno));
|
||||
else
|
||||
log_tag("split:shrink:%s:%" PRIu64 ": ok\n", split->path, size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the highest bit set.
|
||||
*/
|
||||
uint64_t hbit_u64(uint64_t v)
|
||||
{
|
||||
unsigned ilog;
|
||||
|
||||
ilog = 0;
|
||||
while ((v /= 2) != 0)
|
||||
++ilog;
|
||||
|
||||
return 1ULL << ilog;
|
||||
}
|
||||
|
||||
static int parity_handle_fill(struct snapraid_split_handle* split, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder)
|
||||
{
|
||||
data_off_t base;
|
||||
data_off_t delta;
|
||||
data_off_t block_mask;
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* In Windows we want to avoid the annoying warning
|
||||
* message of disk full.
|
||||
*
|
||||
* To ensure to leave some space available, we first create
|
||||
* a spaceholder file >200 MB, to ensure to not fill completely
|
||||
* the disk.
|
||||
*/
|
||||
char spaceholder_path[PATH_MAX];
|
||||
|
||||
pathprint(spaceholder_path, sizeof(spaceholder_path), "%s%s", split->path, ".spaceholder");
|
||||
|
||||
if (!skip_space_holder) {
|
||||
data_off_t spaceholder_size = 256 * 1024 * 1024;
|
||||
int spaceholder_f;
|
||||
|
||||
spaceholder_f = open(spaceholder_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0600);
|
||||
if (spaceholder_f == -1) {
|
||||
log_fatal("Failed to create space holder file '%s'.\n", spaceholder_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* note that in Windows ftruncate is really allocating space */
|
||||
if (ftruncate(spaceholder_f, spaceholder_size) != 0) {
|
||||
log_fatal("WARNING Failed to resize the space holder file '%s' to %" PRIu64 " bytes.\n", spaceholder_path, spaceholder_size);
|
||||
log_fatal("Assuming that no more space is available.\n");
|
||||
close(spaceholder_f);
|
||||
remove(spaceholder_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fsync(spaceholder_f) != 0) {
|
||||
log_fatal("Failed to sync the space holder file '%s'.\n", spaceholder_path);
|
||||
close(spaceholder_f);
|
||||
remove(spaceholder_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (close(spaceholder_f) != 0) {
|
||||
log_fatal("Failed to close the space holder file '%s'.\n", spaceholder_path);
|
||||
remove(spaceholder_path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)skip_space_holder;
|
||||
#endif
|
||||
|
||||
/* mask of bits used by the block size */
|
||||
block_mask = ((data_off_t)block_size) - 1;
|
||||
|
||||
/* present size */
|
||||
base = split->st.st_size;
|
||||
|
||||
/* truncate it to block size multiplier */
|
||||
/* in case of damage the size may get wrong */
|
||||
base &= ~block_mask;
|
||||
|
||||
/* size we have to increase */
|
||||
delta = size - base;
|
||||
|
||||
log_tag("split:fill:%s:%" PRIu64 ":%" PRIu64 ":\n", split->path, base, size);
|
||||
|
||||
/* grow the size one bit at time, like a kind of binary search */
|
||||
while (delta != 0) {
|
||||
int ret;
|
||||
data_off_t run = hbit_u64(delta);
|
||||
|
||||
/* mask out the bit we process */
|
||||
delta &= ~run;
|
||||
|
||||
log_tag("split:delta:%s:%" PRIu64 ":%" PRIu64 ":\n", split->path, base, run);
|
||||
|
||||
ret = parity_handle_grow(split, base, base + run, skip_fallocate);
|
||||
if (ret != 0) {
|
||||
/* we cannot grow, fallback enabling all the smaller bits */
|
||||
delta = run - 1;
|
||||
|
||||
/* mask out the block size */
|
||||
delta &= ~block_mask;
|
||||
} else {
|
||||
/* increase the effective size */
|
||||
base += run;
|
||||
}
|
||||
}
|
||||
|
||||
/* ensure that the resulting size if block aligned */
|
||||
if ((base & block_mask) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in requested parity size %" PRIu64 " with block %u\n", base, block_size);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* now delete the spaceholder file */
|
||||
if (remove(spaceholder_path) != 0) {
|
||||
log_fatal("WARNING Failed to remove the space holder file '%s'.\n", spaceholder_path);
|
||||
log_fatal("Continuing anyway.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* shrink to the expected size to ensure to throw away any extra */
|
||||
/* data allocated when the grow operation fails */
|
||||
return parity_handle_shrink(split, base);
|
||||
}
|
||||
|
||||
static int parity_handle_chsize(struct snapraid_split_handle* split, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder)
|
||||
{
|
||||
int ret;
|
||||
int f_ret;
|
||||
int f_errno;
|
||||
int f_dir;
|
||||
|
||||
if (split->st.st_size < size) {
|
||||
f_ret = parity_handle_fill(split, size, block_size, skip_fallocate, skip_space_holder);
|
||||
f_errno = errno;
|
||||
f_dir = 1;
|
||||
} else if (split->st.st_size > size) {
|
||||
f_ret = parity_handle_shrink(split, size);
|
||||
f_errno = errno;
|
||||
f_dir = -1;
|
||||
} else {
|
||||
f_ret = 0;
|
||||
f_errno = 0;
|
||||
f_dir = 0;
|
||||
}
|
||||
|
||||
/* get the stat info */
|
||||
ret = fstat(split->f, &split->st);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* now check the error */
|
||||
if (f_ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
if (f_dir > 0) {
|
||||
if (f_errno == ENOSPC) {
|
||||
log_fatal("Failed to grow parity file '%s' to size %" PRIu64 " due lack of space.\n", split->path, size);
|
||||
} else {
|
||||
log_fatal("Error growing parity file '%s' to size %" PRIu64 ". Do you have enough space? %s.\n", split->path, size, strerror(f_errno));
|
||||
}
|
||||
} else {
|
||||
log_fatal("Error truncating parity file '%s' to size %" PRIu64 ". %s.\n", split->path, size, strerror(f_errno));
|
||||
}
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parity_split_is_fixed(struct snapraid_parity_handle* handle, unsigned s)
|
||||
{
|
||||
/* next one */
|
||||
++s;
|
||||
|
||||
/* the latest one is always growing */
|
||||
if (s >= handle->split_mac)
|
||||
return 0;
|
||||
|
||||
/* if the next it's 0, this one is growing */
|
||||
if (handle->split_map[s].size == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int parity_chsize(struct snapraid_parity_handle* handle, struct snapraid_parity* parity, int* is_modified, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder)
|
||||
{
|
||||
int ret;
|
||||
unsigned s;
|
||||
data_off_t block_mask;
|
||||
|
||||
/* mask of bits used by the block size */
|
||||
block_mask = ((data_off_t)block_size) - 1;
|
||||
|
||||
if (size < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
for (s = 0; s < handle->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
int is_fixed = parity_split_is_fixed(handle, s);
|
||||
data_off_t run;
|
||||
|
||||
if (is_fixed) {
|
||||
/* if the required size is smaller, we have to reduce also the file */
|
||||
/* ignoring the previous size */
|
||||
if (size <= split->size) {
|
||||
/* mark it as not fixed anymore for the later check */
|
||||
is_fixed = 0;
|
||||
|
||||
run = size; /* allocate only the needed size */
|
||||
} else {
|
||||
/* if the size cannot be changed, use the fixed one */
|
||||
run = split->size;
|
||||
|
||||
if ((run & block_mask) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in split '%s' size with extra '%" PRIu64 "' bytes.\n", split->path, run & block_mask);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* otherwise tries to allocate all the needed remaining size */
|
||||
run = size;
|
||||
}
|
||||
|
||||
ret = parity_handle_chsize(split, run, block_size, skip_fallocate, skip_space_holder);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (split->st.st_size > run) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Unexpected over resizing parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, (uint64_t)split->st.st_size);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
} else if (is_fixed && split->st.st_size < run) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed restoring parity file '%s' to size %" PRIu64 " resulting in size %" PRIu64 ".\n", split->path, run, (uint64_t)split->st.st_size);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
} else {
|
||||
/* here it's possible to get less than the requested size */
|
||||
run = split->st.st_size;
|
||||
|
||||
if ((run & block_mask) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in final parity size %" PRIu64 " with block size %u\n", run, block_size);
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* store what we have allocated */
|
||||
split->size = run;
|
||||
|
||||
/* decrease the remaining size */
|
||||
size -= run;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we cannot allocate all the space */
|
||||
if (size != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed to allocate all the required parity space. You miss %" PRIu64 " bytes.\n", size);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* now copy the new size in the parity data */
|
||||
if (is_modified)
|
||||
*is_modified = 0;
|
||||
|
||||
for (s = 0; s < handle->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
|
||||
if (parity->split_map[s].size != split->size) {
|
||||
parity->split_map[s].size = split->size;
|
||||
if (is_modified)
|
||||
*is_modified = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size)
|
||||
{
|
||||
unsigned s;
|
||||
data_off_t block_mask;
|
||||
|
||||
handle->level = level;
|
||||
handle->split_mac = 0;
|
||||
|
||||
/* mask of bits used by the block size */
|
||||
block_mask = ((data_off_t)block_size) - 1;
|
||||
|
||||
for (s = 0; s < parity->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
int ret;
|
||||
int flags;
|
||||
|
||||
advise_init(&split->advise, mode);
|
||||
pathcpy(split->path, sizeof(split->path), parity->split_map[s].path);
|
||||
split->size = parity->split_map[s].size;
|
||||
split->limit_size = PARITY_LIMIT(limit_size, s, level);
|
||||
|
||||
/* open for read */
|
||||
/* O_NOATIME: do not change access time */
|
||||
flags = O_RDONLY | O_BINARY | advise_flags(&split->advise);
|
||||
|
||||
split->f = open_noatime(split->path, flags);
|
||||
if (split->f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* we have a valid file handle */
|
||||
++handle->split_mac;
|
||||
|
||||
/* get the stat info */
|
||||
ret = fstat(split->f, &split->st);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error accessing parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/**
|
||||
* If the parity size is not yet set, set it now.
|
||||
* This happens when expanding the number of parities,
|
||||
* or when upgrading from a content file that has not split->size data.
|
||||
*/
|
||||
if (split->size == PARITY_SIZE_INVALID) {
|
||||
split->size = split->st.st_size;
|
||||
|
||||
/* ensure that the resulting size if block aligned */
|
||||
if ((split->size & block_mask) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in preallocated size of parity file '%s' with size %" PRIu64 " and block %u .\n", split->path, split->size, block_size);
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
ret = advise_open(&split->advise, split->f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
for (s = 0; s < handle->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
close(split->f);
|
||||
split->f = -1;
|
||||
}
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
int parity_sync(struct snapraid_parity_handle* handle)
|
||||
{
|
||||
#if HAVE_FSYNC
|
||||
unsigned s;
|
||||
|
||||
for (s = 0; s < handle->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
int ret;
|
||||
|
||||
/* Ensure that data changes are written to disk. */
|
||||
/* This is required to ensure that parity is more updated than content */
|
||||
/* in case of a system crash. */
|
||||
ret = fsync(split->f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error synching parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parity_close(struct snapraid_parity_handle* handle)
|
||||
{
|
||||
unsigned s;
|
||||
int f_ret = 0;
|
||||
|
||||
for (s = 0; s < handle->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
int ret;
|
||||
|
||||
ret = close(split->f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
/* This is a serious error, as it may be the result of a failed write */
|
||||
/* identified at later time. */
|
||||
/* In a normal file-system (not NFS) it should never happen */
|
||||
log_fatal("Error closing parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
f_ret = -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
|
||||
/* continue to close the others */
|
||||
}
|
||||
|
||||
/* reset the descriptor */
|
||||
split->f = -1;
|
||||
}
|
||||
|
||||
return f_ret;
|
||||
}
|
||||
|
||||
struct snapraid_split_handle* parity_split_find(struct snapraid_parity_handle* handle, data_off_t* offset)
|
||||
{
|
||||
unsigned s;
|
||||
|
||||
if (*offset < 0)
|
||||
return 0;
|
||||
|
||||
for (s = 0; s < handle->split_mac; ++s) {
|
||||
struct snapraid_split_handle* split = &handle->split_map[s];
|
||||
|
||||
if (*offset < split->size)
|
||||
return split;
|
||||
|
||||
*offset -= split->size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size)
|
||||
{
|
||||
ssize_t write_ret;
|
||||
data_off_t offset;
|
||||
struct snapraid_split_handle* split;
|
||||
int ret;
|
||||
|
||||
offset = pos * (data_off_t)block_size;
|
||||
|
||||
split = parity_split_find(handle, &offset);
|
||||
if (!split) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Writing parity data outside range at extra offset %" PRIu64 ".\n", offset);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
write_ret = pwrite(split->f, block_buffer, block_size, offset);
|
||||
if (write_ret != (ssize_t)block_size) { /* conversion is safe because block_size is always small */
|
||||
/* LCOV_EXCL_START */
|
||||
if (errno == ENOSPC) {
|
||||
log_fatal("Failed to grow parity file '%s' using write due lack of space.\n", split->path);
|
||||
} else {
|
||||
log_fatal("Error writing file '%s'. %s.\n", split->path, strerror(errno));
|
||||
}
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = advise_write(&split->advise, split->f, offset, block_size);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out)
|
||||
{
|
||||
ssize_t read_ret;
|
||||
data_off_t offset;
|
||||
unsigned count;
|
||||
struct snapraid_split_handle* split;
|
||||
int ret;
|
||||
|
||||
offset = pos * (data_off_t)block_size;
|
||||
|
||||
split = parity_split_find(handle, &offset);
|
||||
if (!split) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Reading parity data outside range at extra offset %" PRIu64 ".\n", offset);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
count = 0;
|
||||
do {
|
||||
read_ret = pread(split->f, block_buffer + count, block_size - count, offset + count);
|
||||
if (read_ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Error reading file '%s' at offset %" PRIu64 " for size %u. %s.\n", split->path, offset + count, block_size - count, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (read_ret == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Unexpected end of file '%s' at offset %" PRIu64 ". %s.\n", split->path, offset, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
count += read_ret;
|
||||
} while (count < block_size);
|
||||
|
||||
ret = advise_read(&split->advise, split->f, offset, block_size);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
out("Error advising parity file '%s'. %s.\n", split->path, strerror(errno));
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return block_size;
|
||||
}
|
||||
|
132
cmdline/parity.h
Normal file
132
cmdline/parity.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __PARITY_H
|
||||
#define __PARITY_H
|
||||
|
||||
#include "support.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* parity */
|
||||
|
||||
struct snapraid_split_handle {
|
||||
char path[PATH_MAX]; /**< Path of the file. */
|
||||
int f; /**< Handle of the files. */
|
||||
struct stat st; /**< Stat info of the opened file. */
|
||||
struct advise_struct advise; /**< Advise information. */
|
||||
|
||||
/**
|
||||
* Size of the parity split.
|
||||
* Only the latest not zero size is allowed to grow.
|
||||
* Note that this value CANNOT be PARITY_SIZE_INVALID.
|
||||
*/
|
||||
data_off_t size;
|
||||
|
||||
/**
|
||||
* Artificial size limit for testing.
|
||||
* 0 means unlimited.
|
||||
*/
|
||||
data_off_t limit_size;
|
||||
};
|
||||
|
||||
struct snapraid_parity_handle {
|
||||
struct snapraid_split_handle split_map[SPLIT_MAX];
|
||||
unsigned split_mac; /**< Number of parity splits. */
|
||||
unsigned level; /**< Level of the parity. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Compute the size of the allocated parity data in number of blocks.
|
||||
*
|
||||
* This includes parity blocks not yet written and still invalid.
|
||||
*/
|
||||
block_off_t parity_allocated_size(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Compute the size of the used parity data in number of blocks.
|
||||
*
|
||||
* This includes only parity blocks used for files, not counting
|
||||
* potential invalid parity at the end.
|
||||
*
|
||||
* If the array is fully synced there is no difference between
|
||||
* parity_allocate_size() and parity_used_size().
|
||||
* But if the sync is interrupted, the parity_used_size() returns
|
||||
* the position of the latest BLK block, ignoring CHG, REL and DELETED ones,
|
||||
* because their parity may be still not even written in the parity file.
|
||||
*/
|
||||
block_off_t parity_used_size(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Check if the parity needs to be updated with a "sync".
|
||||
*
|
||||
* This is the same logic used in "status" to detect an incomplete "sync",
|
||||
* that ignores invalid block, if they are not used by a file in any disk.
|
||||
* This means that DELETED blocks won't necessarily imply an invalid parity.
|
||||
*/
|
||||
int parity_is_invalid(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Report all the files outside the specified parity size.
|
||||
*/
|
||||
void parity_overflow(struct snapraid_state* state, data_off_t size);
|
||||
|
||||
/**
|
||||
* Create the parity file.
|
||||
* \param out_size Return the size of the parity file.
|
||||
*/
|
||||
int parity_create(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size);
|
||||
|
||||
/**
|
||||
* Change the parity size.
|
||||
* \param out_size Return the size of the parity file. The out_size is set also on error to reflect a partial resize.
|
||||
*/
|
||||
int parity_chsize(struct snapraid_parity_handle* handle, struct snapraid_parity* parity, int* is_modified, data_off_t size, uint32_t block_size, int skip_fallocate, int skip_space_holder);
|
||||
|
||||
/**
|
||||
* Get the size of the parity.
|
||||
*
|
||||
* This returns the cached/expected version of the split sizes, and not the real file size.
|
||||
*/
|
||||
void parity_size(struct snapraid_parity_handle* handle, data_off_t* out_size);
|
||||
|
||||
/**
|
||||
* Open an already existing parity file.
|
||||
*/
|
||||
int parity_open(struct snapraid_parity_handle* handle, const struct snapraid_parity* parity, unsigned level, int mode, uint32_t block_size, data_off_t limit_size);
|
||||
|
||||
/**
|
||||
* Flush the parity file in the disk.
|
||||
*/
|
||||
int parity_sync(struct snapraid_parity_handle* handle);
|
||||
|
||||
/**
|
||||
* Close the parity file.
|
||||
*/
|
||||
int parity_close(struct snapraid_parity_handle* handle);
|
||||
|
||||
/**
|
||||
* Read a block from the parity file.
|
||||
*/
|
||||
int parity_read(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size, fptr* out);
|
||||
|
||||
/**
|
||||
* Write a block in the parity file.
|
||||
*/
|
||||
int parity_write(struct snapraid_parity_handle* handle, block_off_t pos, unsigned char* block_buffer, unsigned block_size);
|
||||
|
||||
#endif
|
||||
|
470
cmdline/pool.c
Normal file
470
cmdline/pool.c
Normal file
@ -0,0 +1,470 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
|
||||
struct snapraid_pool {
|
||||
char file[PATH_MAX];
|
||||
char linkto[PATH_MAX];
|
||||
int64_t mtime_sec;
|
||||
int mtime_nsec;
|
||||
|
||||
/* nodes for data structures */
|
||||
tommy_hashdyn_node node;
|
||||
};
|
||||
|
||||
struct snapraid_pool* pool_alloc(const char* dir, const char* name, const char* linkto, const struct stat* st)
|
||||
{
|
||||
struct snapraid_pool* pool;
|
||||
|
||||
pool = malloc_nofail(sizeof(struct snapraid_pool));
|
||||
pathprint(pool->file, sizeof(pool->file), "%s%s", dir, name);
|
||||
pathcpy(pool->linkto, sizeof(pool->linkto), linkto);
|
||||
pool->mtime_sec = st->st_mtime;
|
||||
pool->mtime_nsec = STAT_NSEC(st);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
static inline tommy_uint32_t pool_hash(const char* file)
|
||||
{
|
||||
return tommy_hash_u32(0, file, strlen(file));
|
||||
}
|
||||
|
||||
void pool_free(struct snapraid_pool* pool)
|
||||
{
|
||||
free(pool);
|
||||
}
|
||||
|
||||
int pool_compare(const void* void_arg, const void* void_data)
|
||||
{
|
||||
const char* arg = void_arg;
|
||||
const struct snapraid_pool* pool = void_data;
|
||||
|
||||
return strcmp(arg, pool->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove empty dir.
|
||||
* Return == 0 if the directory is empty, and it can be removed
|
||||
*/
|
||||
static int clean_dir(const char* dir)
|
||||
{
|
||||
DIR* d;
|
||||
int full = 0;
|
||||
|
||||
d = opendir(dir);
|
||||
if (!d) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening pool directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
while (1) {
|
||||
char path_next[PATH_MAX];
|
||||
struct stat st;
|
||||
const char* name;
|
||||
struct dirent* dd;
|
||||
|
||||
/* clear errno to detect erroneous conditions */
|
||||
errno = 0;
|
||||
dd = readdir(d);
|
||||
if (dd == 0 && errno != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reading pool directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (dd == 0 && errno == 0) {
|
||||
break; /* finished */
|
||||
}
|
||||
|
||||
/* skip "." and ".." files */
|
||||
name = dd->d_name;
|
||||
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
|
||||
continue;
|
||||
|
||||
pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
|
||||
|
||||
#if HAVE_STRUCT_DIRENT_D_STAT
|
||||
/* convert dirent to lstat result */
|
||||
dirent_lstat(dd, &st);
|
||||
|
||||
/* if the st_mode field is missing, takes care to fill it using normal lstat() */
|
||||
/* at now this can happen only in Windows */
|
||||
if (st.st_mode == 0) {
|
||||
if (lstat(path_next, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* get lstat info about the file */
|
||||
if (lstat(path_next, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
/* recurse */
|
||||
pathslash(path_next, sizeof(path_next));
|
||||
if (clean_dir(path_next) == 0) {
|
||||
int ret;
|
||||
|
||||
/* directory is empty, try to remove it */
|
||||
ret = rmdir(path_next);
|
||||
if (ret < 0) {
|
||||
#ifdef _WIN32
|
||||
if (errno == EACCES) {
|
||||
/* in Windows just ignore EACCES errors removing directories */
|
||||
/* because it could happen that the directory is in use */
|
||||
/* and it cannot be removed */
|
||||
log_fatal("Directory '%s' not removed because it's in use.\n", path_next);
|
||||
full = 1;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing pool directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* something is present */
|
||||
full = 1;
|
||||
}
|
||||
} else {
|
||||
/* something is present */
|
||||
full = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(d) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing pool directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return full;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all the links in a directory tree.
|
||||
*/
|
||||
static void read_dir(tommy_hashdyn* poolset, const char* base_dir, const char* sub_dir)
|
||||
{
|
||||
char dir[PATH_MAX];
|
||||
DIR* d;
|
||||
|
||||
pathprint(dir, sizeof(dir), "%s%s", base_dir, sub_dir);
|
||||
d = opendir(dir);
|
||||
if (!d) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening pool directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
while (1) {
|
||||
char path_next[PATH_MAX];
|
||||
struct stat st;
|
||||
const char* name;
|
||||
struct dirent* dd;
|
||||
|
||||
/* clear errno to detect erroneous conditions */
|
||||
errno = 0;
|
||||
dd = readdir(d);
|
||||
if (dd == 0 && errno != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reading pool directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (dd == 0 && errno == 0) {
|
||||
break; /* finished */
|
||||
}
|
||||
|
||||
/* skip "." and ".." files */
|
||||
name = dd->d_name;
|
||||
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
|
||||
continue;
|
||||
|
||||
pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
|
||||
|
||||
#if HAVE_STRUCT_DIRENT_D_STAT
|
||||
/* convert dirent to lstat result */
|
||||
dirent_lstat(dd, &st);
|
||||
|
||||
/* if the st_mode field is missing, takes care to fill it using normal lstat() */
|
||||
/* at now this can happen only in Windows */
|
||||
if (st.st_mode == 0) {
|
||||
if (lstat(path_next, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* get lstat info about the file */
|
||||
if (lstat(path_next, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
struct snapraid_pool* pool;
|
||||
char linkto[PATH_MAX];
|
||||
int ret;
|
||||
|
||||
ret = readlink(path_next, linkto, sizeof(linkto));
|
||||
if (ret < 0 || ret >= PATH_MAX) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in readlink symlink '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
linkto[ret] = 0;
|
||||
|
||||
/* store the link info */
|
||||
pool = pool_alloc(sub_dir, name, linkto, &st);
|
||||
|
||||
tommy_hashdyn_insert(poolset, &pool->node, pool, pool_hash(pool->file));
|
||||
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
pathprint(path_next, sizeof(path_next), "%s%s/", sub_dir, name);
|
||||
|
||||
read_dir(poolset, base_dir, path_next);
|
||||
} else {
|
||||
msg_verbose("Ignoring pool file '%s'\n", path_next);
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(d) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing pool directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the link
|
||||
*/
|
||||
static void remove_link(void* void_arg, void* void_pool)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
const char* arg = void_arg;
|
||||
struct snapraid_pool* pool = void_pool;
|
||||
int ret;
|
||||
|
||||
pathprint(path, sizeof(path), "%s%s", arg, pool->file);
|
||||
|
||||
/* delete the link */
|
||||
ret = remove(path);
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing symlink '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a link to the specified disk link.
|
||||
*/
|
||||
static void make_link(tommy_hashdyn* poolset, const char* pool_dir, const char* share_dir, struct snapraid_disk* disk, const char* sub, int64_t mtime_sec, int mtime_nsec)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char linkto[PATH_MAX];
|
||||
char linkto_exported[PATH_MAX];
|
||||
struct snapraid_pool* found;
|
||||
int ret;
|
||||
|
||||
/* make the source path */
|
||||
pathprint(path, sizeof(path), "%s%s", pool_dir, sub);
|
||||
|
||||
/* make the linkto path */
|
||||
if (share_dir[0] != 0) {
|
||||
/* with a shared directory, use it */
|
||||
pathprint(linkto, sizeof(linkto), "%s%s/%s", share_dir, disk->name, sub);
|
||||
} else {
|
||||
/* without a share directory, use the local disk paths */
|
||||
pathprint(linkto, sizeof(linkto), "%s%s", disk->dir, sub);
|
||||
}
|
||||
|
||||
/* search for the sub path */
|
||||
found = tommy_hashdyn_search(poolset, pool_compare, sub, pool_hash(sub));
|
||||
if (found) {
|
||||
/* remove from the set */
|
||||
tommy_hashdyn_remove_existing(poolset, &found->node);
|
||||
|
||||
/* check if the info match */
|
||||
if (found->mtime_sec == mtime_sec
|
||||
&& found->mtime_nsec == mtime_nsec
|
||||
&& strcmp(found->linkto, linkto) == 0
|
||||
) {
|
||||
/* nothing to do */
|
||||
pool_free(found);
|
||||
return;
|
||||
}
|
||||
|
||||
/* delete the link */
|
||||
ret = remove(path);
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing symlink '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
pool_free(found);
|
||||
}
|
||||
|
||||
/* create the ancestor directories */
|
||||
ret = mkancestor(path);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* convert back slashes */
|
||||
pathexport(linkto_exported, sizeof(linkto_exported), linkto);
|
||||
|
||||
/* create the symlink */
|
||||
ret = symlink(linkto_exported, path);
|
||||
if (ret != 0) {
|
||||
if (errno == EEXIST) {
|
||||
log_fatal("WARNING! Duplicate pooling for '%s'\n", path);
|
||||
#ifdef _WIN32
|
||||
} else if (errno == EPERM) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You must run as Adminstrator to be able to create symlinks.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
#endif
|
||||
} else {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error writing symlink '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
if (mtime_sec) {
|
||||
ret = lmtime(path, mtime_sec, mtime_nsec);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error setting time to symlink '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void state_pool(struct snapraid_state* state)
|
||||
{
|
||||
tommy_hashdyn poolset;
|
||||
tommy_node* i;
|
||||
char pool_dir[PATH_MAX];
|
||||
char share_dir[PATH_MAX];
|
||||
unsigned count;
|
||||
|
||||
tommy_hashdyn_init(&poolset);
|
||||
|
||||
if (state->pool[0] == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("To use the 'pool' command you must set the pool directory in the configuration file\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
msg_progress("Reading...\n");
|
||||
|
||||
/* pool directory with final slash */
|
||||
pathprint(pool_dir, sizeof(pool_dir), "%s", state->pool);
|
||||
pathslash(pool_dir, sizeof(pool_dir));
|
||||
|
||||
/* share directory with final slash */
|
||||
pathprint(share_dir, sizeof(share_dir), "%s", state->share);
|
||||
pathslash(share_dir, sizeof(share_dir));
|
||||
|
||||
/* first read the previous pool tree */
|
||||
read_dir(&poolset, pool_dir, "");
|
||||
|
||||
msg_progress("Writing...\n");
|
||||
|
||||
/* for each disk */
|
||||
count = 0;
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
tommy_node* j;
|
||||
struct snapraid_disk* disk = i->data;
|
||||
|
||||
/* for each file */
|
||||
for (j = disk->filelist; j != 0; j = j->next) {
|
||||
struct snapraid_file* file = j->data;
|
||||
make_link(&poolset, pool_dir, share_dir, disk, file->sub, file->mtime_sec, file->mtime_nsec);
|
||||
++count;
|
||||
}
|
||||
|
||||
/* for each link */
|
||||
for (j = disk->linklist; j != 0; j = j->next) {
|
||||
struct snapraid_link* slink = j->data;
|
||||
make_link(&poolset, pool_dir, share_dir, disk, slink->sub, 0, 0);
|
||||
++count;
|
||||
}
|
||||
|
||||
/* we ignore empty dirs in disk->dir */
|
||||
}
|
||||
|
||||
msg_progress("Cleaning...\n");
|
||||
|
||||
/* delete all the remaining links */
|
||||
tommy_hashdyn_foreach_arg(&poolset, (tommy_foreach_arg_func*)remove_link, pool_dir);
|
||||
|
||||
/* delete empty dirs */
|
||||
clean_dir(pool_dir);
|
||||
|
||||
tommy_hashdyn_foreach(&poolset, (tommy_foreach_func*)pool_free);
|
||||
tommy_hashdyn_done(&poolset);
|
||||
|
||||
if (count)
|
||||
msg_status("%u links\n", count);
|
||||
else
|
||||
msg_status("No link\n");
|
||||
|
||||
log_tag("summary:link_count::%u\n", count);
|
||||
log_tag("summary:exit:ok\n");
|
||||
log_flush();
|
||||
}
|
||||
|
492
cmdline/portable.h
Normal file
492
cmdline/portable.h
Normal file
@ -0,0 +1,492 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __PORTABLE_H
|
||||
#define __PORTABLE_H
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h" /* Use " to include first in the same directory of this file */
|
||||
#endif
|
||||
|
||||
/***************************************************************************/
|
||||
/* Config */
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/**
|
||||
* Enable the GNU printf functions instead of using the MSVCRT ones.
|
||||
*
|
||||
* Note that this is the default if _POSIX is also defined.
|
||||
* To disable it you have to set it to 0.
|
||||
*/
|
||||
#define __USE_MINGW_ANSI_STDIO 1
|
||||
|
||||
/**
|
||||
* Define the MSVCRT version targetting Windows Vista.
|
||||
*/
|
||||
#define __MSVCRT_VERSION__ 0x0600
|
||||
|
||||
/**
|
||||
* Include Windows Vista headers.
|
||||
*
|
||||
* Like for InitializeCriticalSection().
|
||||
*/
|
||||
#define _WIN32_WINNT 0x600
|
||||
|
||||
/**
|
||||
* Enable the rand_s() function.l
|
||||
*/
|
||||
#define _CRT_RAND_S
|
||||
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Specify the format attribute for printf.
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
#if defined(__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO == 1
|
||||
#define attribute_printf gnu_printf /* GNU format */
|
||||
#else
|
||||
#define attribute_printf ms_printf /* MSVCRT format */
|
||||
#endif
|
||||
#else
|
||||
#define attribute_printf printf /* GNU format is the default one */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Compiler extension
|
||||
*/
|
||||
#ifndef __always_inline
|
||||
#define __always_inline inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
#ifndef __noreturn
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Architecture for inline assembly.
|
||||
*/
|
||||
#if HAVE_ASSEMBLY
|
||||
#if defined(__i386__)
|
||||
#define CONFIG_X86 1
|
||||
#define CONFIG_X86_32 1
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__)
|
||||
#define CONFIG_X86 1
|
||||
#define CONFIG_X86_64 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Includes some platform specific headers.
|
||||
*/
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_MOUNT_H
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_VFS_H
|
||||
#include <sys/vfs.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_STATFS_H
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_FILE_H
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_IOCTL_H
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LINUX_FS_H
|
||||
#include <linux/fs.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_LINUX_FIEMAP_H
|
||||
#include <linux/fiemap.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_BLKID_BLKID_H
|
||||
#include <blkid/blkid.h>
|
||||
#if HAVE_BLKID_DEVNO_TO_DEVNAME && HAVE_BLKID_GET_TAG_VALUE
|
||||
#define HAVE_BLKID 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Includes some standard headers.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* On many systems (e.g., Darwin), `stdio.h' is a prerequisite. */
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if TIME_WITH_SYS_TIME
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#else
|
||||
#if HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_MACH_MACH_TIME_H
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_DIRENT_H
|
||||
#include <dirent.h>
|
||||
#define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
#else
|
||||
#define dirent direct
|
||||
#define NAMLEN(dirent) (dirent)->d_namlen
|
||||
#if HAVE_SYS_NDIR_H
|
||||
#include <sys/ndir.h>
|
||||
#endif
|
||||
#if HAVE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#endif
|
||||
#if HAVE_NDIR_H
|
||||
#include <ndir.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if MAJOR_IN_MKDEV
|
||||
#include <sys/mkdev.h>
|
||||
#elif MAJOR_IN_SYSMACROS
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#ifndef WEXITSTATUS
|
||||
#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
|
||||
#endif
|
||||
#ifndef WIFEXITED
|
||||
#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_FNMATCH_H
|
||||
#include <fnmatch.h>
|
||||
#else
|
||||
#include "fnmatch.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_PTHREAD_H
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_MATH_H
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_EXECINFO_H
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Enable thread use.
|
||||
*/
|
||||
#if HAVE_PTHREAD_CREATE
|
||||
#define HAVE_PTHREAD 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Disable case check in Windows.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#define FNM_CASEINSENSITIVE_FOR_WIN FNM_CASEFOLD
|
||||
#else
|
||||
#define FNM_CASEINSENSITIVE_FOR_WIN 0
|
||||
#endif
|
||||
|
||||
#if HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
#define SWITCH_GETOPT_LONG(a, b) a
|
||||
#else
|
||||
#define SWITCH_GETOPT_LONG(a, b) b
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Enables lock file support.
|
||||
*/
|
||||
#if HAVE_FLOCK && HAVE_FTRUNCATE
|
||||
#define HAVE_LOCKFILE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Basic block position type.
|
||||
* With 32 bits and 128k blocks you can address 256 TB.
|
||||
*/
|
||||
typedef uint32_t block_off_t;
|
||||
|
||||
/**
|
||||
* Basic data position type.
|
||||
* It's signed as file size and offset are usually signed.
|
||||
*/
|
||||
typedef int64_t data_off_t;
|
||||
|
||||
/**
|
||||
* Includes specific support for Windows or Linux.
|
||||
*/
|
||||
#ifdef __MINGW32__
|
||||
#include "mingw.h"
|
||||
#else
|
||||
#include "unix.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Include list support to have tommy_node.
|
||||
*/
|
||||
#include "tommyds/tommylist.h"
|
||||
|
||||
/**
|
||||
* Another name for link() to avoid confusion with local variables called "link".
|
||||
*/
|
||||
static inline int hardlink(const char* a, const char* b)
|
||||
{
|
||||
return link(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the device UUID.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int devuuid(uint64_t device, char* uuid, size_t size);
|
||||
|
||||
/**
|
||||
* Physical offset not yet read.
|
||||
*/
|
||||
#define FILEPHY_UNREAD_OFFSET 0
|
||||
|
||||
/**
|
||||
* Special value returned when the file-system doesn't report any offset for unknown reason.
|
||||
*/
|
||||
#define FILEPHY_UNREPORTED_OFFSET 1
|
||||
|
||||
/**
|
||||
* Special value returned when the file doesn't have a real offset.
|
||||
* For example, because it's stored in the NTFS MFT.
|
||||
*/
|
||||
#define FILEPHY_WITHOUT_OFFSET 2
|
||||
|
||||
/**
|
||||
* Value indicating real offsets. All offsets greater or equal at this one are real.
|
||||
*/
|
||||
#define FILEPHY_REAL_OFFSET 3
|
||||
|
||||
/**
|
||||
* Get the physcal address of the specified file.
|
||||
* This is expected to be just a hint and not necessarily correct or unique.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int filephy(const char* path, uint64_t size, uint64_t* physical);
|
||||
|
||||
/**
|
||||
* Check if the underline file-system support persistent inodes.
|
||||
* Return -1 on error, 0 on success.
|
||||
*/
|
||||
int fsinfo(const char* path, int* has_persistent_inode, int* has_syncronized_hardlinks, uint64_t* total_space, uint64_t* free_space);
|
||||
|
||||
/**
|
||||
* Get the tick counter value.
|
||||
*
|
||||
* Note that the frequency is unspecified, because the time measure
|
||||
* is meant to be used to compare the ratio between usage times.
|
||||
*/
|
||||
uint64_t tick(void);
|
||||
|
||||
/**
|
||||
* Get the tick counter value in millisecond.
|
||||
*/
|
||||
uint64_t tick_ms(void);
|
||||
|
||||
/**
|
||||
* Initializes the system.
|
||||
*/
|
||||
void os_init(int opt);
|
||||
|
||||
/**
|
||||
* Deinitialize the system.
|
||||
*/
|
||||
void os_done(void);
|
||||
|
||||
/**
|
||||
* Abort the process with a stacktrace.
|
||||
*/
|
||||
void os_abort(void) __noreturn;
|
||||
|
||||
/**
|
||||
* Clear the screen.
|
||||
*/
|
||||
void os_clear(void);
|
||||
|
||||
/**
|
||||
* Log file.
|
||||
*
|
||||
* This stream if fully buffered.
|
||||
*
|
||||
* If no log file is selected, it's 0.
|
||||
*/
|
||||
FILE* stdlog;
|
||||
|
||||
/**
|
||||
* Exit codes for testing.
|
||||
*/
|
||||
int exit_success;
|
||||
int exit_failure;
|
||||
int exit_sync_needed;
|
||||
#undef EXIT_SUCCESS
|
||||
#undef EXIT_FAILURE
|
||||
#define EXIT_SUCCESS exit_success
|
||||
#define EXIT_FAILURE exit_failure
|
||||
#define EXIT_SYNC_NEEDED exit_sync_needed
|
||||
|
||||
/**
|
||||
* Fill memory with pseudo-random values.
|
||||
*/
|
||||
int randomize(void* ptr, size_t size);
|
||||
|
||||
/**
|
||||
* Standard SMART attributes.
|
||||
*/
|
||||
#define SMART_START_STOP_COUNT 4
|
||||
#define SMART_REALLOCATED_SECTOR_COUNT 5
|
||||
#define SMART_POWER_ON_HOURS 9
|
||||
#define SMART_AIRFLOW_TEMPERATURE_CELSIUS 190
|
||||
#define SMART_LOAD_CYCLE_COUNT 193
|
||||
#define SMART_TEMPERATURE_CELSIUS 194
|
||||
|
||||
/**
|
||||
* Additional SMART attributes.
|
||||
*/
|
||||
#define SMART_ERROR 256 /**< ATA Error count. */
|
||||
#define SMART_SIZE 257 /**< Size in bytes. */
|
||||
#define SMART_ROTATION_RATE 258 /**< Rotation speed. 0 for SSD. */
|
||||
#define SMART_FLAGS 259 /**< Flags returned by smartctl. */
|
||||
|
||||
/**
|
||||
* SMART attributes count.
|
||||
*/
|
||||
#define SMART_COUNT 260
|
||||
|
||||
/**
|
||||
* Flags returned by smartctl.
|
||||
*/
|
||||
#define SMARTCTL_FLAG_UNSUPPORTED (1 << 0) /**< Device not recognized, requiring the -d option. */
|
||||
#define SMARTCTL_FLAG_OPEN (1 << 1) /**< Device open or identification failed. */
|
||||
#define SMARTCTL_FLAG_COMMAND (1 << 2) /**< Some SMART or ATA commands failed. This is a common error, also happening with full info gathering. */
|
||||
#define SMARTCTL_FLAG_FAIL (1 << 3) /**< SMART status check returned "DISK FAILING". */
|
||||
#define SMARTCTL_FLAG_PREFAIL (1 << 4) /**< We found prefail Attributes <= threshold. */
|
||||
#define SMARTCTL_FLAG_PREFAIL_LOGGED (1 << 5) /**< SMART status check returned "DISK OK" but we found that some (usage or prefail) Attributes have been <= threshold at some time in the past. */
|
||||
#define SMARTCTL_FLAG_ERROR (1 << 6) /**< The device error log contains records of errors. */
|
||||
#define SMARTCTL_FLAG_ERROR_LOGGED (1 << 7) /**< The device self-test log contains records of errors. */
|
||||
|
||||
/**
|
||||
* SMART max attribute length.
|
||||
*/
|
||||
#define SMART_MAX 64
|
||||
|
||||
/**
|
||||
* Value for unassigned SMART attribute.
|
||||
*/
|
||||
#define SMART_UNASSIGNED 0xFFFFFFFFFFFFFFFFULL
|
||||
|
||||
/**
|
||||
* Device info entry.
|
||||
*/
|
||||
struct devinfo_struct {
|
||||
uint64_t device; /**< Device ID. */
|
||||
char name[PATH_MAX]; /**< Name of the disk. */
|
||||
char mount[PATH_MAX]; /**< Mount point or other contained directory. */
|
||||
char smartctl[PATH_MAX]; /**< Options for smartctl. */
|
||||
char file[PATH_MAX]; /**< File device. */
|
||||
#ifdef _WIN32
|
||||
char wfile[PATH_MAX]; /**< File device in Windows format. Like \\.\PhysicalDriveX, or \\?\Volume{X}. */
|
||||
#endif
|
||||
struct devinfo_struct* parent; /**< Pointer at the parent if any. */
|
||||
uint64_t smart[SMART_COUNT]; /**< SMART raw attributes. */
|
||||
char smart_serial[SMART_MAX]; /**< SMART serial number. */
|
||||
char smart_vendor[SMART_MAX]; /**< SMART vendor. */
|
||||
char smart_model[SMART_MAX]; /**< SMART model. */
|
||||
#if HAVE_PTHREAD
|
||||
pthread_t thread;
|
||||
#endif
|
||||
tommy_node node;
|
||||
};
|
||||
typedef struct devinfo_struct devinfo_t;
|
||||
|
||||
#define DEVICE_LIST 0
|
||||
#define DEVICE_DOWN 1
|
||||
#define DEVICE_UP 2
|
||||
#define DEVICE_SMART 3
|
||||
|
||||
/**
|
||||
* Query all the "high" level devices with the specified operation,
|
||||
* and produces a list of "low" level devices to operate on.
|
||||
*
|
||||
* The passed "low" device list must be already initialized.
|
||||
*/
|
||||
int devquery(tommy_list* high, tommy_list* low, int operation, int others);
|
||||
|
||||
#endif
|
||||
|
98
cmdline/rehash.c
Normal file
98
cmdline/rehash.c
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "elem.h"
|
||||
#include "import.h"
|
||||
#include "state.h"
|
||||
#include "parity.h"
|
||||
#include "handle.h"
|
||||
#include "raid/raid.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* rehash */
|
||||
|
||||
void state_rehash(struct snapraid_state* state)
|
||||
{
|
||||
block_off_t blockmax;
|
||||
block_off_t i;
|
||||
|
||||
blockmax = parity_allocated_size(state);
|
||||
|
||||
/* check if a rehash is already in progress */
|
||||
if (state->prevhash != HASH_UNDEFINED) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You already have a rehash in progress.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (state->hash == state->besthash) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You are already using the best hash for your platform.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* copy the present hash as previous one */
|
||||
state->prevhash = state->hash;
|
||||
memcpy(state->prevhashseed, state->hashseed, HASH_MAX);
|
||||
|
||||
/* set the new hash and seed */
|
||||
state->hash = state->besthash;
|
||||
if (randomize(state->hashseed, HASH_MAX) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed to get random values.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* mark all the block for rehashing */
|
||||
for (i = 0; i < blockmax; ++i) {
|
||||
snapraid_info info;
|
||||
|
||||
/* if it's unused */
|
||||
info = info_get(&state->infoarr, i);
|
||||
if (info == 0) {
|
||||
/* skip it */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info_get_rehash(info)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency for a rehash already in progress\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* enable the rehash */
|
||||
info = info_set_rehash(info);
|
||||
|
||||
/* save it */
|
||||
info_set(&state->infoarr, i, info);
|
||||
}
|
||||
|
||||
/* save the new content file */
|
||||
state->need_write = 1;
|
||||
|
||||
msg_status("A rehash is now scheduled. It will take place progressively in the next\n");
|
||||
msg_status("'sync' and 'scrub' commands. You can check the rehash progress using the\n");
|
||||
msg_status("'status' command.\n");
|
||||
}
|
||||
|
1926
cmdline/scan.c
Normal file
1926
cmdline/scan.c
Normal file
File diff suppressed because it is too large
Load Diff
902
cmdline/scrub.c
Normal file
902
cmdline/scrub.c
Normal file
@ -0,0 +1,902 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "parity.h"
|
||||
#include "handle.h"
|
||||
#include "io.h"
|
||||
#include "raid/raid.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* scrub */
|
||||
|
||||
/**
|
||||
* Buffer for storing the new hashes.
|
||||
*/
|
||||
struct snapraid_rehash {
|
||||
unsigned char hash[HASH_MAX];
|
||||
struct snapraid_block* block;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scrub plan to use.
|
||||
*/
|
||||
struct snapraid_plan {
|
||||
struct snapraid_state* state;
|
||||
int plan; /**< One of the SCRUB_*. */
|
||||
time_t timelimit; /**< Time limit. Valid only with SCRUB_AUTO. */
|
||||
block_off_t lastlimit; /**< Number of blocks allowed with time exactly at ::timelimit. */
|
||||
block_off_t countlast; /**< Counter of blocks with time exactly at ::timelimit. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if we have to process the specified block index ::i.
|
||||
*/
|
||||
static int block_is_enabled(void* void_plan, block_off_t i)
|
||||
{
|
||||
struct snapraid_plan* plan = void_plan;
|
||||
time_t blocktime;
|
||||
snapraid_info info;
|
||||
|
||||
/* don't scrub unused blocks in all plans */
|
||||
info = info_get(&plan->state->infoarr, i);
|
||||
if (info == 0)
|
||||
return 0;
|
||||
|
||||
/* bad blocks are always scrubbed in all plans */
|
||||
if (info_get_bad(info))
|
||||
return 1;
|
||||
|
||||
switch (plan->plan) {
|
||||
case SCRUB_FULL :
|
||||
/* in 'full' plan everything is scrubbed */
|
||||
return 1;
|
||||
case SCRUB_EVEN :
|
||||
/* in 'even' plan, scrub only even blocks */
|
||||
return i % 2 == 0;
|
||||
case SCRUB_NEW :
|
||||
/* in 'sync' plan, only blocks never scrubbed */
|
||||
return info_get_justsynced(info);
|
||||
case SCRUB_BAD :
|
||||
/* in 'bad' plan, only bad blocks (already reported) */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if it's too new */
|
||||
blocktime = info_get_time(info);
|
||||
if (blocktime > plan->timelimit) {
|
||||
/* skip it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if the time is less than the limit, always include */
|
||||
/* otherwise, check if we reached the last limit count */
|
||||
if (blocktime == plan->timelimit) {
|
||||
/* if we reached the count limit */
|
||||
if (plan->countlast >= plan->lastlimit) {
|
||||
/* skip it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
++plan->countlast;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_task* task)
|
||||
{
|
||||
struct snapraid_io* io = worker->io;
|
||||
struct snapraid_state* state = io->state;
|
||||
struct snapraid_handle* handle = worker->handle;
|
||||
struct snapraid_disk* disk = handle->disk;
|
||||
block_off_t blockcur = task->position;
|
||||
unsigned char* buffer = task->buffer;
|
||||
int ret;
|
||||
char esc_buffer[ESC_MAX];
|
||||
|
||||
/* if the disk position is not used */
|
||||
if (!disk) {
|
||||
/* use an empty block */
|
||||
memset(buffer, 0, state->block_size);
|
||||
task->state = TASK_STATE_DONE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the block */
|
||||
task->block = fs_par2block_find(disk, blockcur);
|
||||
|
||||
/* if the block is not used */
|
||||
if (!block_has_file(task->block)) {
|
||||
/* use an empty block */
|
||||
memset(buffer, 0, state->block_size);
|
||||
task->state = TASK_STATE_DONE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the file of this block */
|
||||
task->file = fs_par2file_get(disk, blockcur, &task->file_pos);
|
||||
|
||||
/* if the file is different than the current one, close it */
|
||||
if (handle->file != 0 && handle->file != task->file) {
|
||||
/* keep a pointer at the file we are going to close for error reporting */
|
||||
struct snapraid_file* report = handle->file;
|
||||
ret = handle_close(handle);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
/* This one is really an unexpected error, because we are only reading */
|
||||
/* and closing a descriptor should never fail */
|
||||
if (errno == EIO) {
|
||||
log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc_tag(report->sub, esc_buffer), strerror(errno));
|
||||
log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to scrub.\n");
|
||||
log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path);
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
task->state = TASK_STATE_IOERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(report->sub, esc_buffer), strerror(errno));
|
||||
log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to scrub.\n");
|
||||
log_fatal("Ensure that file '%s' can be accessed.\n", handle->path);
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
task->state = TASK_STATE_ERROR;
|
||||
return;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
ret = handle_open(handle, task->file, state->file_mode, log_error, 0);
|
||||
if (ret == -1) {
|
||||
if (errno == EIO) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno));
|
||||
log_fatal("DANGER! Unexpected input/output open error in a data disk, it isn't possible to scrub.\n");
|
||||
log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path);
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
task->state = TASK_STATE_IOERROR;
|
||||
return;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), strerror(errno));
|
||||
task->state = TASK_STATE_ERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* check if the file is changed */
|
||||
if (handle->st.st_size != task->file->size
|
||||
|| handle->st.st_mtime != task->file->mtime_sec
|
||||
|| STAT_NSEC(&handle->st) != task->file->mtime_nsec
|
||||
/* don't check the inode to support filesystem without persistent inodes */
|
||||
) {
|
||||
/* report that the block and the file are not synced */
|
||||
task->is_timestamp_different = 1;
|
||||
/* follow */
|
||||
}
|
||||
|
||||
/* note that we intentionally don't abort if the file has different attributes */
|
||||
/* from the last sync, as we are expected to return errors if running */
|
||||
/* in an unsynced array. This is just like the check command. */
|
||||
|
||||
task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0);
|
||||
if (task->read_size == -1) {
|
||||
if (errno == EIO) {
|
||||
log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno));
|
||||
log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos);
|
||||
task->state = TASK_STATE_IOERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc_tag(task->file->sub, esc_buffer), task->file_pos, strerror(errno));
|
||||
task->state = TASK_STATE_ERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the path of the opened file */
|
||||
pathcpy(task->path, sizeof(task->path), handle->path);
|
||||
|
||||
task->state = TASK_STATE_DONE;
|
||||
}
|
||||
|
||||
static void scrub_parity_reader(struct snapraid_worker* worker, struct snapraid_task* task)
|
||||
{
|
||||
struct snapraid_io* io = worker->io;
|
||||
struct snapraid_state* state = io->state;
|
||||
struct snapraid_parity_handle* parity_handle = worker->parity_handle;
|
||||
unsigned level = parity_handle->level;
|
||||
block_off_t blockcur = task->position;
|
||||
unsigned char* buffer = task->buffer;
|
||||
int ret;
|
||||
|
||||
/* read the parity */
|
||||
ret = parity_read(parity_handle, blockcur, buffer, state->block_size, log_error);
|
||||
if (ret == -1) {
|
||||
if (errno == EIO) {
|
||||
log_tag("parity_error:%u:%s: Read EIO error. %s\n", blockcur, lev_config_name(level), strerror(errno));
|
||||
log_error("Input/Output error in parity '%s' at position '%u'\n", lev_config_name(level), blockcur);
|
||||
task->state = TASK_STATE_IOERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
log_tag("parity_error:%u:%s: Read error. %s\n", blockcur, lev_config_name(level), strerror(errno));
|
||||
task->state = TASK_STATE_ERROR_CONTINUE;
|
||||
return;
|
||||
}
|
||||
|
||||
task->state = TASK_STATE_DONE;
|
||||
}
|
||||
|
||||
static int state_scrub_process(struct snapraid_state* state, struct snapraid_parity_handle* parity_handle, block_off_t blockstart, block_off_t blockmax, struct snapraid_plan* plan, time_t now)
|
||||
{
|
||||
struct snapraid_io io;
|
||||
struct snapraid_handle* handle;
|
||||
void* rehandle_alloc;
|
||||
struct snapraid_rehash* rehandle;
|
||||
unsigned diskmax;
|
||||
block_off_t blockcur;
|
||||
unsigned j;
|
||||
unsigned buffermax;
|
||||
data_off_t countsize;
|
||||
block_off_t countpos;
|
||||
block_off_t countmax;
|
||||
block_off_t autosavedone;
|
||||
block_off_t autosavelimit;
|
||||
block_off_t autosavemissing;
|
||||
int ret;
|
||||
unsigned error;
|
||||
unsigned silent_error;
|
||||
unsigned io_error;
|
||||
unsigned l;
|
||||
unsigned* waiting_map;
|
||||
unsigned waiting_mac;
|
||||
char esc_buffer[ESC_MAX];
|
||||
|
||||
/* maps the disks to handles */
|
||||
handle = handle_mapping(state, &diskmax);
|
||||
|
||||
/* rehash buffers */
|
||||
rehandle = malloc_nofail_align(diskmax * sizeof(struct snapraid_rehash), &rehandle_alloc);
|
||||
|
||||
/* we need 1 * data + 2 * parity */
|
||||
buffermax = diskmax + 2 * state->level;
|
||||
|
||||
/* initialize the io threads */
|
||||
io_init(&io, state, state->opt.io_cache, buffermax, scrub_data_reader, handle, diskmax, scrub_parity_reader, 0, parity_handle, state->level);
|
||||
|
||||
/* possibly waiting disks */
|
||||
waiting_mac = diskmax > RAID_PARITY_MAX ? diskmax : RAID_PARITY_MAX;
|
||||
waiting_map = malloc_nofail(waiting_mac * sizeof(unsigned));
|
||||
|
||||
error = 0;
|
||||
silent_error = 0;
|
||||
io_error = 0;
|
||||
|
||||
/* first count the number of blocks to process */
|
||||
countmax = 0;
|
||||
plan->countlast = 0;
|
||||
for (blockcur = blockstart; blockcur < blockmax; ++blockcur) {
|
||||
if (!block_is_enabled(plan, blockcur))
|
||||
continue;
|
||||
++countmax;
|
||||
}
|
||||
|
||||
/* compute the autosave size for all disk, even if not read */
|
||||
/* this makes sense because the speed should be almost the same */
|
||||
/* if the disks are read in parallel */
|
||||
autosavelimit = state->autosave / (diskmax * state->block_size);
|
||||
autosavemissing = countmax; /* blocks to do */
|
||||
autosavedone = 0; /* blocks done */
|
||||
|
||||
/* drop until now */
|
||||
state_usage_waste(state);
|
||||
|
||||
countsize = 0;
|
||||
countpos = 0;
|
||||
plan->countlast = 0;
|
||||
|
||||
/* start all the worker threads */
|
||||
io_start(&io, blockstart, blockmax, &block_is_enabled, plan);
|
||||
|
||||
state_progress_begin(state, blockstart, blockmax, countmax);
|
||||
while (1) {
|
||||
unsigned char* buffer_recov[LEV_MAX];
|
||||
snapraid_info info;
|
||||
int error_on_this_block;
|
||||
int silent_error_on_this_block;
|
||||
int io_error_on_this_block;
|
||||
int block_is_unsynced;
|
||||
int rehash;
|
||||
void** buffer;
|
||||
|
||||
/* go to the next block */
|
||||
blockcur = io_read_next(&io, &buffer);
|
||||
if (blockcur >= blockmax)
|
||||
break;
|
||||
|
||||
/* until now is scheduling */
|
||||
state_usage_sched(state);
|
||||
|
||||
/* one more block processed for autosave */
|
||||
++autosavedone;
|
||||
--autosavemissing;
|
||||
|
||||
/* by default process the block, and skip it if something goes wrong */
|
||||
error_on_this_block = 0;
|
||||
silent_error_on_this_block = 0;
|
||||
io_error_on_this_block = 0;
|
||||
|
||||
/* if all the blocks at this address are synced */
|
||||
/* if not, parity is not even checked */
|
||||
block_is_unsynced = 0;
|
||||
|
||||
/* get block specific info */
|
||||
info = info_get(&state->infoarr, blockcur);
|
||||
|
||||
/* if we have to use the old hash */
|
||||
rehash = info_get_rehash(info);
|
||||
|
||||
/* for each disk, process the block */
|
||||
for (j = 0; j < diskmax; ++j) {
|
||||
struct snapraid_task* task;
|
||||
int read_size;
|
||||
unsigned char hash[HASH_MAX];
|
||||
struct snapraid_block* block;
|
||||
int file_is_unsynced;
|
||||
struct snapraid_disk* disk;
|
||||
struct snapraid_file* file;
|
||||
block_off_t file_pos;
|
||||
unsigned diskcur;
|
||||
|
||||
/* if the file on this disk is synced */
|
||||
/* if not, silent errors are assumed as expected error */
|
||||
file_is_unsynced = 0;
|
||||
|
||||
/* until now is misc */
|
||||
state_usage_misc(state);
|
||||
|
||||
/* get the next task */
|
||||
task = io_data_read(&io, &diskcur, waiting_map, &waiting_mac);
|
||||
|
||||
/* until now is disk */
|
||||
state_usage_disk(state, handle, waiting_map, waiting_mac);
|
||||
|
||||
/* get the task results */
|
||||
disk = task->disk;
|
||||
block = task->block;
|
||||
file = task->file;
|
||||
file_pos = task->file_pos;
|
||||
read_size = task->read_size;
|
||||
|
||||
/* by default no rehash in case of "continue" */
|
||||
rehandle[diskcur].block = 0;
|
||||
|
||||
/* if the disk position is not used */
|
||||
if (!disk)
|
||||
continue;
|
||||
|
||||
state_usage_file(state, disk, file);
|
||||
|
||||
/* if the block is unsynced, errors are expected */
|
||||
if (block_has_invalid_parity(block)) {
|
||||
/* report that the block and the file are not synced */
|
||||
block_is_unsynced = 1;
|
||||
file_is_unsynced = 1;
|
||||
/* follow */
|
||||
}
|
||||
|
||||
/* if the block is not used */
|
||||
if (!block_has_file(block))
|
||||
continue;
|
||||
|
||||
/* if the block is unsynced, errors are expected */
|
||||
if (task->is_timestamp_different) {
|
||||
/* report that the block and the file are not synced */
|
||||
block_is_unsynced = 1;
|
||||
file_is_unsynced = 1;
|
||||
/* follow */
|
||||
}
|
||||
|
||||
/* handle error conditions */
|
||||
if (task->state == TASK_STATE_IOERROR) {
|
||||
/* LCOV_EXCL_START */
|
||||
++io_error;
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (task->state == TASK_STATE_ERROR) {
|
||||
/* LCOV_EXCL_START */
|
||||
++error;
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (task->state == TASK_STATE_ERROR_CONTINUE) {
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
continue;
|
||||
}
|
||||
if (task->state == TASK_STATE_IOERROR_CONTINUE) {
|
||||
++io_error;
|
||||
if (io_error >= state->opt.io_error_limit) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("DANGER! Too many input/output read error in a data disk, it isn't possible to scrub.\n");
|
||||
log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, task->path);
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* otherwise continue */
|
||||
io_error_on_this_block = 1;
|
||||
continue;
|
||||
}
|
||||
if (task->state != TASK_STATE_DONE) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in task state\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
countsize += read_size;
|
||||
|
||||
/* now compute the hash */
|
||||
if (rehash) {
|
||||
memhash(state->prevhash, state->prevhashseed, hash, buffer[diskcur], read_size);
|
||||
|
||||
/* compute the new hash, and store it */
|
||||
rehandle[diskcur].block = block;
|
||||
memhash(state->hash, state->hashseed, rehandle[diskcur].hash, buffer[diskcur], read_size);
|
||||
} else {
|
||||
memhash(state->hash, state->hashseed, hash, buffer[diskcur], read_size);
|
||||
}
|
||||
|
||||
/* until now is hash */
|
||||
state_usage_hash(state);
|
||||
|
||||
if (block_has_updated_hash(block)) {
|
||||
/* compare the hash */
|
||||
if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) {
|
||||
unsigned diff = memdiff(hash, block->hash, BLOCK_HASH_SIZE);
|
||||
|
||||
log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u/%u\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), file_pos, diff, BLOCK_HASH_SIZE * 8);
|
||||
|
||||
/* it's a silent error only if we are dealing with synced files */
|
||||
if (file_is_unsynced) {
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
} else {
|
||||
log_error("Data error in file '%s' at position '%u', diff bits %u/%u\n", task->path, file_pos, diff, BLOCK_HASH_SIZE * 8);
|
||||
++silent_error;
|
||||
silent_error_on_this_block = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* buffers for parity read and not computed */
|
||||
for (l = 0; l < state->level; ++l)
|
||||
buffer_recov[l] = buffer[diskmax + state->level + l];
|
||||
for (; l < LEV_MAX; ++l)
|
||||
buffer_recov[l] = 0;
|
||||
|
||||
/* until now is misc */
|
||||
state_usage_misc(state);
|
||||
|
||||
/* read the parity */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
struct snapraid_task* task;
|
||||
unsigned levcur;
|
||||
|
||||
task = io_parity_read(&io, &levcur, waiting_map, &waiting_mac);
|
||||
|
||||
/* until now is parity */
|
||||
state_usage_parity(state, waiting_map, waiting_mac);
|
||||
|
||||
/* handle error conditions */
|
||||
if (task->state == TASK_STATE_IOERROR) {
|
||||
/* LCOV_EXCL_START */
|
||||
++io_error;
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (task->state == TASK_STATE_ERROR) {
|
||||
/* LCOV_EXCL_START */
|
||||
++error;
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (task->state == TASK_STATE_ERROR_CONTINUE) {
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
|
||||
/* if continuing on error, clear the missing buffer */
|
||||
buffer_recov[levcur] = 0;
|
||||
continue;
|
||||
}
|
||||
if (task->state == TASK_STATE_IOERROR_CONTINUE) {
|
||||
++io_error;
|
||||
if (io_error >= state->opt.io_error_limit) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("DANGER! Too many input/output read error in the %s disk, it isn't possible to scrub.\n", lev_name(levcur));
|
||||
log_fatal("Ensure that disk '%s' is sane and can be read.\n", lev_config_name(levcur));
|
||||
log_fatal("Stopping at block %u\n", blockcur);
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* otherwise continue */
|
||||
io_error_on_this_block = 1;
|
||||
|
||||
/* if continuing on error, clear the missing buffer */
|
||||
buffer_recov[levcur] = 0;
|
||||
continue;
|
||||
}
|
||||
if (task->state != TASK_STATE_DONE) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in task state\n");
|
||||
os_abort();
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have read all the data required and it's correct, proceed with the parity check */
|
||||
if (!error_on_this_block && !silent_error_on_this_block && !io_error_on_this_block) {
|
||||
|
||||
/* compute the parity */
|
||||
raid_gen(diskmax, state->level, state->block_size, buffer);
|
||||
|
||||
/* compare the parity */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
if (buffer_recov[l] && memcmp(buffer[diskmax + l], buffer_recov[l], state->block_size) != 0) {
|
||||
unsigned diff = memdiff(buffer[diskmax + l], buffer_recov[l], state->block_size);
|
||||
|
||||
log_tag("parity_error:%u:%s: Data error, diff bits %u/%u\n", blockcur, lev_config_name(l), diff, state->block_size * 8);
|
||||
|
||||
/* it's a silent error only if we are dealing with synced blocks */
|
||||
if (block_is_unsynced) {
|
||||
++error;
|
||||
error_on_this_block = 1;
|
||||
} else {
|
||||
log_fatal("Data error in parity '%s' at position '%u', diff bits %u/%u\n", lev_config_name(l), blockcur, diff, state->block_size * 8);
|
||||
++silent_error;
|
||||
silent_error_on_this_block = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* until now is raid */
|
||||
state_usage_raid(state);
|
||||
}
|
||||
|
||||
if (silent_error_on_this_block || io_error_on_this_block) {
|
||||
/* set the error status keeping other info */
|
||||
info_set(&state->infoarr, blockcur, info_set_bad(info));
|
||||
} else if (error_on_this_block) {
|
||||
/* do nothing, as this is a generic error */
|
||||
/* likely caused by a not synced array */
|
||||
} else {
|
||||
/* if rehash is needed */
|
||||
if (rehash) {
|
||||
/* store all the new hash already computed */
|
||||
for (j = 0; j < diskmax; ++j) {
|
||||
if (rehandle[j].block)
|
||||
memcpy(rehandle[j].block->hash, rehandle[j].hash, BLOCK_HASH_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* update the time info of the block */
|
||||
/* and clear any other flag */
|
||||
info_set(&state->infoarr, blockcur, info_make(now, 0, 0, 0));
|
||||
}
|
||||
|
||||
/* mark the state as needing write */
|
||||
state->need_write = 1;
|
||||
|
||||
/* count the number of processed block */
|
||||
++countpos;
|
||||
|
||||
/* progress */
|
||||
if (state_progress(state, &io, blockcur, countpos, countmax, countsize)) {
|
||||
/* LCOV_EXCL_START */
|
||||
break;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* autosave */
|
||||
if (state->autosave != 0
|
||||
&& autosavedone >= autosavelimit /* if we have reached the limit */
|
||||
&& autosavemissing >= autosavelimit /* if we have at least a full step to do */
|
||||
) {
|
||||
autosavedone = 0; /* restart the counter */
|
||||
|
||||
/* until now is misc */
|
||||
state_usage_misc(state);
|
||||
|
||||
state_progress_stop(state);
|
||||
|
||||
msg_progress("Autosaving...\n");
|
||||
state_write(state);
|
||||
|
||||
state_progress_restart(state);
|
||||
|
||||
/* drop until now */
|
||||
state_usage_waste(state);
|
||||
}
|
||||
}
|
||||
|
||||
state_progress_end(state, countpos, countmax, countsize);
|
||||
|
||||
state_usage_print(state);
|
||||
|
||||
if (error || silent_error || io_error) {
|
||||
msg_status("\n");
|
||||
msg_status("%8u file errors\n", error);
|
||||
msg_status("%8u io errors\n", io_error);
|
||||
msg_status("%8u data errors\n", silent_error);
|
||||
} else {
|
||||
/* print the result only if processed something */
|
||||
if (countpos != 0)
|
||||
msg_status("Everything OK\n");
|
||||
}
|
||||
|
||||
if (error)
|
||||
log_fatal("WARNING! Unexpected file errors!\n");
|
||||
if (io_error)
|
||||
log_fatal("DANGER! Unexpected input/output errors! The failing blocks are now marked as bad!\n");
|
||||
if (silent_error)
|
||||
log_fatal("DANGER! Unexpected data errors! The failing blocks are now marked as bad!\n");
|
||||
if (io_error || silent_error) {
|
||||
log_fatal("Use 'snapraid status' to list the bad blocks.\n");
|
||||
log_fatal("Use 'snapraid -e fix' to recover.\n");
|
||||
}
|
||||
|
||||
log_tag("summary:error_file:%u\n", error);
|
||||
log_tag("summary:error_io:%u\n", io_error);
|
||||
log_tag("summary:error_data:%u\n", silent_error);
|
||||
if (error + silent_error + io_error == 0)
|
||||
log_tag("summary:exit:ok\n");
|
||||
else
|
||||
log_tag("summary:exit:error\n");
|
||||
log_flush();
|
||||
|
||||
bail:
|
||||
/* stop all the worker threads */
|
||||
io_stop(&io);
|
||||
|
||||
for (j = 0; j < diskmax; ++j) {
|
||||
struct snapraid_file* file = handle[j].file;
|
||||
struct snapraid_disk* disk = handle[j].disk;
|
||||
ret = handle_close(&handle[j]);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc_tag(file->sub, esc_buffer), strerror(errno));
|
||||
log_fatal("DANGER! Unexpected close error in a data disk.\n");
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
free(handle);
|
||||
free(rehandle_alloc);
|
||||
free(waiting_map);
|
||||
io_done(&io);
|
||||
|
||||
if (state->opt.expect_recoverable) {
|
||||
if (error + silent_error + io_error == 0)
|
||||
return -1;
|
||||
} else {
|
||||
if (error + silent_error + io_error != 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a * b / c approximated to the upper value.
|
||||
*/
|
||||
static uint32_t md(uint32_t a, uint32_t b, uint32_t c)
|
||||
{
|
||||
uint64_t v = a;
|
||||
|
||||
v *= b;
|
||||
v += c - 1;
|
||||
v /= c;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
int state_scrub(struct snapraid_state* state, int plan, int olderthan)
|
||||
{
|
||||
block_off_t blockmax;
|
||||
block_off_t countlimit;
|
||||
block_off_t i;
|
||||
block_off_t count;
|
||||
time_t recentlimit;
|
||||
int ret;
|
||||
struct snapraid_parity_handle parity_handle[LEV_MAX];
|
||||
struct snapraid_plan ps;
|
||||
time_t* timemap;
|
||||
unsigned error;
|
||||
time_t now;
|
||||
unsigned l;
|
||||
|
||||
/* get the present time */
|
||||
now = time(0);
|
||||
|
||||
msg_progress("Initializing...\n");
|
||||
|
||||
if ((plan == SCRUB_BAD || plan == SCRUB_NEW || plan == SCRUB_FULL)
|
||||
&& olderthan >= 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("You can specify -o, --older-than only with a numeric percentage.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
blockmax = parity_allocated_size(state);
|
||||
|
||||
/* preinitialize to avoid warnings */
|
||||
countlimit = 0;
|
||||
recentlimit = 0;
|
||||
|
||||
ps.state = state;
|
||||
if (state->opt.force_scrub_even) {
|
||||
ps.plan = SCRUB_EVEN;
|
||||
} else if (plan == SCRUB_FULL) {
|
||||
ps.plan = SCRUB_FULL;
|
||||
} else if (plan == SCRUB_NEW) {
|
||||
ps.plan = SCRUB_NEW;
|
||||
} else if (plan == SCRUB_BAD) {
|
||||
ps.plan = SCRUB_BAD;
|
||||
} else if (state->opt.force_scrub_at) {
|
||||
/* scrub the specified amount of blocks */
|
||||
ps.plan = SCRUB_AUTO;
|
||||
countlimit = state->opt.force_scrub_at;
|
||||
recentlimit = now;
|
||||
} else {
|
||||
ps.plan = SCRUB_AUTO;
|
||||
if (plan >= 0) {
|
||||
countlimit = md(blockmax, plan, 100);
|
||||
} else {
|
||||
/* by default scrub 8.33% of the array (100/12=8.(3)) */
|
||||
countlimit = md(blockmax, 1, 12);
|
||||
}
|
||||
|
||||
if (olderthan >= 0) {
|
||||
recentlimit = now - olderthan * 24 * 3600;
|
||||
} else {
|
||||
/* by default use a 10 day time limit */
|
||||
recentlimit = now - 10 * 24 * 3600;
|
||||
}
|
||||
}
|
||||
|
||||
/* identify the time limit */
|
||||
/* we sort all the block times, and we identify the time limit for which we reach the quota */
|
||||
/* this allow to process first the oldest blocks */
|
||||
timemap = malloc_nofail(blockmax * sizeof(time_t));
|
||||
|
||||
/* copy the info in the temp vector */
|
||||
count = 0;
|
||||
log_tag("block_count:%u\n", blockmax);
|
||||
for (i = 0; i < blockmax; ++i) {
|
||||
snapraid_info info = info_get(&state->infoarr, i);
|
||||
|
||||
/* skip unused blocks */
|
||||
if (info == 0)
|
||||
continue;
|
||||
|
||||
timemap[count++] = info_get_time(info);
|
||||
}
|
||||
|
||||
if (!count) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("The array appears to be empty.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* sort it */
|
||||
qsort(timemap, count, sizeof(time_t), time_compare);
|
||||
|
||||
/* output the info map */
|
||||
i = 0;
|
||||
log_tag("info_count:%u\n", count);
|
||||
while (i < count) {
|
||||
unsigned j = i + 1;
|
||||
while (j < count && timemap[i] == timemap[j])
|
||||
++j;
|
||||
log_tag("info_time:%" PRIu64 ":%u\n", (uint64_t)timemap[i], j - i);
|
||||
i = j;
|
||||
}
|
||||
|
||||
/* compute the limits from count/recentlimit */
|
||||
if (ps.plan == SCRUB_AUTO) {
|
||||
/* no more than the full count */
|
||||
if (countlimit > count)
|
||||
countlimit = count;
|
||||
|
||||
/* decrease until we reach the specific recentlimit */
|
||||
while (countlimit > 0 && timemap[countlimit - 1] > recentlimit)
|
||||
--countlimit;
|
||||
|
||||
/* if there is something to scrub */
|
||||
if (countlimit > 0) {
|
||||
/* get the most recent time we want to scrub */
|
||||
ps.timelimit = timemap[countlimit - 1];
|
||||
|
||||
/* count how many entries for this exact time we have to scrub */
|
||||
/* if the blocks have all the same time, we end with countlimit == lastlimit */
|
||||
ps.lastlimit = 1;
|
||||
while (countlimit > ps.lastlimit && timemap[countlimit - ps.lastlimit - 1] == ps.timelimit)
|
||||
++ps.lastlimit;
|
||||
} else {
|
||||
/* if nothing to scrub, disable also other limits */
|
||||
ps.timelimit = 0;
|
||||
ps.lastlimit = 0;
|
||||
}
|
||||
|
||||
log_tag("count_limit:%u\n", countlimit);
|
||||
log_tag("time_limit:%" PRIu64 "\n", (uint64_t)ps.timelimit);
|
||||
log_tag("last_limit:%u\n", ps.lastlimit);
|
||||
}
|
||||
|
||||
/* free the temp vector */
|
||||
free(timemap);
|
||||
|
||||
/* open the file for reading */
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
ret = parity_open(&parity_handle[l], &state->parity[l], l, state->file_mode, state->block_size, state->opt.parity_limit_size);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("WARNING! Without an accessible %s file, it isn't possible to scrub.\n", lev_name(l));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
msg_progress("Scrubbing...\n");
|
||||
|
||||
error = 0;
|
||||
|
||||
ret = state_scrub_process(state, parity_handle, 0, blockmax, &ps, now);
|
||||
if (ret == -1) {
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
}
|
||||
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
ret = parity_close(&parity_handle[l]);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("DANGER! Unexpected close error in %s disk.\n", lev_name(l));
|
||||
++error;
|
||||
/* continue, as we are already exiting */
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* abort if required */
|
||||
if (error != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
287
cmdline/search.c
Normal file
287
cmdline/search.c
Normal file
@ -0,0 +1,287 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "search.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* search */
|
||||
|
||||
static void search_file(struct snapraid_state* state, const char* path, data_off_t size, int64_t mtime_sec, int mtime_nsec)
|
||||
{
|
||||
struct snapraid_search_file* file;
|
||||
tommy_uint32_t file_hash;
|
||||
|
||||
file = malloc_nofail(sizeof(struct snapraid_search_file));
|
||||
file->path = strdup_nofail(path);
|
||||
file->size = size;
|
||||
file->mtime_sec = mtime_sec;
|
||||
file->mtime_nsec = mtime_nsec;
|
||||
|
||||
file_hash = file_stamp_hash(file->size, file->mtime_sec, file->mtime_nsec);
|
||||
|
||||
tommy_hashdyn_insert(&state->searchset, &file->node, file, file_hash);
|
||||
}
|
||||
|
||||
void search_file_free(struct snapraid_search_file* file)
|
||||
{
|
||||
free(file->path);
|
||||
free(file);
|
||||
}
|
||||
|
||||
struct search_file_compare_arg {
|
||||
const struct snapraid_state* state;
|
||||
const struct snapraid_block* block;
|
||||
const struct snapraid_file* file;
|
||||
unsigned char* buffer;
|
||||
data_off_t offset;
|
||||
unsigned read_size;
|
||||
int prevhash;
|
||||
};
|
||||
|
||||
int search_file_compare(const void* void_arg, const void* void_data)
|
||||
{
|
||||
const struct search_file_compare_arg* arg = void_arg;
|
||||
const struct snapraid_search_file* file = void_data;
|
||||
const struct snapraid_state* state = arg->state;
|
||||
unsigned char buffer_hash[HASH_MAX];
|
||||
const char* path = file->path;
|
||||
int f;
|
||||
ssize_t ret;
|
||||
|
||||
/* compare file info */
|
||||
if (arg->file->size != file->size)
|
||||
return -1;
|
||||
|
||||
if (arg->file->mtime_sec != file->mtime_sec)
|
||||
return -1;
|
||||
|
||||
if (arg->file->mtime_nsec != file->mtime_nsec)
|
||||
return -1;
|
||||
|
||||
/* read the block and compare the hash */
|
||||
f = open(path, O_RDONLY | O_BINARY);
|
||||
if (f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
if (errno == ENOENT) {
|
||||
log_fatal("DANGER! file '%s' disappeared.\n", path);
|
||||
log_fatal("If you moved it, please rerun the same command.\n");
|
||||
} else {
|
||||
log_fatal("Error opening file '%s'. %s.\n", path, strerror(errno));
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = pread(f, arg->buffer, arg->read_size, arg->offset);
|
||||
if (ret < 0 || (unsigned)ret != arg->read_size) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reading file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = close(f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file '%s'. %s.\n", path, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* compute the hash */
|
||||
if (arg->prevhash)
|
||||
memhash(state->prevhash, state->prevhashseed, buffer_hash, arg->buffer, arg->read_size);
|
||||
else
|
||||
memhash(state->hash, state->hashseed, buffer_hash, arg->buffer, arg->read_size);
|
||||
|
||||
/* check if the hash is matching */
|
||||
if (memcmp(buffer_hash, arg->block->hash, BLOCK_HASH_SIZE) != 0)
|
||||
return -1;
|
||||
|
||||
if (arg->read_size != state->block_size) {
|
||||
/* fill the remaining with 0 */
|
||||
memset(arg->buffer + arg->read_size, 0, state->block_size - arg->read_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapraid_file* missing_file, block_off_t missing_file_pos, struct snapraid_block* missing_block, unsigned char* buffer)
|
||||
{
|
||||
struct snapraid_search_file* file;
|
||||
tommy_uint32_t file_hash;
|
||||
struct search_file_compare_arg arg;
|
||||
|
||||
arg.state = state;
|
||||
arg.block = missing_block;
|
||||
arg.file = missing_file;
|
||||
arg.buffer = buffer;
|
||||
arg.offset = state->block_size * (data_off_t)missing_file_pos;
|
||||
arg.read_size = file_block_size(missing_file, missing_file_pos, state->block_size);
|
||||
arg.prevhash = prevhash;
|
||||
|
||||
file_hash = file_stamp_hash(arg.file->size, arg.file->mtime_sec, arg.file->mtime_nsec);
|
||||
|
||||
/* search in the hashtable, and also check if the data matches the hash */
|
||||
file = tommy_hashdyn_search(&state->searchset, search_file_compare, &arg, file_hash);
|
||||
if (!file)
|
||||
return -1;
|
||||
|
||||
/* if found, buffer is already set with data */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void search_dir(struct snapraid_state* state, struct snapraid_disk* disk, const char* dir, const char* sub)
|
||||
{
|
||||
DIR* d;
|
||||
|
||||
d = opendir(dir);
|
||||
if (!d) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
while (1) {
|
||||
char path_next[PATH_MAX];
|
||||
char sub_next[PATH_MAX];
|
||||
char out[PATH_MAX];
|
||||
struct snapraid_filter* reason = 0;
|
||||
struct stat st;
|
||||
const char* name;
|
||||
struct dirent* dd;
|
||||
|
||||
/* clear errno to detect erroneous conditions */
|
||||
errno = 0;
|
||||
dd = readdir(d);
|
||||
if (dd == 0 && errno != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reading directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (dd == 0) {
|
||||
break; /* finished */
|
||||
}
|
||||
|
||||
/* skip "." and ".." files */
|
||||
name = dd->d_name;
|
||||
if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0)))
|
||||
continue;
|
||||
|
||||
pathprint(path_next, sizeof(path_next), "%s%s", dir, name);
|
||||
pathprint(sub_next, sizeof(sub_next), "%s%s", sub, name);
|
||||
|
||||
/* exclude hidden files even before calling lstat() */
|
||||
if (disk != 0 && filter_hidden(state->filter_hidden, dd) != 0) {
|
||||
msg_verbose("Excluding hidden '%s'\n", path_next);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* exclude content files even before calling lstat() */
|
||||
if (disk != 0 && filter_content(&state->contentlist, path_next) != 0) {
|
||||
msg_verbose("Excluding content '%s'\n", path_next);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if HAVE_STRUCT_DIRENT_D_STAT
|
||||
/* convert dirent to lstat result */
|
||||
dirent_lstat(dd, &st);
|
||||
|
||||
/* if the st_mode field is missing, takes care to fill it using normal lstat() */
|
||||
/* at now this can happen only in Windows (with HAVE_STRUCT_DIRENT_D_STAT defined), */
|
||||
/* because we use a directory reading method that doesn't read info about ReparsePoint. */
|
||||
/* Note that here we cannot call here lstat_sync(), because we don't know what kind */
|
||||
/* of file is it, and lstat_sync() doesn't always work */
|
||||
if (st.st_mode == 0) {
|
||||
if (lstat(path_next, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* get lstat info about the file */
|
||||
if (lstat(path_next, &st) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error in stat file/directory '%s'. %s.\n", path_next, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
if (disk == 0 || filter_path(&state->filterlist, &reason, disk->name, sub_next) == 0) {
|
||||
search_file(state, path_next, st.st_size, st.st_mtime, STAT_NSEC(&st));
|
||||
} else {
|
||||
msg_verbose("Excluding link '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
|
||||
}
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
if (disk == 0 || filter_subdir(&state->filterlist, &reason, disk->name, sub_next) == 0) {
|
||||
pathslash(path_next, sizeof(path_next));
|
||||
pathslash(sub_next, sizeof(sub_next));
|
||||
search_dir(state, disk, path_next, sub_next);
|
||||
} else {
|
||||
msg_verbose("Excluding directory '%s' for rule '%s'\n", path_next, filter_type(reason, out, sizeof(out)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closedir(d) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
void state_search(struct snapraid_state* state, const char* dir)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
|
||||
msg_progress("Importing...\n");
|
||||
|
||||
/* add the final slash */
|
||||
pathimport(path, sizeof(path), dir);
|
||||
pathslash(path, sizeof(path));
|
||||
|
||||
search_dir(state, 0, path, "");
|
||||
}
|
||||
|
||||
void state_search_array(struct snapraid_state* state)
|
||||
{
|
||||
tommy_node* i;
|
||||
|
||||
/* import from all the disks */
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
struct snapraid_disk* disk = i->data;
|
||||
|
||||
/* skip data disks that are not accessible */
|
||||
if (disk->skip_access)
|
||||
continue;
|
||||
|
||||
msg_progress("Searching disk %s...\n", disk->name);
|
||||
|
||||
search_dir(state, disk, disk->dir, "");
|
||||
}
|
||||
}
|
||||
|
64
cmdline/search.h
Normal file
64
cmdline/search.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SEARCH_H
|
||||
#define __SEARCH_H
|
||||
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* search */
|
||||
|
||||
/**
|
||||
* Search file.
|
||||
* File used to search for moved data.
|
||||
*/
|
||||
struct snapraid_search_file {
|
||||
char* path; /**< Full path of the file. */
|
||||
char* name; /**< Pointer of the name inside the path. */
|
||||
data_off_t size;
|
||||
int64_t mtime_sec;
|
||||
int mtime_nsec;
|
||||
|
||||
/* nodes for data structures */
|
||||
tommy_node node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deallocate a search file.
|
||||
*/
|
||||
void search_file_free(struct snapraid_search_file* file);
|
||||
|
||||
/**
|
||||
* Fetch a file from the size, timestamp and name.
|
||||
* Return ==0 if the block is found, and copied into buffer.
|
||||
*/
|
||||
int state_search_fetch(struct snapraid_state* state, int prevhash, struct snapraid_file* missing_file, block_off_t missing_file_pos, struct snapraid_block* missing_block, unsigned char* buffer);
|
||||
|
||||
/**
|
||||
* Import files from the specified directory.
|
||||
*/
|
||||
void state_search(struct snapraid_state* state, const char* dir);
|
||||
|
||||
/**
|
||||
* Import files from all the data disks.
|
||||
*/
|
||||
void state_search_array(struct snapraid_state* state);
|
||||
|
||||
#endif
|
||||
|
640
cmdline/selftest.c
Normal file
640
cmdline/selftest.c
Normal file
@ -0,0 +1,640 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "snapraid.h"
|
||||
#include "util.h"
|
||||
#include "raid/raid.h"
|
||||
#include "raid/cpu.h"
|
||||
#include "raid/combo.h"
|
||||
#include "raid/internal.h"
|
||||
#include "raid/test.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "support.h"
|
||||
#include "tommyds/tommyhash.h"
|
||||
#include "tommyds/tommyarray.h"
|
||||
#include "tommyds/tommyarrayblkof.h"
|
||||
#include "tommyds/tommyhashdyn.h"
|
||||
|
||||
struct hash32_test_vector {
|
||||
const char* data;
|
||||
int len;
|
||||
uint32_t digest;
|
||||
};
|
||||
|
||||
struct strhash32_test_vector {
|
||||
char* data;
|
||||
uint32_t digest;
|
||||
};
|
||||
|
||||
struct hash64_test_vector {
|
||||
const char* data;
|
||||
int len;
|
||||
uint64_t digest;
|
||||
};
|
||||
|
||||
struct hash_test_vector {
|
||||
const char* data;
|
||||
int len;
|
||||
unsigned char digest[HASH_MAX];
|
||||
};
|
||||
|
||||
/**
|
||||
* Test vectors for tommy_hash32
|
||||
*/
|
||||
static struct hash32_test_vector TEST_HASH32[] = {
|
||||
{ "", 0, 0x8614384c },
|
||||
{ "a", 1, 0x12c16c36 },
|
||||
{ "abc", 3, 0xc58e8af5 },
|
||||
{ "message digest", 14, 0x006b32f1 },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 26, 0x7e6fcfe0 },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, 0x8604adf8 },
|
||||
{ "The quick brown fox jumps over the lazy dog", 43, 0xdeba3d3a },
|
||||
{ "\x00", 1, 0x4a7d1c33 },
|
||||
{ "\x16\x27", 2, 0x8b50899b },
|
||||
{ "\xe2\x56\xb4", 3, 0x60406493 },
|
||||
{ "\xc9\x4d\x9c\xda", 4, 0xa049144a },
|
||||
{ "\x79\xf1\x29\x69\x5d", 5, 0x4da2c2f1 },
|
||||
{ "\x00\x7e\xdf\x1e\x31\x1c", 6, 0x59de30cf },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 7, 0x219e149c },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 8, 0x25067520 },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 9, 0xa1f368d8 },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 10, 0x805fc63d },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\x00\xb7\xae", 11, 0x7f75dd0f },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 12, 0xb9154382 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
/**
|
||||
* Test vectors for tommy_strhash32
|
||||
*/
|
||||
struct strhash32_test_vector TEST_STRHASH32[] = {
|
||||
{ "", 0x0af1416d },
|
||||
{ "a", 0x68fa0f3f },
|
||||
{ "abc", 0xfc68ffc5 },
|
||||
{ "message digest", 0x08477b63 },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 0x5b9c25e5 },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0x1e530ce7 },
|
||||
{ "The quick brown fox jumps over the lazy dog", 0xaf93eefe },
|
||||
{ "\xff", 0xfc88801b },
|
||||
{ "\x16\x27", 0xcd7216db },
|
||||
{ "\xe2\x56\xb4", 0x05f98d02 },
|
||||
{ "\xc9\x4d\x9c\xda", 0xf65206f8 },
|
||||
{ "\x79\xf1\x29\x69\x5d", 0x72bd6bda },
|
||||
{ "\xff\x7e\xdf\x1e\x31\x1c", 0x57dfb9b4 },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 0x499ff634 },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 0xe896b7ce },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 0xfe3939f0 },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 0x4351d482 },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\xff\xb7\xae", 0x88e92135 },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 0x01109c16 },
|
||||
{ "\x87\xd8\x61\x61\x4c\x89\x17\x4e\xa1\xa4\xef\x13\xa9", 0xbcb050dc },
|
||||
{ "\xfe\xa6\x5b\xc2\xda\xe8\x95\xd4\x64\xab\x4c\x39\x58\x29", 0xbe5e1fd5 },
|
||||
{ "\x94\x49\xc0\x78\xa0\x80\xda\xc7\x71\x4e\x17\x37\xa9\x7c\x40", 0x70d8c97f },
|
||||
{ "\x53\x7e\x36\xb4\x2e\xc9\xb9\xcc\x18\x3e\x9a\x5f\xfc\xb7\xb0\x61", 0x957440a9 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
/**
|
||||
* Test vectors for tommy_hash64
|
||||
*/
|
||||
static struct hash64_test_vector TEST_HASH64[] = {
|
||||
{ "", 0, 0x8614384cb5165fbfULL },
|
||||
{ "a", 1, 0x1a2e0298a8e94a3dULL },
|
||||
{ "abc", 3, 0x7555796b7a7d21ebULL },
|
||||
{ "message digest", 14, 0x9411a57d04b92fb4ULL },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 26, 0x3ca3f8d2b4e69832ULL },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, 0x6dae542ba0015a4dULL },
|
||||
{ "The quick brown fox jumps over the lazy dog", 43, 0xe06d8cbb3d2ea1a6ULL },
|
||||
{ "\x00", 1, 0x201e664fb5f2c021ULL },
|
||||
{ "\x16\x27", 2, 0xef42fa8032c4b775ULL },
|
||||
{ "\xe2\x56\xb4", 3, 0x6e6c498a6688466cULL },
|
||||
{ "\xc9\x4d\x9c\xda", 4, 0x5195005419905423ULL },
|
||||
{ "\x79\xf1\x29\x69\x5d", 5, 0x221235b48afee7c1ULL },
|
||||
{ "\x00\x7e\xdf\x1e\x31\x1c", 6, 0x1b1f18b9266f095bULL },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 7, 0x2cbafa8e741d49caULL },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 8, 0x4677f04c06e0758dULL },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 9, 0x5afe09e8214e2163ULL },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 10, 0x115b6276d209fab6ULL },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\x00\xb7\xae", 11, 0xd0636d2f01cf3a3eULL },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 12, 0x6d259f5fef74f93eULL },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
/**
|
||||
* Test vectors for MurmorHash3_x86_128
|
||||
*/
|
||||
static struct hash_test_vector TEST_MURMUR3[] = {
|
||||
#include "murmur3test.c"
|
||||
{ 0, 0, { 0 } }
|
||||
};
|
||||
|
||||
/**
|
||||
* Test vectors for SpookyHash_128
|
||||
*/
|
||||
static struct hash_test_vector TEST_SPOOKY2[] = {
|
||||
#include "spooky2test.c"
|
||||
{ 0, 0, { 0 } }
|
||||
};
|
||||
|
||||
#define HASH_TEST_MAX 512 /* tests are never longer than 512 bytes */
|
||||
|
||||
static void test_hash(void)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned char* seed_aligned;
|
||||
void* seed_alloc;
|
||||
unsigned char* buffer_aligned;
|
||||
void* buffer_alloc;
|
||||
uint32_t seed32;
|
||||
uint64_t seed64;
|
||||
|
||||
seed_aligned = malloc_nofail_align(HASH_MAX, &seed_alloc);
|
||||
buffer_aligned = malloc_nofail_align(HASH_TEST_MAX, &buffer_alloc);
|
||||
|
||||
seed32 = 0xa766795d;
|
||||
seed64 = 0x2f022773a766795dULL;
|
||||
|
||||
seed_aligned[0] = 0x5d;
|
||||
seed_aligned[1] = 0x79;
|
||||
seed_aligned[2] = 0x66;
|
||||
seed_aligned[3] = 0xa7;
|
||||
seed_aligned[4] = 0x73;
|
||||
seed_aligned[5] = 0x27;
|
||||
seed_aligned[6] = 0x02;
|
||||
seed_aligned[7] = 0x2f;
|
||||
seed_aligned[8] = 0x6a;
|
||||
seed_aligned[9] = 0xa1;
|
||||
seed_aligned[10] = 0x9e;
|
||||
seed_aligned[11] = 0xc1;
|
||||
seed_aligned[12] = 0x14;
|
||||
seed_aligned[13] = 0x8c;
|
||||
seed_aligned[14] = 0x9e;
|
||||
seed_aligned[15] = 0x43;
|
||||
|
||||
for (i = 0; TEST_HASH32[i].data; ++i) {
|
||||
uint32_t digest;
|
||||
memcpy(buffer_aligned, TEST_HASH32[i].data, TEST_HASH32[i].len);
|
||||
digest = tommy_hash_u32(seed32, buffer_aligned, TEST_HASH32[i].len);
|
||||
if (digest != TEST_HASH32[i].digest) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed hash32 test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; TEST_STRHASH32[i].data; ++i) {
|
||||
uint32_t digest;
|
||||
memcpy(buffer_aligned, TEST_STRHASH32[i].data, strlen(TEST_STRHASH32[i].data) + 1);
|
||||
digest = tommy_strhash_u32(seed32, buffer_aligned);
|
||||
if (digest != TEST_STRHASH32[i].digest) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed strhash32 test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; TEST_HASH64[i].data; ++i) {
|
||||
uint64_t digest;
|
||||
memcpy(buffer_aligned, TEST_HASH64[i].data, TEST_HASH64[i].len);
|
||||
digest = tommy_hash_u64(seed64, buffer_aligned, TEST_HASH64[i].len);
|
||||
if (digest != TEST_HASH64[i].digest) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed hash64 test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; TEST_MURMUR3[i].data; ++i) {
|
||||
unsigned char digest[HASH_MAX];
|
||||
memcpy(buffer_aligned, TEST_MURMUR3[i].data, TEST_MURMUR3[i].len);
|
||||
memhash(HASH_MURMUR3, seed_aligned, digest, buffer_aligned, TEST_MURMUR3[i].len);
|
||||
if (memcmp(digest, TEST_MURMUR3[i].digest, HASH_MAX) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed Murmur3 test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; TEST_SPOOKY2[i].data; ++i) {
|
||||
unsigned char digest[HASH_MAX];
|
||||
memcpy(buffer_aligned, TEST_SPOOKY2[i].data, TEST_SPOOKY2[i].len);
|
||||
memhash(HASH_SPOOKY2, seed_aligned, digest, buffer_aligned, TEST_SPOOKY2[i].len);
|
||||
if (memcmp(digest, TEST_SPOOKY2[i].digest, HASH_MAX) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed Spooky2 test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer_alloc);
|
||||
free(seed_alloc);
|
||||
}
|
||||
|
||||
struct crc_test_vector {
|
||||
const char* data;
|
||||
int len;
|
||||
uint32_t digest;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test vectors for CRC32C (Castagnoli)
|
||||
*/
|
||||
static struct crc_test_vector TEST_CRC32C[] = {
|
||||
{ "", 0, 0 },
|
||||
{ "\x61", 1, 0xc1d04330 },
|
||||
{ "\x66\x6f\x6f", 3, 0xcfc4ae1d },
|
||||
{ "\x68\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64", 11, 0xc99465aa },
|
||||
{ "\x68\x65\x6c\x6c\x6f\x20", 6, 0x7e627e58 },
|
||||
{ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 32, 0x8a9136aa },
|
||||
{ "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", 32, 0x62a8ab43 },
|
||||
{ "\x1f\x1e\x1d\x1c\x1b\x1a\x19\x18\x17\x16\x15\x14\x13\x12\x11\x10\x0f\x0e\x0d\x0c\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00", 32, 0x113fdb5c },
|
||||
{ "\x01\xc0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x14\x00\x00\x00\x18\x28\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00", 48, 0xd9963a56 },
|
||||
{ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", 32, 0x46dd794e },
|
||||
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28", 40, 0x0e2c157f },
|
||||
{ "\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50", 40, 0xe980ebf6 },
|
||||
{ "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78", 40, 0xde74bded },
|
||||
{ "\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0", 40, 0xd579c862 },
|
||||
{ "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8", 40, 0xba979ad0 },
|
||||
{ "\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0", 40, 0x2b29d913 },
|
||||
{ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0", 240, 0x24c5d375 },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
static void test_crc32c(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; TEST_CRC32C[i].data; ++i) {
|
||||
uint32_t digest;
|
||||
uint32_t digest_gen;
|
||||
|
||||
digest = crc32c(0, (const unsigned char*)TEST_CRC32C[i].data, TEST_CRC32C[i].len);
|
||||
digest_gen = crc32c_gen(0, (const unsigned char*)TEST_CRC32C[i].data, TEST_CRC32C[i].len);
|
||||
|
||||
if (digest != TEST_CRC32C[i].digest || digest_gen != TEST_CRC32C[i].digest) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed CRC32C test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of tommy data structures.
|
||||
*/
|
||||
#define TOMMY_SIZE 256
|
||||
|
||||
static int tommy_test_search(const void* arg, const void* obj)
|
||||
{
|
||||
return arg != obj;
|
||||
}
|
||||
|
||||
static int tommy_test_compare(const void* void_arg_a, const void* void_arg_b)
|
||||
{
|
||||
if (void_arg_a < void_arg_b)
|
||||
return -1;
|
||||
if (void_arg_a > void_arg_b)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned tommy_test_foreach_count;
|
||||
|
||||
static void tommy_test_foreach(void* obj)
|
||||
{
|
||||
(void)obj;
|
||||
|
||||
++tommy_test_foreach_count;
|
||||
}
|
||||
|
||||
static void tommy_test_foreach_arg(void* void_arg, void* obj)
|
||||
{
|
||||
unsigned* arg = void_arg;
|
||||
|
||||
(void)obj;
|
||||
|
||||
++*arg;
|
||||
}
|
||||
|
||||
static void test_tommy(void)
|
||||
{
|
||||
tommy_array array;
|
||||
tommy_arrayblkof arrayblkof;
|
||||
tommy_list list;
|
||||
tommy_hashdyn hashdyn;
|
||||
tommy_tree tree;
|
||||
tommy_node node[TOMMY_SIZE + 1];
|
||||
unsigned i;
|
||||
|
||||
tommy_array_init(&array);
|
||||
tommy_arrayblkof_init(&arrayblkof, sizeof(unsigned));
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE; ++i) {
|
||||
tommy_array_insert(&array, &node[i]);
|
||||
tommy_arrayblkof_grow(&arrayblkof, i + 1);
|
||||
*(unsigned*)tommy_arrayblkof_ref(&arrayblkof, i) = i;
|
||||
}
|
||||
|
||||
tommy_array_grow(&array, TOMMY_SIZE);
|
||||
tommy_arrayblkof_grow(&arrayblkof, TOMMY_SIZE);
|
||||
|
||||
if (tommy_array_memory_usage(&array) < TOMMY_SIZE * sizeof(void*)) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (tommy_arrayblkof_memory_usage(&arrayblkof) < TOMMY_SIZE * sizeof(unsigned)) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE; ++i) {
|
||||
if (tommy_array_get(&array, i) != &node[i]) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (*(unsigned*)tommy_arrayblkof_ref(&arrayblkof, i) != i) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
tommy_arrayblkof_done(&arrayblkof);
|
||||
tommy_array_done(&array);
|
||||
|
||||
tommy_list_init(&list);
|
||||
|
||||
if (!tommy_list_empty(&list)) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (tommy_list_tail(&list)) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (tommy_list_head(&list)) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
tommy_list_insert_tail(&list, &node[0], &node[0]);
|
||||
|
||||
if (tommy_list_tail(&list) != tommy_list_head(&list)) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
tommy_hashdyn_init(&hashdyn);
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE; ++i)
|
||||
tommy_hashdyn_insert(&hashdyn, &node[i], &node[i], i % 64);
|
||||
|
||||
if (tommy_hashdyn_count(&hashdyn) != TOMMY_SIZE) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (tommy_hashdyn_memory_usage(&hashdyn) < TOMMY_SIZE * sizeof(tommy_node)) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
tommy_test_foreach_count = 0;
|
||||
tommy_hashdyn_foreach(&hashdyn, tommy_test_foreach);
|
||||
if (tommy_test_foreach_count != TOMMY_SIZE) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
tommy_test_foreach_count = 0;
|
||||
tommy_hashdyn_foreach_arg(&hashdyn, tommy_test_foreach_arg, &tommy_test_foreach_count);
|
||||
if (tommy_test_foreach_count != TOMMY_SIZE) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE / 2; ++i)
|
||||
tommy_hashdyn_remove_existing(&hashdyn, &node[i]);
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE / 2; ++i) {
|
||||
if (tommy_hashdyn_remove(&hashdyn, tommy_test_search, &node[i], i % 64) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
for (i = TOMMY_SIZE / 2; i < TOMMY_SIZE; ++i) {
|
||||
if (tommy_hashdyn_remove(&hashdyn, tommy_test_search, &node[i], i % 64) == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
if (tommy_hashdyn_count(&hashdyn) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
tommy_hashdyn_done(&hashdyn);
|
||||
|
||||
tommy_tree_init(&tree, tommy_test_compare);
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE; ++i)
|
||||
tommy_tree_insert(&tree, &node[i], (void*)(uintptr_t)(i + 1));
|
||||
|
||||
/* try to insert a duplicate, count should not change */
|
||||
tommy_tree_insert(&tree, &node[TOMMY_SIZE], (void*)(uintptr_t)1);
|
||||
|
||||
if (tommy_tree_count(&tree) != TOMMY_SIZE) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (tommy_tree_memory_usage(&tree) < TOMMY_SIZE * sizeof(tommy_node)) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (tommy_tree_search(&tree, (void*)1) != (void*)1) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (tommy_tree_search(&tree, (void*)-1) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (tommy_tree_search_compare(&tree, tommy_test_compare, (void*)1) != (void*)1) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (tommy_tree_search_compare(&tree, tommy_test_compare, (void*)-1) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
tommy_test_foreach_count = 0;
|
||||
tommy_tree_foreach(&tree, tommy_test_foreach);
|
||||
if (tommy_test_foreach_count != TOMMY_SIZE) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
tommy_test_foreach_count = 0;
|
||||
tommy_tree_foreach_arg(&tree, tommy_test_foreach_arg, &tommy_test_foreach_count);
|
||||
if (tommy_test_foreach_count != TOMMY_SIZE) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE / 2; ++i)
|
||||
tommy_tree_remove_existing(&tree, &node[i]);
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE / 2; ++i) {
|
||||
if (tommy_tree_remove(&tree, (void*)(uintptr_t)(i + 1)) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (i = TOMMY_SIZE / 2; i < TOMMY_SIZE; ++i) {
|
||||
if (tommy_tree_remove(&tree, (void*)(uintptr_t)(i + 1)) == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
if (tommy_tree_count(&tree) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return;
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed tommy test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
void selftest(void)
|
||||
{
|
||||
log_tag("selftest:\n");
|
||||
log_flush();
|
||||
|
||||
msg_progress("Self test...\n");
|
||||
|
||||
/* large file check */
|
||||
if (sizeof(off_t) < sizeof(uint64_t)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Missing support for large files\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
test_hash();
|
||||
test_crc32c();
|
||||
test_tommy();
|
||||
if (raid_selftest() != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed SELF test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (raid_test_sort() != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed SORT test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (raid_test_insert() != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed INSERT test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (raid_test_combo() != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed COMBO test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (raid_test_par(RAID_MODE_VANDERMONDE, 32, 256) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed GEN Vandermonde test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (raid_test_rec(RAID_MODE_VANDERMONDE, 12, 256) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed REC Vandermonde test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (raid_test_par(RAID_MODE_CAUCHY, 32, 256) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed GEN Cauchy test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (raid_test_rec(RAID_MODE_CAUCHY, 12, 256) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed REC Cauchy test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (raid_test_par(RAID_MODE_CAUCHY, 1, 256) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed GEN Cauchy test sigle data disk\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
1511
cmdline/snapraid.c
Normal file
1511
cmdline/snapraid.c
Normal file
File diff suppressed because it is too large
Load Diff
28
cmdline/snapraid.h
Normal file
28
cmdline/snapraid.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SNAPRAID_H
|
||||
#define __SNAPRAID_H
|
||||
|
||||
/****************************************************************************/
|
||||
/* snapraid */
|
||||
|
||||
void speed(int period);
|
||||
void selftest(void);
|
||||
|
||||
#endif
|
||||
|
948
cmdline/speed.c
Normal file
948
cmdline/speed.c
Normal file
@ -0,0 +1,948 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "snapraid.h"
|
||||
#include "util.h"
|
||||
#include "raid/raid.h"
|
||||
#include "raid/cpu.h"
|
||||
#include "raid/internal.h"
|
||||
#include "raid/memory.h"
|
||||
#include "state.h"
|
||||
|
||||
/*
|
||||
* Size of the blocks to test.
|
||||
*/
|
||||
#define TEST_SIZE (256 * KIBI)
|
||||
|
||||
/*
|
||||
* Number of data blocks to test.
|
||||
*/
|
||||
#define TEST_COUNT (8)
|
||||
|
||||
/**
|
||||
* Differential us of two timeval.
|
||||
*/
|
||||
static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop)
|
||||
{
|
||||
int64_t d;
|
||||
|
||||
d = 1000000LL * (stop->tv_sec - start->tv_sec);
|
||||
d += stop->tv_usec - start->tv_usec;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start time measurement.
|
||||
*/
|
||||
#define SPEED_START \
|
||||
count = 0; \
|
||||
gettimeofday(&start, 0); \
|
||||
do { \
|
||||
for (i = 0; i < delta; ++i)
|
||||
|
||||
/**
|
||||
* Stop time measurement.
|
||||
*/
|
||||
#define SPEED_STOP \
|
||||
count += delta; \
|
||||
gettimeofday(&stop, 0); \
|
||||
} while (diffgettimeofday(&start, &stop) < period * 1000LL) ; \
|
||||
ds = size * (int64_t)count * nd; \
|
||||
dt = diffgettimeofday(&start, &stop);
|
||||
|
||||
/**
|
||||
* Global variable used to propagate side effects.
|
||||
*
|
||||
* This is required to avoid optimizing compilers
|
||||
* to remove code without side effects.
|
||||
*/
|
||||
static unsigned side_effect;
|
||||
|
||||
void speed(int period)
|
||||
{
|
||||
struct timeval start;
|
||||
struct timeval stop;
|
||||
int64_t ds;
|
||||
int64_t dt;
|
||||
int i, j;
|
||||
unsigned char digest[HASH_MAX];
|
||||
unsigned char seed[HASH_MAX];
|
||||
int id[RAID_PARITY_MAX];
|
||||
int ip[RAID_PARITY_MAX];
|
||||
int count;
|
||||
int delta = period >= 1000 ? 10 : 1;
|
||||
int size = TEST_SIZE;
|
||||
int nd = TEST_COUNT;
|
||||
int nv;
|
||||
void *v_alloc;
|
||||
void **v;
|
||||
|
||||
nv = nd + RAID_PARITY_MAX + 1;
|
||||
|
||||
v = malloc_nofail_vector_align(nd, nv, size, &v_alloc);
|
||||
|
||||
/* initialize disks with fixed data */
|
||||
for (i = 0; i < nd; ++i)
|
||||
memset(v[i], i, size);
|
||||
|
||||
/* zero buffer */
|
||||
memset(v[nd + RAID_PARITY_MAX], 0, size);
|
||||
raid_zero(v[nd + RAID_PARITY_MAX]);
|
||||
|
||||
/* hash seed */
|
||||
for (i = 0; i < HASH_MAX; ++i)
|
||||
seed[i] = i;
|
||||
|
||||
/* basic disks and parity mapping */
|
||||
for (i = 0; i < RAID_PARITY_MAX; ++i) {
|
||||
id[i] = i;
|
||||
ip[i] = i;
|
||||
}
|
||||
|
||||
printf(PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
|
||||
|
||||
#ifdef __GNUC__
|
||||
printf("Compiler gcc " __VERSION__ "\n");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
{
|
||||
char vendor[CPU_VENDOR_MAX];
|
||||
unsigned family;
|
||||
unsigned model;
|
||||
|
||||
raid_cpu_info(vendor, &family, &model);
|
||||
|
||||
printf("CPU %s, family %u, model %u, flags%s%s%s%s%s%s\n", vendor, family, model,
|
||||
raid_cpu_has_sse2() ? " sse2" : "",
|
||||
raid_cpu_has_ssse3() ? " ssse3" : "",
|
||||
raid_cpu_has_crc32() ? " crc32" : "",
|
||||
raid_cpu_has_avx2() ? " avx2" : "",
|
||||
raid_cpu_has_slowmult() ? " slowmult" : "",
|
||||
raid_cpu_has_slowextendedreg() ? " slowext" : ""
|
||||
);
|
||||
}
|
||||
#else
|
||||
printf("CPU is not a x86/x64\n");
|
||||
#endif
|
||||
#if WORDS_BIGENDIAN
|
||||
printf("Memory is big-endian %d-bit\n", (int)sizeof(void *) * 8);
|
||||
#else
|
||||
printf("Memory is little-endian %d-bit\n", (int)sizeof(void *) * 8);
|
||||
#endif
|
||||
|
||||
#if HAVE_FUTIMENS
|
||||
printf("Support nanosecond timestamps with futimens()\n");
|
||||
#elif HAVE_FUTIMES
|
||||
printf("Support nanosecond timestamps with futimes()\n");
|
||||
#elif HAVE_FUTIMESAT
|
||||
printf("Support nanosecond timestamps with futimesat()\n");
|
||||
#else
|
||||
printf("Does not support nanosecond timestamps\n");
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Speed test using %u data buffers of %u bytes, for a total of %u KiB.\n", nd, size, nd * size / KIBI);
|
||||
printf("Memory blocks have a displacement of %u bytes to improve cache performance.\n", RAID_MALLOC_DISPLACEMENT);
|
||||
printf("The reported values are the aggregate bandwidth of all data blocks in MB/s,\n");
|
||||
printf("not counting parity blocks.\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Memory write speed using the C memset() function:\n");
|
||||
printf("%8s", "memset");
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
memset(v[j], j, size);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
/* crc table */
|
||||
printf("CRC used to check the content file integrity:\n");
|
||||
|
||||
printf("%8s", "table");
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
side_effect += crc32c_gen(0, v[j], size);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "intel");
|
||||
fflush(stdout);
|
||||
|
||||
#if HAVE_SSE42
|
||||
if (raid_cpu_has_crc32()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
side_effect += crc32c_x86(0, v[j], size);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
/* hash table */
|
||||
printf("Hash used to check the data blocks integrity:\n");
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "best");
|
||||
printf("%8s", "murmur3");
|
||||
printf("%8s", "spooky2");
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "hash");
|
||||
#ifdef CONFIG_X86
|
||||
if (sizeof(void *) == 4 && !raid_cpu_has_slowmult())
|
||||
printf("%8s", "murmur3");
|
||||
else
|
||||
printf("%8s", "spooky2");
|
||||
#else
|
||||
if (sizeof(void *) == 4)
|
||||
printf("%8s", "murmur3");
|
||||
else
|
||||
printf("%8s", "spooky2");
|
||||
#endif
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
memhash(HASH_MURMUR3, seed, digest, v[j], size);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
memhash(HASH_SPOOKY2, seed, digest, v[j], size);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
/* RAID table */
|
||||
printf("RAID functions used for computing the parity with 'sync':\n");
|
||||
printf("%8s", "");
|
||||
printf("%8s", "best");
|
||||
printf("%8s", "int8");
|
||||
printf("%8s", "int32");
|
||||
printf("%8s", "int64");
|
||||
#ifdef CONFIG_X86
|
||||
printf("%8s", "sse2");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "sse2e");
|
||||
#endif
|
||||
printf("%8s", "ssse3");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "ssse3e");
|
||||
#endif
|
||||
printf("%8s", "avx2");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "avx2e");
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN1 */
|
||||
printf("%8s", "gen1");
|
||||
printf("%8s", raid_gen1_tag());
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
SPEED_START {
|
||||
raid_gen1_int32(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen1_int64(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
SPEED_START {
|
||||
raid_gen1_sse2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
printf("%8s", "");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen1_avx2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN2 */
|
||||
printf("%8s", "gen2");
|
||||
printf("%8s", raid_gen2_tag());
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
SPEED_START {
|
||||
raid_gen2_int32(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen2_int64(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
SPEED_START {
|
||||
raid_gen2_sse2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen2_sse2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen2_avx2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GENz */
|
||||
printf("%8s", "genz");
|
||||
printf("%8s", raid_genz_tag());
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
SPEED_START {
|
||||
raid_genz_int32(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_genz_int64(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
SPEED_START {
|
||||
raid_genz_sse2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_genz_sse2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_genz_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN3 */
|
||||
printf("%8s", "gen3");
|
||||
printf("%8s", raid_gen3_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen3_int8(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
if (raid_cpu_has_sse2()) {
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
raid_gen3_ssse3(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen3_ssse3ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen3_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN4 */
|
||||
printf("%8s", "gen4");
|
||||
printf("%8s", raid_gen4_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen4_int8(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
raid_gen4_ssse3(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen4_ssse3ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen4_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN5 */
|
||||
printf("%8s", "gen5");
|
||||
printf("%8s", raid_gen5_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen5_int8(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
raid_gen5_ssse3(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen5_ssse3ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen5_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN6 */
|
||||
printf("%8s", "gen6");
|
||||
printf("%8s", raid_gen6_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen6_int8(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
raid_gen6_ssse3(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen6_ssse3ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen6_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
/* recover table */
|
||||
printf("RAID functions used for recovering with 'fix':\n");
|
||||
printf("%8s", "");
|
||||
printf("%8s", "best");
|
||||
printf("%8s", "int8");
|
||||
#ifdef CONFIG_X86
|
||||
printf("%8s", "ssse3");
|
||||
printf("%8s", "avx2");
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec1");
|
||||
printf("%8s", raid_rec1_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN1 optimized case */
|
||||
raid_rec1_int8(1, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN1 optimized case */
|
||||
raid_rec1_ssse3(1, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN1 optimized case */
|
||||
raid_rec1_avx2(1, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec2");
|
||||
printf("%8s", raid_rec2_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN2 optimized case */
|
||||
raid_rec2_int8(2, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN2 optimized case */
|
||||
raid_rec2_ssse3(2, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN1 optimized case */
|
||||
raid_rec2_avx2(2, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec3");
|
||||
printf("%8s", raid_recX_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_int8(3, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_ssse3(3, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_avx2(3, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec4");
|
||||
printf("%8s", raid_recX_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_int8(4, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_ssse3(4, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_avx2(4, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec5");
|
||||
printf("%8s", raid_recX_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_int8(5, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_ssse3(5, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_avx2(5, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec6");
|
||||
printf("%8s", raid_recX_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_int8(6, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_ssse3(6, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_avx2(6, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
printf("If the 'best' expectations are wrong, please report it in the SnapRAID forum\n\n");
|
||||
|
||||
free(v_alloc);
|
||||
free(v);
|
||||
}
|
||||
|
162
cmdline/spooky2.c
Normal file
162
cmdline/spooky2.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Derivative work from SpookyV2.cpp/h
|
||||
*
|
||||
* WARNING!!!! Note that this implementation doesn't use the short hash optimization
|
||||
* resulting in different hashes for any length shorter than 192 bytes
|
||||
*
|
||||
* SpookyHash
|
||||
* http://burtleburtle.net/bob/hash/spooky.html
|
||||
*
|
||||
* Exact source used as reference:
|
||||
* http://burtleburtle.net/bob/c/SpookyV2.h
|
||||
* http://burtleburtle.net/bob/c/SpookyV2.cpp
|
||||
*/
|
||||
|
||||
// Spooky Hash
|
||||
// A 128-bit noncryptographic hash, for checksums and table lookup
|
||||
// By Bob Jenkins. Public domain.
|
||||
// Oct 31 2010: published framework, disclaimer ShortHash isn't right
|
||||
// Nov 7 2010: disabled ShortHash
|
||||
// Oct 31 2011: replace End, ShortMix, ShortEnd, enable ShortHash again
|
||||
// April 10 2012: buffer overflow on platforms without unaligned reads
|
||||
// July 12 2012: was passing out variables in final to in/out in short
|
||||
// July 30 2012: I reintroduced the buffer overflow
|
||||
// August 5 2012: SpookyV2: d = should be d += in short hash, and remove extra mix from long hash
|
||||
//
|
||||
// Up to 3 bytes/cycle for long messages. Reasonably fast for short messages.
|
||||
// All 1 or 2 bit deltas achieve avalanche within 1% bias per output bit.
|
||||
//
|
||||
// This was developed for and tested on 64-bit x86-compatible processors.
|
||||
// It assumes the processor is little-endian. There is a macro
|
||||
// controlling whether unaligned reads are allowed (by default they are).
|
||||
// This should be an equally good hash on big-endian machines, but it will
|
||||
// compute different results on them than on little-endian machines.
|
||||
//
|
||||
// Google's CityHash has similar specs to SpookyHash, and CityHash is faster
|
||||
// on new Intel boxes. MD4 and MD5 also have similar specs, but they are orders
|
||||
// of magnitude slower. CRCs are two or more times slower, but unlike
|
||||
// SpookyHash, they have nice math for combining the CRCs of pieces to form
|
||||
// the CRCs of wholes. There are also cryptographic hashes, but those are even
|
||||
// slower than MD5.
|
||||
//
|
||||
|
||||
#define Mix(data, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11) \
|
||||
s0 += data[0]; s2 ^= s10; s11 ^= s0; s0 = util_rotl64(s0, 11); s11 += s1; \
|
||||
s1 += data[1]; s3 ^= s11; s0 ^= s1; s1 = util_rotl64(s1, 32); s0 += s2; \
|
||||
s2 += data[2]; s4 ^= s0; s1 ^= s2; s2 = util_rotl64(s2, 43); s1 += s3; \
|
||||
s3 += data[3]; s5 ^= s1; s2 ^= s3; s3 = util_rotl64(s3, 31); s2 += s4; \
|
||||
s4 += data[4]; s6 ^= s2; s3 ^= s4; s4 = util_rotl64(s4, 17); s3 += s5; \
|
||||
s5 += data[5]; s7 ^= s3; s4 ^= s5; s5 = util_rotl64(s5, 28); s4 += s6; \
|
||||
s6 += data[6]; s8 ^= s4; s5 ^= s6; s6 = util_rotl64(s6, 39); s5 += s7; \
|
||||
s7 += data[7]; s9 ^= s5; s6 ^= s7; s7 = util_rotl64(s7, 57); s6 += s8; \
|
||||
s8 += data[8]; s10 ^= s6; s7 ^= s8; s8 = util_rotl64(s8, 55); s7 += s9; \
|
||||
s9 += data[9]; s11 ^= s7; s8 ^= s9; s9 = util_rotl64(s9, 54); s8 += s10; \
|
||||
s10 += data[10]; s0 ^= s8; s9 ^= s10; s10 = util_rotl64(s10, 22); s9 += s11; \
|
||||
s11 += data[11]; s1 ^= s9; s10 ^= s11; s11 = util_rotl64(s11, 46); s10 += s0;
|
||||
|
||||
#define EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) \
|
||||
h11 += h1; h2 ^= h11; h1 = util_rotl64(h1, 44); \
|
||||
h0 += h2; h3 ^= h0; h2 = util_rotl64(h2, 15); \
|
||||
h1 += h3; h4 ^= h1; h3 = util_rotl64(h3, 34); \
|
||||
h2 += h4; h5 ^= h2; h4 = util_rotl64(h4, 21); \
|
||||
h3 += h5; h6 ^= h3; h5 = util_rotl64(h5, 38); \
|
||||
h4 += h6; h7 ^= h4; h6 = util_rotl64(h6, 33); \
|
||||
h5 += h7; h8 ^= h5; h7 = util_rotl64(h7, 10); \
|
||||
h6 += h8; h9 ^= h6; h8 = util_rotl64(h8, 13); \
|
||||
h7 += h9; h10 ^= h7; h9 = util_rotl64(h9, 38); \
|
||||
h8 += h10; h11 ^= h8; h10 = util_rotl64(h10, 53); \
|
||||
h9 += h11; h0 ^= h9; h11 = util_rotl64(h11, 42); \
|
||||
h10 += h0; h1 ^= h10; h0 = util_rotl64(h0, 54);
|
||||
|
||||
#define End(data, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11) \
|
||||
h0 += data[0]; h1 += data[1]; h2 += data[2]; h3 += data[3]; \
|
||||
h4 += data[4]; h5 += data[5]; h6 += data[6]; h7 += data[7]; \
|
||||
h8 += data[8]; h9 += data[9]; h10 += data[10]; h11 += data[11]; \
|
||||
EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); \
|
||||
EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11); \
|
||||
EndPartial(h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
|
||||
|
||||
// number of uint64_t's in internal state
|
||||
#define sc_numVars 12
|
||||
|
||||
// size of the internal state
|
||||
#define sc_blockSize (sc_numVars * 8)
|
||||
|
||||
//
|
||||
// sc_const: a constant which:
|
||||
// * is not zero
|
||||
// * is odd
|
||||
// * is a not-very-regular mix of 1's and 0's
|
||||
// * does not need any other special mathematical properties
|
||||
//
|
||||
#define sc_const 0xdeadbeefdeadbeefLL
|
||||
|
||||
void SpookyHash128(const void* data, size_t size, const uint8_t* seed, uint8_t* digest)
|
||||
{
|
||||
uint64_t h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11;
|
||||
uint64_t buf[sc_numVars];
|
||||
size_t nblocks;
|
||||
const uint64_t* blocks;
|
||||
const uint64_t* end;
|
||||
size_t size_remainder;
|
||||
#if WORDS_BIGENDIAN
|
||||
unsigned i;
|
||||
#endif
|
||||
|
||||
h9 = util_read64(seed + 0);
|
||||
h10 = util_read64(seed + 8);
|
||||
|
||||
h0 = h3 = h6 = h9;
|
||||
h1 = h4 = h7 = h10;
|
||||
h2 = h5 = h8 = h11 = sc_const;
|
||||
|
||||
nblocks = size / sc_blockSize;
|
||||
blocks = data;
|
||||
end = blocks + nblocks * sc_numVars;
|
||||
|
||||
/* body */
|
||||
while (blocks < end) {
|
||||
#if WORDS_BIGENDIAN
|
||||
for (i = 0; i < sc_numVars; ++i)
|
||||
buf[i] = util_swap64(blocks[i]);
|
||||
Mix(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
|
||||
#else
|
||||
Mix(blocks, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
|
||||
#endif
|
||||
blocks += sc_numVars;
|
||||
}
|
||||
|
||||
/* tail */
|
||||
size_remainder = (size - ((const uint8_t*)end - (const uint8_t*)data));
|
||||
memcpy(buf, end, size_remainder);
|
||||
memset(((uint8_t*)buf) + size_remainder, 0, sc_blockSize - size_remainder);
|
||||
((uint8_t*)buf)[sc_blockSize - 1] = size_remainder;
|
||||
|
||||
/* finalization */
|
||||
#if WORDS_BIGENDIAN
|
||||
for (i = 0; i < sc_numVars; ++i)
|
||||
buf[i] = util_swap64(buf[i]);
|
||||
#endif
|
||||
End(buf, h0, h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11);
|
||||
|
||||
util_write64(digest + 0, h0);
|
||||
util_write64(digest + 8, h1);
|
||||
}
|
||||
|
264
cmdline/spooky2test.c
Normal file
264
cmdline/spooky2test.c
Normal file
@ -0,0 +1,264 @@
|
||||
{ "", 0, { 0xc7, 0xd7, 0x7b, 0x13, 0xfc, 0xa2, 0x7b, 0x21, 0x00, 0x95, 0xf6, 0xa9, 0x6f, 0x84, 0xaa, 0xc9 } },
|
||||
{ "a", 1, { 0x85, 0x34, 0x3d, 0x36, 0xf4, 0x56, 0x79, 0x60, 0xa7, 0x96, 0x5f, 0x16, 0x44, 0x1e, 0x8c, 0xea } },
|
||||
{ "abc", 3, { 0xb0, 0x41, 0x6b, 0xce, 0xba, 0xdf, 0x5d, 0xe3, 0x09, 0x38, 0xcb, 0x1f, 0x25, 0xdc, 0x44, 0xa2 } },
|
||||
{ "message digest", 14, { 0xdf, 0xe5, 0xcb, 0x3f, 0x51, 0xa8, 0xa2, 0xd4, 0x8d, 0xa0, 0xd5, 0x48, 0x26, 0x1c, 0x17, 0x74 } },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 26, { 0x95, 0xe3, 0x9c, 0x85, 0xb8, 0x70, 0x3d, 0x24, 0x51, 0x1c, 0x3c, 0x85, 0x8c, 0xd7, 0x57, 0x2c } },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, { 0x7d, 0x0d, 0xb7, 0xae, 0x85, 0xce, 0xa1, 0x13, 0xf8, 0xfc, 0xb4, 0xf4, 0x05, 0xab, 0x68, 0xb0 } },
|
||||
{ "The quick brown fox jumps over the lazy dog", 43, { 0xda, 0xfa, 0x43, 0x97, 0xaf, 0x0b, 0xdc, 0x06, 0x1e, 0xc2, 0x77, 0x12, 0xeb, 0x36, 0xd4, 0x4d } },
|
||||
{ "\x00", 1, { 0x51, 0xe3, 0xc3, 0x5c, 0x6d, 0x8f, 0xb3, 0xc8, 0x01, 0x19, 0x29, 0xcb, 0x9d, 0x98, 0xa3, 0xa0 } },
|
||||
{ "\x16\x27", 2, { 0xbb, 0x96, 0x86, 0x56, 0xcc, 0x62, 0x37, 0xe0, 0xe8, 0xf0, 0x5b, 0x63, 0x3b, 0xd1, 0x6c, 0x42 } },
|
||||
{ "\xe2\x56\xb4", 3, { 0xf6, 0xb2, 0x17, 0x1a, 0x27, 0x85, 0x2b, 0x8a, 0x45, 0x4e, 0x26, 0xf1, 0xeb, 0xb9, 0x60, 0x64 } },
|
||||
{ "\xc9\x4d\x9c\xda", 4, { 0x94, 0xdb, 0x3e, 0x5b, 0x3a, 0x4c, 0x0e, 0xf9, 0x4a, 0xe6, 0x42, 0xfa, 0xc6, 0xb5, 0xa6, 0x1d } },
|
||||
{ "\x79\xf1\x29\x69\x5d", 5, { 0x0c, 0x5e, 0x36, 0x05, 0x04, 0xd5, 0xf2, 0x53, 0x7b, 0x56, 0x03, 0xc7, 0x6f, 0x08, 0x45, 0x07 } },
|
||||
{ "\x00\x7e\xdf\x1e\x31\x1c", 6, { 0xd5, 0x65, 0x58, 0x3d, 0xa3, 0x96, 0x8a, 0xa2, 0x6e, 0xe5, 0x8d, 0x84, 0xa5, 0x3f, 0xd7, 0x6c } },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 7, { 0x19, 0x00, 0x13, 0x2a, 0xd9, 0x50, 0x80, 0x5e, 0xb9, 0x19, 0x36, 0x5a, 0xb6, 0x36, 0x2a, 0x0f } },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 8, { 0x13, 0xc7, 0xac, 0xcb, 0x7a, 0x5d, 0xe5, 0x14, 0x4b, 0xf6, 0xee, 0xfd, 0x52, 0x86, 0xb7, 0x5f } },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 9, { 0xe4, 0x12, 0x97, 0x2c, 0xe2, 0xca, 0x21, 0x67, 0xec, 0xe8, 0x63, 0xf7, 0x20, 0x7d, 0xae, 0xad } },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 10, { 0x11, 0x14, 0x7d, 0xd2, 0x79, 0xd5, 0x32, 0x30, 0x43, 0x83, 0x26, 0x60, 0x47, 0xed, 0x63, 0x2b } },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\x00\xb7\xae", 11, { 0x59, 0xa5, 0x00, 0x96, 0x3f, 0x01, 0xd8, 0x90, 0x00, 0x46, 0x2f, 0x11, 0xf1, 0xf9, 0xb8, 0x7d } },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 12, { 0x21, 0x3e, 0x1d, 0x1b, 0x44, 0xb7, 0x71, 0xc0, 0xde, 0x2b, 0xb4, 0x6d, 0x82, 0x6d, 0x8c, 0x1e } },
|
||||
{ "\x87\xd8\x61\x61\x4c\x89\x17\x4e\xa1\xa4\xef\x13\xa9", 13, { 0xe3, 0xa9, 0x25, 0xc9, 0x53, 0x3c, 0xa2, 0xa5, 0x69, 0x62, 0x31, 0xde, 0x10, 0xbb, 0x54, 0xd3 } },
|
||||
{ "\xfe\xa6\x5b\xc2\xda\xe8\x95\xd4\x64\xab\x4c\x39\x58\x29", 14, { 0x91, 0x14, 0xf0, 0x97, 0x98, 0x3b, 0x8e, 0x97, 0x33, 0x33, 0x8e, 0xb9, 0xca, 0x3a, 0x1d, 0x82 } },
|
||||
{ "\x94\x49\xc0\x78\xa0\x80\xda\xc7\x71\x4e\x17\x37\xa9\x7c\x40", 15, { 0x06, 0x33, 0x47, 0x61, 0xe7, 0xc9, 0xc1, 0x0e, 0x23, 0x36, 0x86, 0x2b, 0x2d, 0x21, 0x89, 0x57 } },
|
||||
{ "\x53\x7e\x36\xb4\x2e\xc9\xb9\xcc\x18\x3e\x9a\x5f\xfc\xb7\xb0\x61", 16, { 0x66, 0x36, 0x7d, 0xee, 0x47, 0x92, 0xa4, 0x4f, 0x62, 0xf8, 0xd9, 0x36, 0x8e, 0xe7, 0x69, 0x53 } },
|
||||
{ "\x59\xa9\x9f\xa6\xdb\xb7\x02\xc5\x95\x65\x34\x17\xde\xe5\xbb\xdf\xc5", 17, { 0xd7, 0x7b, 0x00, 0x79, 0xae, 0x0f, 0xc9, 0x16, 0x02, 0x28, 0xab, 0x6a, 0xdf, 0x3e, 0x30, 0x03 } },
|
||||
{ "\x0d\x52\x83\x32\x6a\x92\xf9\x9a\x6e\x3c\x3d\x5e\xc4\x25\xfe\xc1\xc4\xbe", 18, { 0x46, 0x32, 0xb2, 0xa0, 0x1b, 0xa8, 0xea, 0xce, 0x66, 0x9f, 0xc1, 0x58, 0xc9, 0x94, 0xba, 0x3b } },
|
||||
{ "\x59\x84\x02\x3f\xbc\x20\x01\x70\xed\xa0\x05\x14\x23\x18\x06\xf2\x52\xc5\xc1", 19, { 0x98, 0xfc, 0x24, 0x88, 0x92, 0xbd, 0xad, 0x17, 0xcc, 0x07, 0x11, 0x2b, 0x37, 0x4e, 0xb1, 0x47 } },
|
||||
{ "\x81\x84\xc3\xe8\x2f\x63\x65\x79\x4e\xd3\x34\x2c\x9c\xbc\x87\x05\x6d\xe5\xbc\x0a", 20, { 0x9f, 0x9d, 0x76, 0xcf, 0x19, 0x6b, 0xae, 0x90, 0x61, 0x27, 0x76, 0x9d, 0xe4, 0x7b, 0x29, 0x4c } },
|
||||
{ "\x77\xfc\x10\x0f\x3a\xb2\x20\xad\x0a\x03\xfd\x51\xba\x93\xe6\x70\xe7\x34\xa4\xd8\xde", 21, { 0xb2, 0xfe, 0xf1, 0xb3, 0x6c, 0x1d, 0x2a, 0x88, 0x2a, 0x02, 0x4e, 0x25, 0x12, 0xa8, 0x6a, 0x6d } },
|
||||
{ "\x84\x87\x22\x2b\xb3\xf8\x44\xbf\x63\xbb\x43\xbd\xa8\xc4\x05\xe1\x2f\xb2\x44\x8d\x7a\xec", 22, { 0x2e, 0x1f, 0xd3, 0x56, 0xce, 0x43, 0x56, 0x70, 0xb8, 0x84, 0x6d, 0xd9, 0x24, 0x49, 0x36, 0x4d } },
|
||||
{ "\x9f\x72\x49\x57\xca\xd7\x15\xb1\xe6\x89\xb5\x8d\xec\x5f\x24\xeb\x42\x69\x5a\x73\x70\xb5\x56", 23, { 0xf2, 0xbf, 0x7a, 0x59, 0x6e, 0x6c, 0x2f, 0xcf, 0x5b, 0xaa, 0x02, 0x31, 0xac, 0x48, 0x5d, 0xe9 } },
|
||||
{ "\x4e\xec\xbd\x3d\xa2\x11\x70\x9c\xa8\x2e\xdb\xca\x6b\xbb\x74\x69\x1e\xa7\x03\x0b\x1b\xcd\x2e\xf0", 24, { 0x68, 0x75, 0x89, 0x8f, 0xaf, 0xdb, 0x8e, 0x21, 0x92, 0xab, 0x3a, 0xd2, 0x25, 0xad, 0xc1, 0x26 } },
|
||||
{ "\x74\x84\x9f\xed\x38\x55\xd4\x69\x44\xc8\x82\x82\xc2\x57\xa7\x4d\x43\x84\x2b\x3a\x75\x06\x32\x95\x81", 25, { 0x03, 0x4c, 0x88, 0xfc, 0x08, 0x2e, 0x21, 0x1e, 0x9f, 0xac, 0x56, 0x0c, 0xfc, 0x96, 0xbf, 0xec } },
|
||||
{ "\x1e\x01\x28\x03\x09\x8a\xfe\xa7\x8e\x95\x42\x5d\xb7\x8d\x46\x38\x9c\xe5\xa1\xe8\x5a\x25\x70\xd2\x23\x95", 26, { 0x0d, 0xb4, 0xe1, 0xa3, 0x6a, 0xed, 0xb5, 0x0b, 0x0f, 0xa1, 0x90, 0xf1, 0x48, 0xb7, 0x47, 0xd8 } },
|
||||
{ "\xbc\xc9\x70\x84\xfc\x6c\x51\x35\xb1\x1c\xe4\x67\x2f\x97\xe4\x80\x7c\x36\x59\x55\x51\xbf\x6d\x98\x3d\xe8\x5f", 27, { 0x6b, 0x15, 0x3d, 0x7d, 0xe7, 0x46, 0x1f, 0xe1, 0xb8, 0x15, 0xe7, 0xc8, 0x75, 0x66, 0x19, 0xf5 } },
|
||||
{ "\xdf\xe9\x69\x90\x4d\x76\xbc\xbb\xdf\x03\x74\x42\x55\x4a\x37\xa3\xba\x6a\x5a\x09\x92\xbf\x17\xff\xa0\xed\x6d\x3f", 28, { 0x6d, 0x27, 0xc4, 0x1a, 0xa8, 0xa4, 0x76, 0x37, 0x72, 0x9d, 0x84, 0xbe, 0x00, 0x7b, 0x7b, 0xf6 } },
|
||||
{ "\x51\xfc\x95\xa9\xc8\x9d\x1c\x4f\x87\x8b\xa2\xad\xb7\x0d\x2d\xf6\x14\x98\x2b\x89\x77\x91\x02\x83\x01\x2f\x56\x6e\xe1", 29, { 0x65, 0xa5, 0xce, 0x1b, 0x75, 0x9d, 0x8f, 0xd3, 0x5f, 0x84, 0x26, 0x59, 0x32, 0x0d, 0x9c, 0x5f } },
|
||||
{ "\x7f\xd6\x16\xc3\x81\xc3\x7c\xd6\x70\xff\xe4\x77\x1f\xcd\x09\x7f\x7f\x2b\x71\x26\x3d\xc9\xdb\x92\x88\xa5\xd4\x00\xf0\x44", 30, { 0x99, 0xfa, 0xec, 0x52, 0x11, 0x1b, 0xfc, 0x3a, 0xba, 0xe5, 0x96, 0xbc, 0xa7, 0xb4, 0xa8, 0x3c } },
|
||||
{ "\x68\x8e\x6a\x8e\xf6\xa2\x70\x47\x1d\xfb\x45\x26\xd2\x52\x56\x94\x94\xac\xbc\x02\xb6\x3f\xde\xe7\xdb\xfe\x34\x55\x81\xc3\x26", 31, { 0x14, 0x6f, 0xe7, 0x1d, 0x1c, 0xa6, 0x6d, 0xc6, 0xd5, 0x33, 0xbb, 0xf5, 0xdc, 0x90, 0x83, 0xf7 } },
|
||||
{ "\x37\xb3\x18\x13\x29\xe2\xa2\x6d\xf4\xce\x2b\x01\xa5\x9f\x4b\x54\x48\x10\xb1\x29\x46\xcb\x13\x20\x58\xcf\xb0\x78\x27\x0d\x7e\xf5", 32, { 0x41, 0x97, 0x27, 0x98, 0x5b, 0x0a, 0x50, 0x29, 0x3f, 0x71, 0xa0, 0x20, 0xfa, 0x18, 0x13, 0x9b } },
|
||||
{ "\x82\x13\xf6\xdd\x3b\xdf\x78\x1c\x9e\xd6\x5b\x87\x8f\xcd\x95\x3d\x3f\x43\x04\x2a\x8b\xb2\x57\xa5\xf1\xfa\x9c\x39\x2f\xfe\x66\x81\x7a", 33, { 0x96, 0xda, 0xe6, 0x6e, 0xda, 0xaf, 0x1c, 0x5c, 0xb6, 0x68, 0x6c, 0xb5, 0x2a, 0x53, 0x52, 0x21 } },
|
||||
{ "\x4a\x9a\x2c\x58\xf1\xd6\x21\x1a\x76\x7f\xbc\xfa\xe0\x66\x35\xcd\xf1\x17\x22\x64\x6f\xbd\x13\x85\xa1\xb5\x5b\x81\xd6\xad\xee\x72\x1e\x79", 34, { 0x2c, 0x13, 0x32, 0xbe, 0x4b, 0xee, 0x1e, 0x36, 0x8a, 0xcd, 0x5c, 0x1c, 0x5f, 0x5a, 0x7e, 0xce } },
|
||||
{ "\x66\x13\x1c\x72\x20\x3c\xf3\x8b\x83\xf8\x5e\xf2\x60\x44\xdc\x5e\x75\x67\x08\xfb\x0c\xe9\x07\xf0\xc1\x31\x1a\x89\x60\xbf\x53\x06\xed\x02\x64", 35, { 0x8a, 0x9e, 0x07, 0x96, 0x6b, 0xeb, 0x7e, 0xc2, 0x3f, 0xca, 0xe4, 0x74, 0x0f, 0x8a, 0xd0, 0xb1 } },
|
||||
{ "\xff\xbd\xd6\x92\x72\xc1\x9e\xc9\x6b\xe3\xfb\xca\x4e\x88\x26\x7f\xc4\x36\xf0\x70\x40\x4f\x53\x4d\x2d\xfc\xb3\xab\xb6\x25\xb7\xcc\x31\x9c\xbf\x97", 36, { 0x6d, 0x72, 0xeb, 0xd3, 0xf4, 0x77, 0x52, 0x8b, 0xb9, 0x10, 0x42, 0x47, 0x1d, 0xcc, 0xa3, 0xa4 } },
|
||||
{ "\x29\x59\x01\xa6\x06\xe0\x43\x7e\x5b\xbf\x37\xda\xcc\x33\x6e\x20\x9a\xeb\xfa\xf5\xcd\xe4\xa5\xec\xfd\x73\xc7\x59\xbc\x61\xc8\x44\xa3\x30\x33\x79\xf8", 37, { 0xd1, 0x39, 0xc1, 0x5b, 0x60, 0xb6, 0x53, 0x6e, 0xda, 0x86, 0xc6, 0x34, 0xa7, 0x8f, 0xe9, 0x66 } },
|
||||
{ "\x7c\x72\xbd\xf9\x7d\x2c\x1b\xc8\xa9\x38\x5c\xf2\x76\x3c\x94\x9d\x3d\xe7\xd9\x4e\x3a\xc7\x0f\x55\xb0\xc7\xdf\xd5\x29\x49\xc6\x74\xdb\xdc\x49\x9b\x27\x9a", 38, { 0x8e, 0x6e, 0x12, 0xe2, 0x8f, 0xd3, 0x0d, 0x34, 0xac, 0x81, 0xc6, 0xe6, 0xe8, 0xf2, 0x84, 0x03 } },
|
||||
{ "\x46\x6a\x3b\x21\x66\x3c\xd6\x2c\xaf\xd2\x2b\xcd\x36\x1e\xdf\x49\xf2\xae\x2d\x8f\xab\xb3\x29\x57\x10\xae\x22\xd4\xe8\xb6\x20\x15\x61\x68\x8c\xfd\x85\x6b\xef", 39, { 0x73, 0x15, 0x7b, 0xcb, 0xa7, 0x03, 0x3b, 0xb0, 0xac, 0x14, 0x75, 0x41, 0xe5, 0x83, 0xb4, 0x66 } },
|
||||
{ "\xdd\xca\x9e\xd3\xab\xc8\xe1\xc5\xe2\x05\x7d\x7c\xf5\xec\x31\x14\x71\xdd\xda\x73\xae\x5e\xbd\xcd\x31\x6e\x74\x42\xa1\xfa\x74\xa4\x64\x69\x37\x57\xd6\x52\x0a\x51", 40, { 0x41, 0x74, 0x00, 0x0d, 0xee, 0x8b, 0x3e, 0x10, 0xac, 0x8e, 0x4e, 0x41, 0x25, 0x38, 0xa6, 0xf0 } },
|
||||
{ "\x26\x4d\x75\x42\xcc\xe7\x42\xcd\xaa\xaf\x2c\xf3\xbf\x6d\x26\x91\x82\x72\x44\x00\xe1\x0b\x4a\xda\xd5\x0f\xd0\xdc\xa2\x98\x0e\xe7\xa8\xce\x4a\x21\xe9\xdf\xdb\x38\x18", 41, { 0x46, 0x5e, 0x28, 0x3e, 0x2d, 0x14, 0x30, 0xbf, 0x07, 0x39, 0x12, 0x33, 0x8e, 0x1b, 0xcd, 0x05 } },
|
||||
{ "\x0b\xd8\xc7\x5a\xdb\x62\xd1\x9c\x71\x8b\x69\x90\xfb\xe2\x74\x45\x41\x9d\x87\x61\x5e\x61\xea\xfe\x8c\xb0\xbe\x1f\x18\xef\x3a\xce\x74\x13\x11\xd3\x6b\xe8\xf0\x12\x6f\xfe", 42, { 0x19, 0xae, 0x68, 0x51, 0xdb, 0xf7, 0xfa, 0xe7, 0x3c, 0xdc, 0x83, 0x35, 0x95, 0xb7, 0x9e, 0xd8 } },
|
||||
{ "\x23\x82\x0e\x30\x57\xc6\x83\xd2\x7a\x69\x69\x76\xbf\xbb\x8b\x5b\xbd\x42\xd6\x73\xb7\xdf\x70\x10\xf6\x7f\xe1\x2a\x53\x7a\x6f\x4f\xd1\x8b\x89\x27\x66\x6d\x59\xa3\xdb\x0e\x7c", 43, { 0xfc, 0xe5, 0x55, 0x88, 0x24, 0xff, 0x12, 0x50, 0x72, 0x7d, 0xbb, 0x96, 0xda, 0xfa, 0x2a, 0xd0 } },
|
||||
{ "\xc2\xc9\x72\xce\xff\xc3\x27\x5e\x5b\x92\x60\x81\x02\x9b\xb1\x02\x9d\x5d\x66\x77\x33\x17\x80\xaf\xbc\x86\x4d\x47\x44\xcc\xa3\x5b\xb9\x6c\xb9\x5a\x51\x72\xa1\xf3\x9a\xb0\x66\x2c", 44, { 0x4e, 0x95, 0x9e, 0x13, 0xba, 0x8e, 0x68, 0xa8, 0xd2, 0xcb, 0x9c, 0xd6, 0xb0, 0x91, 0x48, 0xc9 } },
|
||||
{ "\x1f\x22\xbe\x91\xb4\x73\x6c\x89\x5f\x99\x35\xc4\xe3\x9b\x7c\xd0\xea\x73\x7c\xcb\xce\x0e\x22\x33\x04\x6f\x85\xd9\x25\xf4\x03\xf4\x9b\xb1\xf9\x52\xe4\xf8\x1e\xa9\x86\xfb\x7d\x0c\x8f", 45, { 0x32, 0x7d, 0xcc, 0x9a, 0x8b, 0x86, 0x41, 0xe3, 0x94, 0x5d, 0xb2, 0xa1, 0xc4, 0xf2, 0xb9, 0x9a } },
|
||||
{ "\x88\x0d\x79\xc8\xf2\xee\x8f\x76\x10\x42\x5d\xcc\x5f\xa6\x55\xf0\x43\x4c\x5f\xa8\x6b\xb7\x0a\xa1\x51\x11\xdd\x5c\xe1\x2c\xcc\xb6\x31\x13\xc6\x12\x6f\x4c\x6b\x24\xd9\xae\xdb\x5d\xe4\xd9", 46, { 0x9d, 0x7d, 0x73, 0xcf, 0x4b, 0x16, 0x28, 0xd1, 0x06, 0x3a, 0xde, 0xde, 0xf5, 0xdd, 0x8a, 0xda } },
|
||||
{ "\xaa\xee\x80\x55\xef\x7b\x73\x4a\x7c\x5e\xe2\xd9\x27\x95\xef\x17\x47\x49\x7b\xa4\x3b\xfc\x0c\xeb\x24\x4e\xca\xf8\xb2\x6b\xa4\xf0\x1c\x14\x90\x32\x29\x49\xef\x09\x6c\x91\x0e\x0a\x8d\xe5\xc9", 47, { 0x00, 0xf1, 0x9c, 0x62, 0x0b, 0xe5, 0x13, 0xde, 0x01, 0x5e, 0x1c, 0xe9, 0xf5, 0x8d, 0x5e, 0x54 } },
|
||||
{ "\x11\xc1\x3f\x4a\xd2\x5b\xba\xef\x1e\x7c\x66\x4a\xb5\xe6\xaa\x41\xc2\xef\x56\x56\xf7\x91\x45\x01\x45\x9e\xab\x3a\x38\x10\x01\x13\xee\x7f\x8a\x81\xb2\xab\x80\x3b\x39\x39\xe0\xba\x78\x7b\xcf\x61", 48, { 0xa9, 0x50, 0x1d, 0x59, 0x8d, 0x20, 0x34, 0xca, 0x14, 0xc3, 0xfe, 0xc6, 0xd2, 0x01, 0xcb, 0xc6 } },
|
||||
{ "\x20\x68\xa7\xb7\xb8\xab\xa3\xcf\x55\xd7\x23\xc9\xf7\xb7\x9b\x71\x83\xc3\x1e\x04\x59\xaf\x83\x13\x91\x1e\x31\x81\xd7\x75\x8d\xa6\xe0\xca\xfc\x96\x88\xfa\x97\x7c\x8a\xd9\x6b\x1f\xdb\x85\x69\x87\xa3", 49, { 0xc3, 0xf7, 0x89, 0x76, 0x95, 0xe3, 0xbd, 0x8c, 0xca, 0x78, 0xfd, 0x14, 0x43, 0xd5, 0x3b, 0xc0 } },
|
||||
{ "\xd4\xf1\xb9\xd9\xeb\xf5\x9d\x7a\xf0\xcd\x01\x65\xd7\x98\xb6\xd6\x59\x49\xd8\x7d\x03\x55\x2c\x3a\x6b\xf7\xa1\x78\x7d\x1e\xf9\x23\xf3\xf5\x81\x47\xe3\x0c\xfc\x46\x72\x28\x9e\xb6\xa6\xa4\x34\xd5\x5a\x81", 50, { 0x1c, 0x9d, 0x43, 0x52, 0xba, 0x7f, 0xc6, 0x30, 0x6b, 0x72, 0xd7, 0x96, 0x5b, 0xd1, 0x2d, 0xbf } },
|
||||
{ "\x61\xa9\x4a\x12\x02\xb8\x4e\x3d\xb3\x61\xa4\x6e\x6b\xd6\x66\x1e\x42\xb7\x1a\xfb\x54\x4b\x68\xb5\xbd\x5d\xe6\x65\xc3\xb1\x0f\x99\x13\x22\x53\x00\x24\x59\x48\xaf\xb8\x2c\xfe\x0d\x81\x90\x70\x62\xe0\x3c\x15", 51, { 0x7e, 0x5a, 0xb7, 0x6b, 0xb6, 0x54, 0xdf, 0x9e, 0x2f, 0xb5, 0x77, 0xf1, 0x9a, 0x6a, 0x59, 0x79 } },
|
||||
{ "\xf6\xc8\xdd\x96\xe9\xc2\xef\x9b\x8f\x09\x3f\xbf\x85\xd5\xfa\xa2\x55\xb5\x70\x1c\xc1\x15\x6b\x8e\xb0\xdf\x26\x55\xb2\x3e\xec\x58\x32\x7e\x4f\xc1\x37\x10\x01\xc8\xd6\xa9\x52\xab\x38\x89\x46\xba\x44\xd9\x52\x8e", 52, { 0xb9, 0x98, 0x85, 0xa3, 0x53, 0x84, 0x15, 0xf4, 0x7d, 0xbe, 0x68, 0xff, 0x96, 0x56, 0x6a, 0xc5 } },
|
||||
{ "\xe9\x2d\xb3\x5a\x09\x2a\x6c\x59\x05\x41\xda\x67\xe1\x99\xf5\xac\x14\x0b\x25\x73\xef\x47\xbe\x19\xa7\x14\x1a\x20\x01\xb4\x52\x63\x99\x65\x98\x64\xce\x04\x34\xc1\x4d\xcd\x19\xc5\x39\x3d\x24\x1b\xf4\x18\xf0\x9e\x8d", 53, { 0x78, 0x0a, 0x2e, 0xce, 0x91, 0xb5, 0xd9, 0xa2, 0xc1, 0x7f, 0xab, 0xd3, 0x93, 0x73, 0xc5, 0xf2 } },
|
||||
{ "\x86\x58\x4b\xc6\x59\x8a\x58\xc0\x6a\xc4\x5e\x45\x21\xaf\xb1\xb2\x12\x54\xd0\x7f\xc4\xbf\xf8\x6d\x8e\x2f\xd3\x4b\x9b\xf6\x4e\x64\x0c\xf3\x88\x88\x3c\xaa\xe6\xb5\x1f\xfd\x43\x63\xc3\x89\x45\x69\xf9\xa0\xcb\x8f\x0d\xde", 54, { 0x20, 0x66, 0xd7, 0xd2, 0x54, 0xf6, 0x4a, 0x99, 0xbd, 0x73, 0xde, 0x75, 0x3b, 0x07, 0xaa, 0x2a } },
|
||||
{ "\x82\xb1\xb0\x6a\x97\x8c\xf7\xcb\x86\x28\x7c\x64\x11\xe2\xa2\x8e\x4d\x15\xf7\x50\xd6\x64\xb2\xbd\x23\xa7\x5b\xeb\xf4\x70\x8a\x8b\xe8\x39\xc7\x2a\x2b\x2b\x91\x03\x4c\x8d\x7a\x7e\x2c\xc8\x6f\x49\x12\x13\x16\x12\xdc\xbf\x50", 55, { 0x0b, 0x6a, 0x58, 0xcd, 0x5c, 0x4b, 0xa5, 0xbe, 0xff, 0xdb, 0xff, 0x98, 0x89, 0x58, 0xe4, 0xe9 } },
|
||||
{ "\xde\x50\x21\xdd\x09\x91\x17\x1f\xda\xad\x39\xf7\xc2\x53\x9e\xcc\x32\xa2\x48\xaa\x16\x1c\x2d\x86\xf1\xb9\xe2\xa0\x96\x18\xe6\x01\x80\xd0\x89\x24\xcf\xe5\x77\xb1\xe0\x57\xe5\x64\x87\xd4\x57\x0d\xeb\x8d\x0b\xb0\xff\x25\x06\xcc", 56, { 0xcb, 0x43, 0x10, 0xa9, 0x26, 0xff, 0xaf, 0x74, 0xd9, 0xde, 0xc4, 0xab, 0xa2, 0x97, 0x12, 0x12 } },
|
||||
{ "\x99\xc6\xb8\xb9\x30\x4e\x4e\x2a\x37\xa7\x95\xd2\x10\x35\x86\x24\xaf\x68\x72\x32\xcc\x71\xcb\xb7\xc4\x11\x8c\x30\x0d\x8c\x46\x24\x54\xbd\xc8\x85\x35\x43\x6b\x2f\x96\xd9\xf7\x8d\xa0\xc4\x36\x5b\x5b\x65\x13\x85\xe6\xee\x6d\x2f\x4f", 57, { 0x69, 0x64, 0x39, 0x12, 0xc7, 0x7b, 0x98, 0x65, 0xf1, 0x8b, 0xc8, 0x61, 0xad, 0x18, 0x5e, 0x44 } },
|
||||
{ "\x31\x7e\xce\x15\x94\xe2\x73\x37\x21\x47\x28\xf8\xba\xb0\x73\x32\x69\x65\xf7\x54\xd6\x7b\x3a\xfa\xd2\xfc\x82\x28\x0f\xb2\xd8\x22\xf2\x95\x2e\xea\x81\xce\x9c\x57\x77\x67\xc6\xce\x77\x92\x5a\xa0\x5d\x93\xb6\x00\xaf\x4a\xa6\x9f\x32\x61", 58, { 0xc3, 0xc8, 0x1d, 0xfd, 0x52, 0x98, 0x05, 0x1b, 0xe1, 0x01, 0x1e, 0xbf, 0x18, 0xbd, 0x55, 0x5d } },
|
||||
{ "\x4b\xe6\x99\x0e\x17\xcf\x58\x85\xf4\x60\x98\xfe\x84\xc6\x43\x5e\x84\x0a\x3e\x84\x4a\x72\xb7\x33\x6d\x77\x94\x97\x83\x5d\x0a\x76\x05\x75\x4f\xf4\x4f\xeb\x67\x02\xc4\x4c\x1b\x65\x0f\x99\x09\x5f\x84\x00\xd4\xfc\xa4\x3d\x7b\xfa\xbf\x8d\xc7", 59, { 0x81, 0x50, 0x46, 0x50, 0xc1, 0x0e, 0x9f, 0xb5, 0x07, 0xaf, 0xde, 0xd3, 0x59, 0xfe, 0xcc, 0x22 } },
|
||||
{ "\x55\xb4\x4a\xde\x6f\xd4\x28\xf6\xd9\xe5\x0a\x23\xc1\x42\x82\x50\xf8\x20\xe4\x4c\x9e\xeb\x05\xfc\x6b\xce\x95\xaf\x9d\x52\x16\x8f\x7a\x1e\x78\x32\x81\xdd\x53\x50\x31\x3d\xc0\x8f\x75\x13\xd5\x7b\xaa\x9b\xbb\x91\x4f\xdd\x6c\x7a\x48\x2c\x0e\x55", 60, { 0xb4, 0xc3, 0xbe, 0x48, 0x13, 0x1d, 0x4c, 0xa6, 0x77, 0x96, 0xfb, 0x46, 0x00, 0xaa, 0xe0, 0x23 } },
|
||||
{ "\xcf\xc9\xe7\x2d\xf7\xa4\xfd\x8a\xde\x42\x4b\x23\x6f\xba\xa1\xb1\xd1\xd9\x19\xde\x70\x65\x31\x5c\xa6\x7f\x8a\x13\x05\x21\x3c\x72\x43\xc7\xd4\xe7\xc3\x2b\xeb\x69\xbc\x28\x64\x32\x08\xc0\x41\x8b\x8b\x39\x22\xbf\x3e\x62\x5c\x31\xd7\xf3\xb2\x8a\x17", 61, { 0xae, 0x50, 0xbd, 0x11, 0xb4, 0x2e, 0x1b, 0x32, 0xbc, 0x0a, 0x61, 0xb0, 0x07, 0x0c, 0xb7, 0x6e } },
|
||||
{ "\x12\xb3\x0a\xb0\xf2\xaf\x00\xd0\x96\x57\x55\x4e\xb4\xf0\x42\x70\xb4\x34\x21\x56\xd7\xc5\x61\x07\x75\x4f\x94\x17\x5e\x39\xa3\xf1\x62\x07\x21\xc7\xed\x4f\xbc\x13\xca\x55\xd0\xc8\x08\x46\x15\x1a\xfa\x0d\x79\xe7\x58\xd6\x09\xc0\x82\x1d\x08\x98\xe5\x72", 62, { 0xb6, 0x1f, 0xc7, 0x47, 0x6f, 0x2c, 0x1a, 0x33, 0xcd, 0x50, 0x40, 0xd0, 0x30, 0xd4, 0x96, 0x9f } },
|
||||
{ "\x22\x09\x76\xcb\xba\x3d\x5c\x85\x60\x7f\xaa\xf9\x5e\x5e\x4a\xb7\x71\x7b\xf5\x62\x95\xf0\x5e\x28\xf9\x5d\x6e\xdb\x12\x90\xaa\xb1\xcc\xd0\xb2\x95\xdb\xc7\xe3\x27\x2f\x09\x1b\x57\x85\x45\x9c\x99\x1a\x07\x09\xc5\x7a\x27\x8e\x8f\x77\xd2\x1d\x9e\x36\x32\xd3", 63, { 0x54, 0xbb, 0x99, 0xe2, 0xff, 0x14, 0xe1, 0xce, 0xa6, 0xb9, 0x6b, 0x77, 0xf9, 0x1f, 0x52, 0xd7 } },
|
||||
{ "\x4a\x64\xbd\x79\xf7\x86\x17\x25\x09\x6d\xa5\x01\x83\xc7\xaf\x23\x3f\xd2\x31\x9c\xcc\x2c\x3f\x8d\xdf\xc7\x12\x72\x78\xf8\xb3\x82\x93\xae\x42\x2f\x86\xbf\xe3\xc8\xfd\x5e\x46\x3f\x90\xa9\xd2\x04\xfe\x5f\x6e\x0f\x09\xaf\xeb\xfd\xed\x2b\x11\x52\x7e\xdc\x45\xdd", 64, { 0xa7, 0x71, 0x25, 0x07, 0x06, 0x4e, 0x0a, 0x46, 0xbb, 0x2f, 0xd6, 0x8a, 0x0b, 0x19, 0xda, 0x2f } },
|
||||
{ "\xdd\x6e\xd4\x39\xd6\x8c\xde\x6f\xda\x47\xe1\xb9\x94\xaf\xe1\x62\x29\x84\x32\xc9\x11\x06\xe2\x84\x8d\xe9\xc5\xa0\xc4\x65\x1d\x07\x7e\x69\xe6\xfb\x7c\xef\xbc\xbe\x71\x6b\x6a\x54\xa1\x5d\x10\x60\x15\x06\xf0\x2b\x78\x37\xd5\xc4\x92\x44\x20\x41\x5e\x18\x70\x23\xc9", 65, { 0x7e, 0x44, 0xc6, 0xdd, 0x7f, 0x97, 0x6b, 0x87, 0x68, 0x0a, 0xd6, 0x98, 0xec, 0x78, 0x88, 0x0b } },
|
||||
{ "\x62\xed\xd8\x0a\xed\x32\x59\x98\x0e\xd4\xf4\xcd\x36\x93\x24\x15\xa7\x1d\x9c\xd2\x44\x79\x63\xd0\x81\x16\x18\x60\x79\x71\x57\x13\x1e\x5d\x34\x15\x8a\xf2\xe4\x23\x75\x14\x7c\x2a\xc0\x9f\xd1\x7e\x2d\x2c\x7d\xb3\x32\x83\x03\x1c\xe2\x9d\x0a\xdd\x0b\x54\xc6\xaf\x5f\xa9", 66, { 0x1e, 0x1d, 0x15, 0x6e, 0x61, 0xaf, 0x88, 0x11, 0x0d, 0x63, 0xfc, 0x25, 0x8a, 0x13, 0x66, 0xb9 } },
|
||||
{ "\x74\x30\xca\xb2\x03\xe5\xe2\x1e\xd0\xcd\x7d\x66\x8a\xa2\x5c\x92\x35\xaf\x04\xa5\x4a\x49\xad\xa7\xfb\xeb\x54\x4d\x93\xf2\xeb\x46\xfc\xf1\xb1\x24\x5a\xb2\x9c\xe5\xd5\xca\xf1\x1e\x75\xd8\xf6\xc3\x26\x5a\xc0\x95\xda\x2b\x26\x28\xcd\x9d\xd6\x90\xe4\x2f\x85\xa8\x2f\xeb\x42", 67, { 0x8a, 0x89, 0xe2, 0xa9, 0xd2, 0xbb, 0xeb, 0x0c, 0xd6, 0x6c, 0xe7, 0x6b, 0xbd, 0xe1, 0xd3, 0xa7 } },
|
||||
{ "\xfe\x8e\x5f\xe4\x5e\x6f\x35\xa2\xfa\xb5\x71\xc1\x33\xb4\x47\x68\x06\x59\x97\x8f\x16\x67\x06\x16\x52\xdc\xba\xf2\x42\x72\xb1\x82\xf3\x41\xbf\x00\x7d\x81\x22\x12\x2e\x6e\xc3\x80\x55\x44\x0c\x01\xac\x6a\x60\x2e\x63\xab\x3b\x98\xc5\x9f\xe8\xf5\x89\x28\xd9\x75\xb8\x18\xa6\x33", 68, { 0x27, 0x2d, 0x93, 0x98, 0x27, 0x31, 0xa7, 0x1c, 0x09, 0x80, 0xd8, 0x3b, 0xcf, 0xde, 0x6f, 0x7a } },
|
||||
{ "\x35\xf0\xa5\xc6\xee\xc3\x22\xf8\x9e\x3a\x3b\x8e\x3c\xb0\x5b\x46\x03\x7d\x51\xdf\x1f\x50\x0c\x52\xf1\xb6\xf5\x1e\xff\xb7\xe9\xc1\x7b\x9f\xd2\x42\x6e\xda\xe1\xeb\x81\xf9\x69\x15\x68\xd1\x5b\x1b\xec\xc2\x5a\x71\x93\x15\x7a\xcd\xed\x7f\x9a\x83\x7e\xc2\x5b\xee\x43\x73\xbc\x0a\xe3", 69, { 0x00, 0x4e, 0xc2, 0xb8, 0x3e, 0xdf, 0x71, 0x7c, 0xc0, 0x9c, 0xd3, 0x98, 0x85, 0x4d, 0xc7, 0x95 } },
|
||||
{ "\xd6\x54\x1f\x73\xe5\x2b\x98\xe6\x70\x34\xf2\x10\x5e\x6b\xd0\x55\x11\x87\x2b\xf2\xe8\x5d\xa6\xe7\xde\xd1\xff\x80\x4f\x79\xa2\x7f\xdb\xd0\x58\xe8\x63\x13\x1c\x69\x31\xbb\x0e\x63\x34\x98\x81\x99\x68\x87\x2f\x74\x54\xd0\x8c\xf0\xad\x1e\x37\x27\x18\x1b\x8d\x78\x0d\xa8\x58\x54\xd7\xb6", 70, { 0x81, 0x58, 0x80, 0xad, 0x21, 0x1f, 0x75, 0x90, 0x18, 0x1c, 0x0a, 0xb5, 0xf2, 0xa3, 0x72, 0x34 } },
|
||||
{ "\xa5\xa5\xb7\xc4\xb3\xda\x29\xf5\x07\x93\x3e\xcd\x9d\xe6\x28\x88\x38\x4c\xd4\x17\xdb\x2c\xb2\xb8\x50\x01\x90\x30\xe5\x2a\xa4\xa8\x37\x4e\xa8\x21\x26\x69\x20\x96\xe8\x78\xb7\xad\x39\xbd\xc7\x19\xb0\xaf\xf8\x8f\x2d\x82\x00\x62\x6f\x4e\x88\xbd\xc2\xdf\x2f\x7d\xd5\x18\xa7\xa9\xa9\x04\xfd", 71, { 0xfb, 0x0d, 0x18, 0xc6, 0xe4, 0x89, 0x48, 0xb1, 0xf6, 0xfd, 0xeb, 0xe2, 0xc1, 0xf1, 0xf3, 0x23 } },
|
||||
{ "\x8e\xa6\x7b\xf7\x7b\xc8\x6d\x96\x16\xf6\xce\xbb\x5a\x73\x1e\xe6\x2e\x6d\x93\x19\xa2\xb3\xe6\xdb\xc8\x84\xb7\x58\x2d\x83\x9e\xa6\xf3\xc6\xcf\x22\x8c\x0d\x69\xf9\x15\x0f\x5b\xc3\x4d\xf0\xf3\x49\x30\xd0\x05\x67\x34\x7d\xb4\x0d\x1f\x48\xe0\x5f\x83\xf5\x2c\xfc\xd7\xcc\xaa\x5c\x34\xcc\x26\x53", 72, { 0x36, 0x75, 0xbc, 0x48, 0xda, 0x88, 0x50, 0x72, 0x0e, 0xf7, 0x29, 0x63, 0x24, 0x34, 0xe3, 0x39 } },
|
||||
{ "\xa9\xff\x0c\xb2\x3b\xe9\xf7\x0c\x7c\x1a\xd6\x96\xc6\xe3\xbd\x28\x15\x25\x46\x60\x7e\x45\xa1\xe6\x50\x3b\x3f\xc9\xc6\xca\x17\x08\x65\xca\x94\x2e\xf8\xa1\x1b\x14\x26\xd0\x3c\xca\xad\xa9\x74\x91\x3d\x1e\x9d\xff\xf3\xb5\xf3\x45\x70\x99\xc3\x8e\x96\xca\xb2\x7d\xdf\x73\xa7\xd9\x59\x5c\x56\x45\x42", 73, { 0x2e, 0x33, 0xf2, 0x55, 0x54, 0x86, 0xb7, 0xa7, 0x53, 0x25, 0xf2, 0xe5, 0x8a, 0x28, 0xf6, 0x82 } },
|
||||
{ "\x76\x6a\x28\x3c\x94\x4e\xab\x2c\x39\x99\xe0\xb5\x8c\x14\x00\x4c\x68\x68\xcd\xf8\x90\x69\x16\xa9\xff\xf9\x59\x32\x5e\x9a\x82\xe3\x8f\x94\xd2\xc7\x66\xbf\xdb\x77\x78\xee\xa7\x99\x0b\xf8\xf9\xf9\x2d\x64\xab\x41\xe0\xb0\x36\x58\x72\x3e\x50\x55\xec\xdc\xb0\x1f\xa0\xee\xed\xa3\xe5\x3a\x84\xb0\xe0\x50", 74, { 0xfd, 0xff, 0x52, 0x9f, 0xba, 0xe5, 0xe2, 0x49, 0xa8, 0xfa, 0x24, 0xec, 0xa0, 0xc7, 0x0b, 0x65 } },
|
||||
{ "\xf8\x72\x78\x94\x14\x89\x6b\xea\x4c\xc5\x7f\xfc\x42\x80\xd0\x2a\x64\x98\x48\x0f\xb2\x08\x2e\xad\x9d\x23\xd5\x34\x0b\x6c\x74\x74\x78\x14\x16\xdc\x36\x11\xa8\x2e\xd4\xd7\x30\xc1\x9d\xb5\x1d\x72\x38\xcf\xb9\x28\x6d\xb4\xba\x03\x07\x9b\xf8\x21\xd4\x3f\x3a\x0c\xc9\x54\x29\xc3\x42\xa4\x66\x64\x68\xcb\xb7", 75, { 0x17, 0x43, 0xcd, 0x6e, 0xf2, 0xfb, 0x65, 0xa6, 0x27, 0x7f, 0x7b, 0x30, 0xa9, 0x73, 0xb9, 0xe3 } },
|
||||
{ "\x73\xac\x8b\x5c\xc9\x6f\xcd\x80\x1b\xc4\x35\xcb\x26\x4d\x60\x14\x74\x42\xbd\x34\xce\x90\x05\xf6\x3f\x1d\x58\x2a\xc0\x2a\xf6\xd9\x85\xd2\x96\x92\xe3\xaf\x66\xe3\xdc\x9c\xa0\xe3\x49\x94\xc6\xec\xa2\xb9\x7a\x67\x6d\x71\xfc\xc0\x41\xab\x40\x78\x76\x40\xab\x58\x6c\x74\x6a\xc3\x74\x9b\x6f\x25\x5e\xd8\x09\x88", 76, { 0x1d, 0xc9, 0xfa, 0xc0, 0x76, 0x7a, 0xd0, 0x00, 0x3b, 0xec, 0xae, 0x60, 0x8f, 0xb8, 0x72, 0xb3 } },
|
||||
{ "\x9f\x01\x1f\x45\x1f\x9e\x09\xd7\x9d\x10\x0c\xcb\xc0\xcf\x6f\xd3\xbb\xcc\x3e\xfb\x9b\xf5\x9b\xf3\x30\xd7\xbb\x8a\x96\x5d\x84\x3c\x5f\xb6\xc2\xe2\x5e\x55\x00\x87\x12\x12\x09\x5b\xae\x6e\xfb\xc1\xc1\xf3\x04\x83\x87\xba\xbc\x25\xcb\x06\x1f\x57\x77\x0e\x25\x83\xba\xd8\x00\x87\xd4\x41\xf2\x7d\x81\x19\xc8\xb5\x00", 77, { 0x7e, 0x0a, 0x91, 0xef, 0x91, 0x65, 0x79, 0x1f, 0x66, 0x8b, 0x7e, 0xb7, 0xb3, 0xe1, 0x02, 0x61 } },
|
||||
{ "\x6b\xf6\xc4\xbe\xda\x50\xb6\xa4\x26\x63\x5e\xfa\xce\x6e\xcf\xf6\xd0\x00\xe3\xe5\x8c\x2f\xf8\xf5\xc7\x72\xbb\x9d\xca\x1c\x1c\xa9\xaa\x76\x61\xe5\xa3\x77\x56\x65\x9e\x22\xa2\x70\xd2\x7c\x36\x07\x86\x29\xde\x15\xf4\xa3\xfa\x34\x4a\x15\x46\x19\xca\xda\xd4\x9e\x11\x8d\x1c\x6b\x74\xcc\x2a\x3f\x86\x8e\xf5\xe0\xb6\x1e", 78, { 0xd2, 0x81, 0xce, 0x6f, 0x24, 0x4b, 0x96, 0x1b, 0x08, 0x0c, 0x6e, 0x2e, 0x55, 0xd5, 0x40, 0x8b } },
|
||||
{ "\xd0\x9d\x15\xb4\xf9\x7d\x36\xae\x4f\x06\x2e\x70\x21\xab\xbb\xd5\x22\xd3\x81\x50\x78\x82\x6f\xa4\xf3\xa6\x41\x3c\x5b\x00\x1e\x27\xe2\xad\x61\xb4\xb8\x51\x75\xa7\xbe\xdf\xd9\x15\x52\x06\x43\xe1\x49\x3b\xe1\xd3\xfa\x5f\xba\x52\x77\x0e\x33\xbe\xd7\x84\xae\x6c\xaf\x2b\x4d\x3f\x9f\xc5\xd4\xdf\x08\x32\xac\x99\xdb\xdf\x04", 79, { 0xb0, 0xc7, 0xe4, 0x19, 0x13, 0x5d, 0x32, 0x5b, 0x90, 0x39, 0x3c, 0x85, 0x8c, 0xd8, 0x61, 0xfd } },
|
||||
{ "\xd3\x8d\xcb\x12\x2a\x27\x37\x78\x2a\x79\xea\xc1\xa9\x6e\x1e\x0a\xc0\x7b\x0a\xbd\x67\x31\x0d\x79\xac\xf3\x74\x0e\x90\xc1\xe8\xa4\x7e\x32\x77\xfb\x69\x80\x3d\xcc\x81\xbd\xae\x4f\x91\x24\x83\xd6\xf8\x8b\x3f\x96\x41\xf4\x5d\x86\x62\x42\x18\x61\x8e\x08\xd6\xc5\xb7\x7d\x32\x7d\xa3\x8c\xa5\xdc\xaa\x08\xd0\x40\x0a\xfd\x68\xb6", 80, { 0x6a, 0xa7, 0xac, 0x63, 0x95, 0x32, 0x9d, 0xb9, 0x93, 0x8b, 0x41, 0xfe, 0xd5, 0x77, 0x03, 0x84 } },
|
||||
{ "\xe6\x21\xbe\xbc\xe1\x6a\xea\x21\x53\xb9\x93\x09\x27\xb4\x5e\x0d\x51\xb1\xf1\x7f\xee\xcd\xa3\xcb\xf9\x1d\xc2\xf8\xa7\xfc\x80\x4e\x61\x84\x7a\x12\x5c\x18\xe6\x6d\xd6\x1d\x59\x6b\xee\xc8\x33\x1e\x20\x12\xa8\xe3\x5d\xc9\x6b\xbc\xc3\xc0\xf9\xdd\xfe\x27\x7f\x42\x3a\xf5\x68\x7d\xc4\x81\x87\x8e\x3c\x30\xde\xea\x79\x49\x09\x9e\xf9", 81, { 0xa4, 0x46, 0x74, 0x55, 0xda, 0x5c, 0x22, 0x46, 0xf2, 0xb8, 0xd1, 0x7a, 0x5e, 0xa9, 0x22, 0x09 } },
|
||||
{ "\xe5\x4a\x8d\x03\x02\x32\xd5\x5c\xb6\xe8\x50\xa1\x80\x19\x36\x47\xba\x7c\xe0\x2d\x2a\x00\xa7\xdb\xb9\x95\xeb\x5a\x3b\x94\x30\xaf\x6c\xcc\x62\xf5\xfc\x2a\x39\x16\xc1\x04\xb7\x26\x0c\x02\xcf\x5c\x16\xa9\x20\xad\x98\x85\xde\x07\x79\xf3\xd2\x27\xa2\x88\x78\x17\xee\x22\x46\x48\x3d\x89\x0c\x47\xa7\xc1\x76\x1f\xce\xee\xaf\x4c\x4d\xe4", 82, { 0x67, 0x67, 0xb5, 0x70, 0xa1, 0xd2, 0x3b, 0x5c, 0xb5, 0xea, 0xb7, 0xf3, 0x39, 0xa9, 0xef, 0xf7 } },
|
||||
{ "\x20\x57\x4d\x4b\x56\x13\x36\x6b\x02\x72\x81\x9a\x19\x04\xac\x3f\x1c\x0e\x47\x82\x72\x43\x2c\x92\xf1\x22\xcc\x92\x7b\xeb\xa3\x21\xc5\x3f\xcd\x84\x33\x53\xb3\x73\xdf\xd0\xdd\x7d\xb9\x4b\xec\x18\xc8\x5c\x9f\x49\x8f\x5d\x12\xec\x8a\xc1\x08\xa1\xd7\x0e\x5d\x53\xf2\x78\x9e\x66\x99\x1c\xb4\x7c\xce\xd5\xbb\xe4\xfb\xbf\xf0\xa1\x2f\x46\xc9", 83, { 0xb9, 0x7f, 0x77, 0xa3, 0xd3, 0x37, 0x5f, 0x32, 0xbd, 0x36, 0x3b, 0x21, 0xb8, 0xd0, 0x42, 0xef } },
|
||||
{ "\x12\x87\xe9\x1f\x42\xa8\x91\x87\xce\x68\x88\xbe\x6f\x8c\x18\x42\x24\xac\xc1\xfd\xfd\x33\x15\x1c\x85\x83\x34\xff\xcd\x35\xe0\x49\x11\x7e\x3c\x16\x0a\xad\x26\x4c\xcf\xd0\x2d\x0b\x69\x76\x31\x3e\xf2\x90\x96\x53\x68\x71\x24\x07\x13\xf5\x7f\x5a\x91\xbd\x3e\xa2\x7b\x98\xa9\xbc\xb6\xfd\x14\x5d\x58\xb4\xd2\x86\x34\x95\xd8\x16\x04\x69\xf0\x79", 84, { 0x1d, 0x33, 0x53, 0x15, 0xa2, 0x3a, 0x5b, 0x3d, 0x37, 0x92, 0x65, 0xc7, 0x04, 0xb6, 0x7a, 0xd8 } },
|
||||
{ "\x32\xed\x96\x7e\x43\xf4\x73\x47\xe0\xac\x73\x59\x83\xf9\x85\xd4\xba\xfd\xef\xbc\x1b\xb9\x4b\x75\xc5\xcd\x21\x4e\x8e\x5b\x22\x34\xce\x0a\xff\x87\xc7\x26\xe4\x09\xaf\xe5\x95\xf2\x5c\xc5\x23\x22\x8c\x10\x4a\x6e\xcd\x81\x6a\x1b\x0f\x01\x20\x69\xc4\x8a\x81\x46\xb1\x2d\xf3\x24\x55\x2e\xa7\xe4\xf2\x4d\xb6\xf1\x3c\x20\xd7\x6a\x9d\x9b\xbb\x77\x23", 85, { 0x2d, 0x58, 0x23, 0x43, 0xe5, 0xa1, 0xc3, 0x4b, 0x28, 0x16, 0x9e, 0x76, 0xb5, 0x07, 0xd4, 0x3a } },
|
||||
{ "\xb2\x05\xbd\x07\x15\xe9\xec\xdb\x1a\x60\x75\x4f\xb9\x05\x59\x9f\xb0\x90\x1d\x9d\xc7\xec\xda\x56\x2e\xf6\x70\x64\x02\xd4\xdb\xd0\xee\xf0\x9e\xa1\xee\x90\x5b\x06\x2f\x14\x84\x1b\x13\xcb\x2c\x5b\x50\x71\xf7\xa3\x38\x49\x30\xdf\x13\xd3\xf9\x53\xa8\x2b\x9d\x88\xdb\xfe\x02\xd1\x70\x29\x3a\x78\xed\xf0\x38\x8a\x9e\xd7\x9f\x3c\xb2\x20\xb6\xf9\x83\xe2", 86, { 0x88, 0xef, 0x98, 0xec, 0xda, 0x19, 0xbe, 0xbe, 0x17, 0xb8, 0xe4, 0x4d, 0xea, 0x79, 0xc2, 0x82 } },
|
||||
{ "\x78\x09\xf3\xc3\xc8\xdf\xf2\x52\xc2\xff\x1b\x03\x2d\x8a\x7e\xc8\x0c\x67\x79\x48\x54\x10\xbf\xbe\xb7\xf6\x7a\x71\x9f\x92\x8d\xcb\x36\x0a\xf2\x19\xa2\x7c\x43\xde\x4e\xe9\x54\xd4\x64\xc1\xfd\x80\x57\x07\xf5\x71\x9c\x20\xd9\x15\x78\x3e\x4d\x37\xf4\x64\x39\x19\xee\x15\x35\x29\x4a\x9d\xff\x64\x45\xfb\x29\x44\xe9\x69\xd0\x67\x9d\x8a\x86\xbe\xd4\x2f\x51", 87, { 0x5a, 0x35, 0x4a, 0x9b, 0x4a, 0x1f, 0x23, 0x3b, 0x70, 0x42, 0xbb, 0x52, 0x31, 0x27, 0xee, 0xee } },
|
||||
{ "\x6e\xe6\xc6\xcd\x46\xfb\x60\x6c\xdd\x23\x5d\xde\x48\x84\xb7\x8c\x76\xab\xe7\x3d\x28\x03\x77\xdb\x8f\x63\x26\x50\x83\xc1\xb1\x8b\x5e\x04\x44\x9f\x73\xf8\x7d\x0a\x2e\x5b\x19\x12\xca\x14\x3d\x4b\xa9\x83\x63\x36\x53\xf3\xdf\x04\x0d\x2c\x0d\x78\x15\x26\x19\xea\x79\xd7\x6b\x67\x91\x2d\xad\xf6\x1f\x18\x7a\xf6\x01\xbe\xa4\xa3\x90\xd2\x22\xb7\x99\xff\x95\x2c", 88, { 0xdd, 0x18, 0xb1, 0x72, 0xbb, 0x74, 0x5b, 0xfc, 0x9b, 0x3f, 0x66, 0xec, 0xc2, 0x0a, 0x43, 0xcc } },
|
||||
{ "\xf6\x7e\x75\x20\xc8\xc7\xdc\xd2\x52\x63\xef\xc9\x75\xe0\xe5\x14\xc4\xde\xb5\xac\x43\x47\x60\xf5\xc1\x9c\xd8\x63\xcf\x6a\x8c\x3a\x5c\xdb\x91\x6e\xee\x68\x6e\xa8\x7f\xac\x84\x6a\xf2\x54\x18\x49\x30\x33\xff\x59\xe4\x72\xe5\xa8\xcf\xe5\x39\xe0\xc8\x78\xb8\x10\x54\xc8\x95\x84\xde\xce\x42\xd0\x93\xb6\xde\xec\xdc\xce\x3b\x79\x79\x99\x8a\x22\x37\x04\xa6\x1d\x4d", 89, { 0x95, 0xd2, 0xf3, 0xfa, 0x24, 0xcf, 0xd0, 0x6d, 0xca, 0x74, 0x7b, 0x13, 0x05, 0x68, 0xcd, 0x51 } },
|
||||
{ "\xb0\xfa\xd1\x59\x6e\x0f\x92\xf2\xc9\xb5\x87\xe9\xbc\xcd\xad\x21\x84\xb2\xf4\x08\x90\x42\x87\xb1\x96\x8c\x29\x90\xbf\x18\xbb\xd1\x02\xcd\xda\x55\x8f\x83\xa5\x4a\x61\x26\x9c\x65\xf6\x83\xa4\xbf\x1b\xb2\x27\x49\xe0\x20\x58\xee\xac\x38\x94\x44\x69\xae\xe4\xed\xdf\x68\x9f\x90\x1f\x09\x2c\x6f\x15\x1a\xe5\xa6\x41\xd7\x18\xff\x7f\x94\x27\x74\x02\xca\xcf\x42\x5f\xc2", 90, { 0x1c, 0x07, 0x39, 0x77, 0xf3, 0x7e, 0xb5, 0x17, 0xb5, 0x1c, 0x09, 0x97, 0xbb, 0x47, 0x34, 0xe3 } },
|
||||
{ "\x85\xa6\xc5\xdd\xfc\x37\x4b\x7e\xc4\xdf\x62\x94\x0c\x77\x6a\xc7\x88\xfe\x60\x3e\x6d\x76\xb4\x0b\x99\x5c\x38\x34\xd1\xc2\x35\x5f\x22\x0a\x98\x19\x68\x41\x4a\xc3\xed\x15\x9d\x19\x29\x75\xe1\x60\xa8\xc4\x17\x2c\x09\xb9\xbd\xcb\x22\xd5\xc8\x51\x41\x82\xb0\x41\x8d\xc5\xa5\xd5\x8c\xa0\xdf\xeb\xbe\x07\x13\x8c\x66\x7c\x01\x19\x68\x49\x2a\x14\x4d\x5a\xa0\x88\x64\xb4\xf5", 91, { 0x6b, 0xcf, 0x3d, 0x4f, 0x7a, 0x79, 0xf2, 0x5e, 0xe8, 0xd1, 0xda, 0xe9, 0x5e, 0xb1, 0x9c, 0xc5 } },
|
||||
{ "\x17\x04\x96\x55\x9e\xec\x2a\xb0\x86\xcb\xe8\x0f\xaa\xdb\x88\x08\xe0\xa7\xa1\x4d\x26\xee\xe3\x5e\x6b\xa0\xee\x5f\xf7\x05\xcc\x04\x77\xfd\x12\xa8\xa9\x62\x8e\x7d\xa0\x89\xad\xde\xb4\xe8\x6c\xc1\x0a\xd1\xf9\x48\xbc\x5c\xe6\x76\xa4\x64\x08\xfe\xca\xa7\xf2\x37\x68\x11\x09\x2d\x96\x12\x44\xd1\x96\x2b\x83\x50\xbe\x89\x88\x80\xfe\xc8\x96\x77\x0d\xd8\xa4\x36\x35\xfd\x3e\x83", 92, { 0x0a, 0x40, 0xa5, 0x22, 0x7b, 0xe3, 0x34, 0x40, 0xb1, 0x02, 0xa4, 0xf4, 0x4a, 0x1d, 0x26, 0xcb } },
|
||||
{ "\xb7\xf0\xf9\xd4\xdc\x23\x91\x67\x99\x22\xa1\x6f\xdd\x15\xfd\x68\x7b\x62\xaf\x8c\xaf\x6f\x8d\x5e\x4f\x85\x74\x63\x8f\xd0\x23\xf0\x71\x83\xb6\x1f\xc7\x18\xbc\xdb\xe6\xb5\xf8\x1b\xe9\xaa\xb1\x2c\x9f\x17\xb6\x26\x12\xab\xf2\x80\xb5\x87\xa7\xc0\x29\x40\x4b\x4a\xac\x03\xfc\x5a\x1e\xd3\xa0\x0d\xb1\xef\x9d\x99\x2d\x4f\x32\x9e\xde\x4c\x70\x94\x1b\x5f\xd9\x63\x73\x01\x93\x11\x75", 93, { 0x83, 0x24, 0x5e, 0x67, 0xff, 0x3f, 0xf3, 0xac, 0x7f, 0x5d, 0x83, 0xda, 0x0f, 0x0f, 0x3b, 0x66 } },
|
||||
{ "\xb2\x49\x95\x1c\x16\x9f\xcb\xd5\x39\x4f\x81\x2f\xf3\xe5\xae\x1e\x67\x13\xc2\xec\xa5\xb2\x19\xbd\x70\x56\x89\xbd\x19\x8c\x1a\xe8\x8a\xb2\xd5\x75\x5f\x73\xb5\xe0\x2e\xdf\xba\x93\xe7\x23\x1d\x30\x57\xe9\x9e\x7e\xc7\x4f\xf9\xed\xc1\x7c\x77\xc7\xf2\xe5\xa0\xf5\x2b\x1b\x0e\x6c\x81\x4e\x5c\x32\x95\x62\x3e\x11\xee\xac\xab\xd6\x82\x49\x34\x46\x54\x1b\x78\x9f\x37\x61\xb0\xc6\xb0\xf2", 94, { 0xc1, 0xa1, 0x23, 0x7f, 0xf0, 0x11, 0x23, 0xcf, 0x64, 0xb1, 0x96, 0x5d, 0xb6, 0xb5, 0x34, 0xe0 } },
|
||||
{ "\x66\x12\xf9\x16\x43\xb3\x22\x01\x05\xc0\x53\xed\x8f\xdd\x2c\xd2\x1a\x85\x4d\xc5\x8a\xfa\xf1\xeb\xdb\xc6\xb5\x18\xba\xec\x77\x08\x30\xb0\x59\x38\x79\x00\xe5\x62\xf3\x7e\x4b\x94\x32\x2b\xc5\xec\x30\xb1\x1b\xf2\xa2\x4d\x42\x92\x65\x57\x20\xb4\x17\x6f\x6b\x7a\xc3\x46\xaf\x15\xb4\x06\x6e\x44\x6a\x5f\x61\x6b\xaa\x2f\xdd\x4c\xb0\xcd\x51\x64\x80\xf3\xec\xe4\x5b\x45\x5b\x4a\x4c\x82\xb0", 95, { 0x5c, 0xe8, 0x8d, 0x8c, 0xb0, 0x07, 0x9f, 0xc3, 0x82, 0x01, 0x92, 0x4f, 0x7d, 0xb2, 0x46, 0x76 } },
|
||||
{ "\x9c\xe1\x46\x5e\x41\xf7\x79\x61\x7c\xaf\x58\x7a\x85\x7d\x1e\x98\x46\x5f\x4e\x53\xaf\x2a\xa0\x91\xb6\xff\x86\x4b\xef\xdd\x59\x6a\xc3\x50\x25\xcb\x50\x48\x0d\x62\xdd\x04\x5d\x7a\xf8\x2d\x2a\x1a\x2e\xff\xa8\x83\x67\xa2\x08\xd7\xdb\x97\x0b\xd4\xb5\x4e\x28\xbd\x42\xd4\x56\x59\xd6\xa9\x77\x15\x3c\xb0\x61\x44\xd7\x3f\x89\x87\x59\x56\x4e\x48\x1f\xed\xe0\x60\x28\x66\xcb\xd9\xb1\x22\x24\xcd", 96, { 0x13, 0x2f, 0xc8, 0x0f, 0xaf, 0x52, 0x90, 0x3f, 0x45, 0x2f, 0x80, 0x39, 0xa5, 0x04, 0x8c, 0xd4 } },
|
||||
{ "\x6e\x2f\x4e\x6d\x66\x1f\x69\x1e\x6c\xf4\x59\xbd\x35\x37\x6e\x03\x1b\x28\xb5\x04\x6d\x0f\xda\xd1\x70\xb1\xb8\x3e\xf7\xde\x7f\xbe\x9a\x27\x81\x6a\x96\xae\x99\x20\x41\x16\x38\xc8\x28\x98\x0d\xb2\xc7\x37\x51\x1b\xe4\x0c\xac\xcf\x88\xbb\xc7\xe8\x9b\x06\x6f\xb4\x1b\x80\x62\xb5\xf8\x59\xba\xc2\x90\x58\xf3\x4a\xc2\xe8\x9b\xb8\xb1\x49\x95\xf3\x17\xe7\x09\xfd\x43\xc8\xec\xbb\xb0\x1e\x27\xd3\x44", 97, { 0xe5, 0x04, 0x88, 0xc9, 0xa8, 0x97, 0xde, 0x0f, 0xc3, 0x2b, 0xee, 0x13, 0xc6, 0x06, 0x7c, 0x2d } },
|
||||
{ "\xfc\x66\xb1\x22\x26\x80\xa5\x2c\x01\x7e\x26\x18\xa9\x4a\x3a\x2d\x21\xf6\xed\x9b\xa5\xa5\xfe\x75\x1c\x1a\x9a\x4c\xa9\xdb\x40\x69\x61\x01\xc3\xa6\x17\x9f\x6e\xe9\x52\xcd\x41\x3e\x60\x50\x5a\x91\x84\xe7\x6f\x05\x4a\x34\x78\xf3\xfc\x46\x69\x82\x2d\xbf\x1d\xdf\x72\xa7\x4e\x19\x30\xcc\xc1\x9c\x91\xd3\x7f\x48\x91\xe0\x3d\x2e\x34\xdd\xdd\xe7\xda\x6b\x0d\x90\xaa\x63\x0e\x65\x2c\x07\x8f\xf9\xf3\xcb", 98, { 0xf8, 0x09, 0xb6, 0x5e, 0xb8, 0xfb, 0xde, 0x39, 0xd6, 0xfe, 0x1c, 0xd8, 0x44, 0x48, 0x7f, 0x01 } },
|
||||
{ "\xb7\x0f\x77\xb9\x42\x19\x01\x85\xc3\x4a\xbf\x2d\x07\x5a\xf7\x4c\x9a\xd6\x59\xfd\x63\x21\x6d\x66\x6a\x0b\x2b\xe8\xba\x0b\xa9\xe1\x62\x1c\xef\x1c\x95\x32\xe6\xd6\xf1\x58\x6f\x6e\xdd\x68\x91\xa8\x0b\x66\xca\x9d\x1d\x79\x86\x43\x64\x86\xad\x95\xc3\x6a\x57\x5f\xb2\xd4\x9b\xa8\x5e\xbe\x85\xbb\xee\x86\x25\xd4\xe1\xad\xc4\x64\x93\x2b\x32\x01\xde\x6c\x3b\xed\xdd\xeb\x38\x41\xcc\x6a\xc1\xb7\x0b\xcb\x80", 99, { 0x4e, 0x3f, 0xa9, 0x33, 0xaf, 0x6e, 0x3a, 0xac, 0xc0, 0x29, 0x88, 0x8f, 0x91, 0x86, 0xc9, 0x7c } },
|
||||
{ "\x11\x42\x8e\x21\x28\x9e\xe8\x65\x94\x38\x7c\x56\xf5\x97\xb8\x95\xdc\x4c\xcf\xcf\x5a\xbc\x4e\x4e\x22\xfa\x5d\xab\x5d\xd2\x95\xa2\x0b\xe3\x78\xfe\x10\xe4\x91\xb3\xe3\x07\x29\x0a\xce\x7a\xa3\xf7\xe2\x0a\x75\x86\x7b\xe2\xc3\x74\x6c\x72\x9a\xda\xc6\x6b\xc5\x04\x4a\xe6\x50\x60\x69\xa4\x97\x92\xf3\x70\x09\xa4\x64\xa1\x7f\x5b\xc8\xbc\x33\xa5\x47\x36\x5e\x2e\x51\x56\x72\x11\x66\x39\xf1\xab\x82\xef\xe8\x8c", 100, { 0xbe, 0x63, 0xc5, 0x40, 0x5e, 0x75, 0x2c, 0x1d, 0x52, 0xb3, 0x28, 0x39, 0x09, 0x05, 0x7b, 0x4d } },
|
||||
{ "\x24\xc3\x0c\x87\xfa\x99\x6f\xe9\x2b\x6f\xdf\xc6\x40\x06\xdc\x6f\xb0\x9a\x33\xff\x06\xcc\x3b\x15\xb1\xa1\xab\x9c\x68\xa3\x17\xc5\x38\x25\x05\x16\x2b\xa4\xb0\x9c\x97\x49\x58\x3c\x00\x8c\x44\x28\xab\xf2\x56\x6d\xc0\xf6\x49\xa8\x1a\x06\x89\xd8\xaf\xa4\xae\x4f\x97\xad\x97\xc3\xba\xb7\x1f\x81\x1b\x93\x7f\xc1\xbb\xf1\x40\x14\x2b\x23\xda\xfa\xb2\xfa\xee\x90\x16\xcd\x1d\x66\x0b\x98\x83\x6f\x35\x40\xd4\x11\xdc", 101, { 0xd6, 0x38, 0x85, 0xcf, 0x1e, 0xaf, 0x84, 0xf1, 0x6a, 0x8f, 0x77, 0xc8, 0xab, 0x9e, 0x1a, 0x64 } },
|
||||
{ "\xf4\x11\x5d\x2b\xb0\xe6\x59\x25\xdb\xa3\x78\x25\x10\xd5\x2b\x10\xfa\x81\x90\x19\x59\xfc\x49\x30\x21\x6a\x68\x08\xc1\xd1\x86\xc3\x81\xd9\xf3\x3d\x04\x22\x07\xf2\xed\x42\x97\x8d\x9e\x59\x83\x0e\x1c\x53\x6d\x96\x0f\xba\x84\xd2\xe5\x36\x7e\x02\x15\xa2\xa4\xa5\x81\xcb\x07\xc3\xf4\xc7\xd0\xd6\xcb\xf0\xb5\x56\xb1\x7c\x88\xe0\x83\xba\xe9\x02\x52\xeb\x1c\xa5\x86\xbb\xf5\x18\x1f\x5a\xf0\xb5\x17\x3c\x5d\x32\xe4\x69", 102, { 0x7b, 0xe8, 0xa1, 0x02, 0xa6, 0x52, 0xe9, 0x3b, 0x9d, 0xb4, 0xbc, 0x95, 0xba, 0x9e, 0xd1, 0x07 } },
|
||||
{ "\xb8\x86\x19\x81\x17\x75\x2c\x50\xbc\xba\x52\x0a\xca\xd0\x87\x23\x15\x5e\xaa\xcd\x12\x3d\xc4\x0f\xed\x27\x69\x7f\xba\xfd\x37\x9c\xc3\xb4\x7b\xca\xff\xde\xf4\xea\xa4\xd1\xaf\x95\xd4\x76\x11\xf6\x72\xb0\xf3\x41\x18\x66\xe7\xd4\x21\x2f\x9a\xe8\xe1\x99\x52\xf4\xf4\x16\x96\x9e\xb4\x84\xec\x5e\xc4\x57\xbd\xb2\xc9\x66\x55\xf8\x39\x4e\x07\xeb\x4b\x87\x6d\xbc\x0e\x01\xcd\xcc\x96\x7a\x98\x04\x50\x5f\x0c\xd2\x77\x5c\xf9", 103, { 0x60, 0xd0, 0x9d, 0x98, 0xae, 0xef, 0x2b, 0x51, 0xa0, 0x3c, 0x5d, 0x3c, 0x71, 0xa6, 0x4a, 0x5b } },
|
||||
{ "\xc0\x9f\x82\xa0\xb2\x6f\x14\xb6\xbc\x6c\xee\x89\x9e\xf0\x93\x3a\xdd\x39\xd1\x28\x7f\x9d\x13\x6d\x62\xdb\x43\x82\x39\x8e\x5a\xfe\x24\xbb\x85\x7b\xeb\x89\xf5\x99\xd8\x10\x44\x1c\x2e\x49\x7f\x31\x49\x26\xd4\xce\x53\xbb\xd9\x37\xa0\x99\x76\x9c\xa7\x3c\x71\xdf\x9e\x9a\x94\x74\xb1\xdb\x7d\x62\xde\x28\x02\x66\x70\x9d\x3e\x36\x15\x58\x3d\xe3\x9e\xb3\x40\x57\x54\x8e\xad\xfe\xf1\xc5\x96\x82\x42\xc1\xe4\xae\x57\x2a\x20\x74", 104, { 0x1a, 0xe2, 0xe9, 0xa9, 0xb1, 0xf0, 0x27, 0x90, 0x7d, 0xf3, 0x66, 0x14, 0x07, 0xe0, 0xe9, 0xdc } },
|
||||
{ "\x63\xba\xdd\x0a\x37\x2d\xc6\x2e\x56\x54\x40\x8b\xb4\x49\xbb\x34\x10\xbd\x9a\x4d\xeb\x6d\xbc\xc8\x23\xb4\xa7\x4d\x31\x39\x51\x33\xfc\xc8\x8a\xab\x57\x3f\x09\xfd\x1e\x9f\x11\xea\xe8\x42\xbf\x2f\x69\x2b\xf3\x2b\x67\x79\xd9\x98\x57\xf6\x13\x75\x94\xcc\x85\x04\x3b\x57\xbc\xef\xa5\x16\xfb\x86\x82\xba\xe4\x23\x8e\x61\xc0\xaf\xf3\xdc\x6b\x3d\x3b\x2c\xdf\xd4\xf0\x0c\x5b\x4a\xd3\xa8\x2f\x4b\xb5\x6b\x27\x79\xf5\xf6\x91\xae\x96", 105, { 0x0c, 0x2a, 0x47, 0x52, 0xba, 0xb6, 0xca, 0x3e, 0xb2, 0x6e, 0x64, 0x53, 0x9f, 0x3d, 0x3f, 0xf2 } },
|
||||
{ "\x2c\xed\x5c\xfb\x6a\x31\x16\x42\xd4\xb6\x27\x3b\xcb\xc2\x60\x04\x7a\xb3\xf0\x42\x90\xc4\x6b\xfe\x08\x7f\xed\x19\x23\xbf\x58\x6d\x78\x61\xb8\x82\x21\x87\xc8\xea\x17\x88\x8e\x3a\x98\x77\x21\xa5\xc4\x4f\x8b\x36\x48\xb8\xc9\xaa\x31\x78\xef\xe7\xe2\x79\x68\x1d\x21\x72\x5b\x78\x4b\x35\x2a\x7f\xa8\x95\x14\x0c\xd9\xf2\xfa\xe8\x6e\x63\x3f\x02\x94\x7e\xc8\x4c\xeb\xc7\x23\x33\x76\xb2\xc4\xb9\xac\x56\x6a\x30\xab\xb1\xa0\x95\x8c\x92", 106, { 0x73, 0x8a, 0xe1, 0x0f, 0xcf, 0x84, 0x6e, 0xf5, 0x84, 0xab, 0x8b, 0x58, 0xd5, 0x1b, 0xc8, 0x95 } },
|
||||
{ "\x5f\x86\xd1\x27\xd0\xe1\xfb\x23\x30\xfb\x39\x8b\xcd\x7a\x3a\x1e\x2d\xd0\x23\x5f\x4d\x54\x9d\x40\x07\xfe\x05\x6d\x8d\xbf\xc7\x32\x11\x7b\xc5\x09\x87\xa4\xf0\xc4\x82\x74\xfa\x53\x3b\xc7\x22\x33\xb1\x92\x2e\x74\xea\x04\x77\x64\x57\x37\x1e\xdd\x55\x93\x5c\x28\xd0\xc0\xf8\x8d\x02\x45\xd1\x79\x59\xc2\x9b\x49\x77\xc6\xa7\xb9\x53\x4e\xda\xe4\x7c\xdb\xbf\xf7\x7e\x2e\xb9\x76\x5d\xa3\x51\x2a\x3e\x28\xae\xa6\x26\xd8\x22\x75\xd9\x38\xe0", 107, { 0x4e, 0x61, 0xed, 0x55, 0xbd, 0x31, 0x31, 0x6f, 0xa6, 0xa6, 0x8f, 0xde, 0x2b, 0x8f, 0x51, 0x60 } },
|
||||
{ "\xe3\xe4\x0c\xcc\x64\xb7\xd7\x6b\xa4\xea\xee\xfa\x2b\xa0\x38\x9a\xac\x09\x84\xa8\xeb\x01\x87\x2b\x4a\xd6\x71\x67\xee\x27\x2a\x8e\x92\xe7\x2e\x96\xe8\x81\x02\x26\xa7\x16\x51\xa9\x36\xe1\xa8\x85\xf3\xbc\xcb\x66\x20\xbb\xb2\xb4\x6a\xf6\x23\x23\x18\x65\xed\x68\xcd\xe3\xbe\x09\xf9\x55\xa2\x4d\xe2\xe4\x18\x53\x4b\x66\xd3\x3f\xbe\xda\x0a\x8f\x7b\x12\x7c\x8b\xfd\x6b\x04\xdb\x25\xb8\xd4\x33\x06\x3d\x51\x29\x4c\xd7\x8b\x26\x49\x39\x57\x7b", 108, { 0x35, 0x50, 0xf9, 0xfe, 0xb2, 0x42, 0x8e, 0x9b, 0x20, 0x2d, 0x1f, 0xd7, 0x1b, 0x32, 0x8a, 0x93 } },
|
||||
{ "\x9d\x51\x0b\x8b\x82\xc9\xd6\x26\xb2\xa9\xb9\xf7\xf5\x19\x26\x13\x4a\x44\x33\xb1\xb1\x59\x7b\xf9\x93\xab\x92\xf5\xcf\xf8\x22\xa4\x63\xc7\xa7\x2d\xb2\xea\xc3\x31\x77\x23\x3e\x39\x47\xe3\x9e\x4e\xbc\x2e\x5f\xa8\x44\x9a\xd0\x7e\x84\x75\x8a\xfc\x6a\x06\x8d\x53\xce\xec\xf8\xea\xc4\xa4\x65\xb2\x80\x26\xdf\x97\xe6\xae\x81\x12\xae\x98\xac\xdb\x31\x64\xe4\xbc\xd2\xda\x47\x81\x0b\x47\xac\x0c\x13\xe5\x54\x85\x29\x58\x4f\xae\x80\x55\x6f\x54\xc7", 109, { 0x3a, 0xf8, 0x64, 0x70, 0xe9, 0x73, 0x58, 0x6b, 0x98, 0xb5, 0xdd, 0xbd, 0xfc, 0x56, 0x38, 0xc1 } },
|
||||
{ "\x5d\xe1\xe1\x54\xa7\x6d\x0f\xec\x1c\x4a\xb7\x31\x7c\x9e\xc7\xa9\x9e\x92\x52\x67\xd4\x0f\xc2\x58\x6d\x17\x28\x2c\x54\xc2\xb4\xde\xd5\xd3\x40\xe2\x80\xf6\x06\xeb\x26\x98\x73\x56\x00\x63\x13\x36\xf0\x55\xab\xfc\xdf\x7c\x65\xc3\x45\x50\x26\x36\xc6\xac\xfc\x1f\xfa\x6b\xb3\x8c\x45\x9b\x86\xa0\xe5\x61\xf3\xf3\x0b\x69\xa7\xa7\x20\x07\x99\x08\x28\xef\x33\xdf\x44\x8d\xaa\x54\x51\x02\x6f\x7d\xae\xbc\xbd\x87\x1c\xb1\x53\x7f\xbe\x38\x3c\xbe\x3f\x84", 110, { 0x96, 0x3d, 0x85, 0x1f, 0xc8, 0xcf, 0x7e, 0x10, 0xe1, 0x2c, 0x33, 0xe0, 0x8a, 0x3b, 0x50, 0x98 } },
|
||||
{ "\xc9\xef\x12\xbd\xa1\xbe\xd5\xbd\xef\x1f\xcf\x64\xb9\x38\x98\x98\x51\xec\xd8\xdc\xe4\x05\x27\x8c\x2f\xfd\x14\xb2\x52\x69\x41\x89\xbd\x03\xac\x8c\x47\x52\x08\x39\x5d\xf8\x49\x67\x57\x98\x3f\x41\xe6\x62\x5a\xde\xaa\x3c\x8c\x7e\xe0\x8e\x4c\x64\x39\xaa\xb6\x4b\xc5\xd7\xcf\x86\x0e\xf9\xe7\xb7\x42\xde\x17\x2b\x87\x27\xea\xd1\x73\xd1\x18\xd5\x94\x5f\x6d\xde\x29\xa6\xc9\xe0\xf4\x34\x40\x9e\x27\x5e\x61\xc0\x7b\xe5\x94\x8c\x60\x44\x9d\x44\x4f\x99\x3d", 111, { 0x50, 0x81, 0x50, 0xba, 0x15, 0x74, 0xa5, 0xf8, 0x00, 0x23, 0x1f, 0xe5, 0xf0, 0x1a, 0xef, 0x6f } },
|
||||
{ "\x1c\x3b\x2d\xf7\xd7\x25\xa2\xf0\xfd\xcf\xb8\xf0\xbb\x88\xbc\x85\x57\x26\x8d\x46\x4e\x12\x4c\x35\x0b\x7d\xa0\x3e\x46\xb1\xa2\xdc\xf8\x82\x6c\xdb\xf6\xe3\x39\x38\x31\x95\x39\x24\x89\xf9\xf4\x27\x49\x07\x58\x62\x43\x57\x61\xed\x89\x5d\x63\x5e\xc5\xb2\xf7\x6b\x36\x8d\x80\xa7\x48\x50\x59\x68\xce\x3e\x9d\xca\xde\x4b\x92\xcc\x49\x0c\xb2\x97\xb5\xce\x58\xdf\x59\xc2\x04\x62\x55\x56\x4b\x8e\xac\x9e\x5e\x40\xdf\xf1\x34\xa6\x27\x91\x57\x45\x4e\x82\x48\x16", 112, { 0x24, 0xfa, 0x3a, 0xa0, 0x34, 0xeb, 0x16, 0x59, 0xd6, 0x98, 0xf1, 0x66, 0xad, 0xfb, 0xf7, 0x93 } },
|
||||
{ "\x2a\x7b\x90\xcc\xb7\xfa\x65\x31\xd0\x72\xf5\xae\x8a\xa0\x51\xe9\x2d\xfc\xf9\x89\xd0\x4a\x00\x15\x90\x4f\xdc\xfa\x6c\xa1\xcc\xab\xc0\x98\xe6\xe3\x5c\x61\xbc\x06\x41\x30\xaa\xa5\xf7\x95\xbf\x20\x8e\xe8\x46\x66\x2f\xdf\xf0\xd9\x5d\x3e\x9f\x4c\xce\xad\xd1\x2e\xe0\xa5\xa7\xc0\xba\x84\x91\x82\x00\xc1\x99\xac\x32\x39\x48\xd8\xa2\xa8\x38\xbd\x10\x33\x38\x15\xe3\x21\x15\xa0\x06\xaa\x0b\x42\x5d\xe8\xc8\x48\xe3\xea\x19\xc8\x62\xe8\x34\x26\xcd\x90\xa1\xb3\x3d", 113, { 0xa1, 0xc5, 0xd1, 0x2c, 0x14, 0xcf, 0xb3, 0xd5, 0x90, 0xa0, 0xe8, 0x8d, 0xef, 0x19, 0xa2, 0xdc } },
|
||||
{ "\x7f\xc5\x6f\x87\xcb\x0c\xef\x76\xbd\xb2\x5a\xaa\x9c\x2f\x8d\x0c\xa4\x3d\x5f\xec\x16\x87\xfe\xba\x69\xef\x78\x5e\x9e\x7c\x56\x34\xb1\xdf\x63\xa7\x2b\xa0\x8a\x69\xd4\xea\xdd\x4c\x86\xef\xb2\xc0\x1d\xf9\xe8\xea\x8b\x0f\x47\x5d\x08\x40\x05\x77\x66\x8f\x65\x5a\x82\x7a\x7a\x86\xd7\x29\x0a\x10\x2c\x30\x8d\x81\x6e\x01\x55\x4e\x98\xf1\xc7\xef\xce\xe5\xc7\x9e\x8a\x99\x32\xad\xed\x8c\x85\x84\x37\x8c\x9b\x36\x52\xd9\x93\xc0\x89\xf9\xd0\xdd\x56\x18\x19\x89\x58\x19", 114, { 0x65, 0x16, 0xd9, 0xfd, 0x97, 0x36, 0x97, 0x2c, 0x1d, 0x90, 0xe6, 0xb9, 0x11, 0x75, 0x7e, 0xd1 } },
|
||||
{ "\xe1\x10\x63\x3d\xa2\xd1\xb2\x6e\x62\x94\x37\x29\x58\x85\x13\x06\xa7\xcd\x21\xe6\x49\xcc\xad\xb8\x07\xf4\x43\xe7\xa4\x45\xa1\x64\x1a\x61\xce\x4b\xfc\x4b\x44\x35\xfa\xc0\x48\x19\x83\x32\x5b\xdf\x85\x5d\xc8\x83\x50\x88\x5e\xe2\x98\x5a\x38\x25\x99\x57\xb8\xc7\x55\xf5\x92\x44\xf9\x5f\x04\x5f\x5e\xc5\x24\x10\xab\x5e\x51\x09\x17\xfb\xcb\xe4\xcc\x49\x5f\xeb\xe7\xa3\x3b\x83\x9c\x92\xe0\x35\x77\xe2\x34\x5a\xbd\x62\xb7\x63\xf1\x37\xce\xc3\x72\xdd\x3b\x79\x41\xbc\xae", 115, { 0xdd, 0xa6, 0xd8, 0x85, 0x1a, 0x69, 0x15, 0x50, 0xbb, 0x0b, 0x98, 0x6a, 0x04, 0x95, 0x94, 0x7b } },
|
||||
{ "\x3d\xe1\x62\x74\x46\x57\x63\x4e\xb6\x51\xca\x5d\xa3\x63\x3b\x38\xc3\x6c\xa7\x20\xb3\x17\xaa\x4b\xe4\x7d\x84\x5c\x23\xe8\xb2\xf4\xc3\xb3\x28\x62\x68\x4d\x2e\x76\x73\x5c\xd4\x73\x05\xfe\x13\x22\xb2\x2a\x82\x03\xc4\x35\xb1\x9f\x29\x71\x26\xf9\xfa\xf0\xf2\x22\xa8\x66\xee\xec\xc5\x2c\x97\xb6\x6d\x61\x83\x67\x4f\x2b\x80\x76\x5b\x1b\x48\x25\x0a\xaf\xe2\xcd\x45\xf0\x97\x55\xf3\x3c\x8f\xbc\x22\x1e\x09\xd6\xd1\x59\x34\x14\x57\x04\xac\x7b\x74\xcf\x94\xb7\xf3\x63\x4c\x49", 116, { 0xc8, 0x45, 0x92, 0xb3, 0xa3, 0xee, 0xed, 0x4c, 0x7d, 0xad, 0x54, 0x75, 0xbd, 0x5e, 0xc8, 0x88 } },
|
||||
{ "\xf8\xe8\xcf\xdb\xec\xa0\xac\xb4\x01\xb0\x9f\x46\x64\xff\xcc\xe5\xff\x37\x97\x92\xe7\xe9\x22\xf6\x69\xcd\x64\x6a\xac\x27\xe3\x33\x03\x44\x0e\xcb\xd2\x23\x39\x5a\x19\x31\x35\x44\xa2\x2d\x8b\xdb\xc3\x2b\x55\x35\xd1\xb4\xba\x19\x21\x0a\x04\x13\xbc\x89\x60\xa7\x9e\x28\x31\xa2\xab\x1f\x10\x8c\x2f\xa3\x65\x39\x10\xcd\x9b\x7e\x93\x99\x03\x01\xc7\x09\x47\x2a\x92\x69\x88\x36\x56\xae\x17\x6a\x3f\xf8\xcd\x64\x2b\x37\x08\x8c\x37\xe9\x42\xaa\xe2\x01\x4f\x92\xe1\xe3\x33\xfa\x7f", 117, { 0xce, 0x59, 0x2a, 0x66, 0xbd, 0x8e, 0xcc, 0x02, 0x56, 0xa9, 0xb2, 0x02, 0x08, 0x00, 0x60, 0xf2 } },
|
||||
{ "\x8c\x9d\x6c\xad\xcf\x04\x56\xad\xba\x5d\x3f\x57\x17\x76\x14\x07\x0e\xf2\xa1\x24\xe8\xe1\x1b\x4d\xee\xfb\xd9\x21\x70\x7a\x23\xab\xe1\x91\x23\x69\x20\x8c\xf9\xf8\xd2\x85\xea\x5d\xea\xc0\xb8\xf2\x4a\xa4\x0c\xeb\x83\x57\x10\x84\xb9\xf4\x19\xc9\xa2\x6c\x82\x01\xad\xf6\x94\xb8\x3f\x34\xa1\x68\x18\xe4\x30\xc3\xd4\x3f\x52\xa0\x8e\xf2\x13\x7f\x9f\xb6\x0c\xba\x84\x8e\x15\x4b\xdd\x9c\x19\x34\x92\xa1\x02\x8f\x10\x10\xd2\x32\xb1\xcd\xd3\xfe\x3a\x87\xe7\xc5\x7e\xae\xf9\xd5\x1f\x13", 118, { 0x21, 0xc8, 0x1d, 0xc6, 0x45, 0xbe, 0xfc, 0x87, 0x21, 0x04, 0xc5, 0xc2, 0x14, 0x3b, 0x40, 0x91 } },
|
||||
{ "\x94\x25\x74\x1c\x92\x1b\x86\xa0\xec\xf8\x35\x65\xb1\xe1\x78\x33\x12\x8b\xc2\x94\x9a\x81\x7f\x2b\x7a\x15\xbd\xaf\x02\xe1\xe8\x82\x2c\xf9\xae\xf2\x53\xaf\x01\x0b\x01\x01\x3b\x16\xe5\xa3\x5b\xb3\xe3\xa5\x6d\x8e\x46\xc2\x08\xc1\x11\x44\xf1\xc6\x73\x96\xdd\x17\x58\x68\x54\x64\x1c\x79\xb1\x70\x5a\x04\x46\x89\xe3\xc9\x9c\xa2\xcb\xb6\xd8\x0e\x9d\x32\x39\xdb\xae\x07\xbd\xc9\x8f\xe9\xe3\xe6\x9c\xa7\x8c\xc7\xb1\xed\xfb\x65\xfc\xb3\xfb\x91\xee\x46\x20\x15\x4b\xf1\x25\x69\x62\x48\x74", 119, { 0xc1, 0x1f, 0x44, 0xbf, 0x5d, 0x95, 0xee, 0x5f, 0x2e, 0x4f, 0xef, 0x28, 0x62, 0xf6, 0xe7, 0x5c } },
|
||||
{ "\x0f\x56\x10\xc5\x8c\x9a\xce\xde\x03\x7b\xeb\x78\x6f\xd7\x81\x42\x7c\xeb\xc4\xff\x03\x4a\x0f\xca\x20\xea\x8a\x7a\xf2\x59\x76\x20\xef\x0d\x15\xad\xe1\xd8\x39\xb1\x81\x7a\x67\x3e\xae\x50\xa6\xeb\x4a\x2b\xea\xf4\xb2\x3c\x18\x7f\xd8\x2b\xb6\xf9\xfe\x46\x31\x9f\x10\xd6\xc9\x19\x9f\x8e\x1d\x40\x76\x1d\x4e\x00\xdb\xe3\xd3\x59\x63\xbf\xd9\x7f\x72\x07\x55\x22\x4f\x91\xa7\xc8\xe0\xee\xec\x55\x06\xb7\xe0\xad\x97\xff\x6e\x70\xf4\xe8\xd7\xe4\x47\x51\x7a\xf1\x5c\xad\x45\x45\x18\xef\xb9\x98", 120, { 0xf6, 0x28, 0x50, 0x22, 0xdd, 0x55, 0xfc, 0xba, 0xb4, 0x4c, 0xc4, 0x1f, 0xa7, 0x92, 0x8a, 0x03 } },
|
||||
{ "\x9a\xa1\x93\x09\xec\x14\x1c\xa7\x65\xb2\x0f\x0d\x9f\x6f\x22\x25\x11\x5e\x33\x0d\x48\x60\x10\x16\xc7\xf7\xe3\xe9\x77\x38\x38\xc4\xcc\xdf\xad\xe2\x77\x7c\x35\xf9\xc1\xcc\x08\xdd\x8b\x23\x2b\x42\xdf\x04\x97\x9e\x32\xd3\x09\x2d\x38\xa1\x65\x0e\x64\x27\xc8\x8b\xfb\xcf\x29\x76\xd4\xeb\xaa\xae\xae\x08\x81\xc1\x2e\x5d\x7d\xab\x73\x5e\x38\xbd\x58\x6e\xd8\x99\x45\xb1\x81\x5a\xb2\xff\x5b\xd0\x3a\xf4\x3b\xe8\x57\x24\xf0\x2b\xc0\x6c\x2d\x5d\x5c\x64\x0e\x45\xe1\xf0\x48\x8d\x0e\xf6\xf2\xbf\x81", 121, { 0xec, 0x78, 0x08, 0x73, 0x5a, 0xc1, 0xb9, 0x65, 0xd2, 0xa0, 0x7c, 0x7c, 0xfb, 0x45, 0x7b, 0xb2 } },
|
||||
{ "\x29\xea\x6f\x36\x04\xe5\x78\x9c\xd3\x17\x5e\x55\xeb\x7b\xd3\x8b\xfa\xbf\x55\xea\x79\xd0\xf4\x3d\x3e\xfd\x31\xa8\x2d\xca\x02\x7f\x0f\x54\xf3\xc2\x7b\x5c\x66\x37\xf0\xf1\xfb\x22\x05\xbe\x0b\xa2\xb7\xee\x4d\xab\xe2\xb7\x9b\x9b\xcb\x8a\xcf\x7b\xda\xd5\xc7\xd5\x65\x73\x89\x2d\xa6\xb2\x7f\x1d\xcf\xfe\xe3\x10\x34\x2e\x36\x9b\xa7\x6b\xe9\x73\xe2\xb9\x1f\x0f\x1c\x23\x8a\xdb\xbe\x87\x72\x15\x2f\xfb\xd4\x48\xcc\xdb\xa7\x63\xf3\x71\x3a\x76\x3e\x3f\xb9\x08\xce\xeb\xce\x17\xbd\xc8\x63\xad\xb5\xfd", 122, { 0x41, 0x22, 0x16, 0xa5, 0xec, 0x77, 0xcc, 0x6c, 0x26, 0x63, 0x46, 0xa1, 0xf4, 0xe3, 0x94, 0x6e } },
|
||||
{ "\x86\x1b\x9f\x54\x66\xd5\x73\xa1\x7a\xe9\x2e\xcc\xc1\x1d\xe2\x7e\x24\xa5\xe7\x64\xf7\x7e\x2f\x23\x9e\x6a\xb7\xd8\x4c\x88\x1a\x4a\xe7\x8f\x40\xaf\x08\xa7\x33\x17\x1e\xe4\x12\x79\xb1\x60\x1e\x59\xc4\xf3\xf1\x12\x55\x91\xcf\xc5\xfe\x41\x15\xde\xbd\xb6\xce\x40\xd1\x8c\x65\x0d\xbb\x20\x74\x13\x64\x0c\xbb\xd6\x5d\x3e\x2c\x36\x40\xb3\x22\xbd\x36\xd5\xb2\x87\x93\x6f\x1a\xce\x9b\x49\x57\x12\x68\x65\xd2\xe1\xe3\xd4\x3a\x48\xef\x35\x6d\xd6\xa6\xcb\x8f\x49\xbb\x3a\x3d\xd8\xff\xde\xdc\x1c\xff\xc9\x0b", 123, { 0x09, 0xff, 0x3e, 0x2d, 0x99, 0x55, 0xc5, 0x1e, 0x17, 0xcc, 0xc1, 0xdd, 0x07, 0x11, 0x8a, 0x62 } },
|
||||
{ "\x9c\xca\x57\x37\xf3\xd0\x6e\x4c\xa0\xe5\x57\x89\x6a\x65\x34\x6c\x6e\x72\x1d\xcd\xc7\x59\xdb\x07\xd8\x13\x40\x50\x39\xe7\x21\x2a\x3b\x2d\xf2\xf2\x1a\x2d\xfc\x96\xbe\x25\x3d\x64\x2e\x69\xdc\xfd\x92\xa5\x47\x68\xe2\x3e\xeb\x43\x31\xd7\x8f\x14\x90\xf0\x4e\xbd\xa0\xa8\x2f\x0e\xb8\xa3\x62\x75\xae\x06\x1a\xd0\x46\x9f\x01\x63\x35\x22\x5d\xe5\xd0\x8e\xbd\xb5\x56\xaf\x5f\x2a\xd6\xbc\x22\x07\xbf\x20\x22\x0d\x02\x56\xf5\xab\xe6\xed\x81\xd1\x68\xab\x78\xe2\x4c\xce\x72\xc8\xc4\x6d\xa5\x21\xbc\xfe\x43\x97", 124, { 0xe3, 0xc6, 0x50, 0x53, 0x82, 0x8e, 0xf8, 0xd1, 0x42, 0x08, 0xdc, 0xf3, 0x3b, 0x60, 0x8d, 0xc7 } },
|
||||
{ "\xc0\xf1\x71\x4d\x8b\x79\xdf\x75\x2d\x6a\x08\xfe\xd7\x3d\x08\x6b\x46\x31\x15\xbf\xca\x8c\x9b\x94\xf2\x00\xf8\x4c\xd6\x28\xd1\x5e\x01\x31\x0f\xd2\xf9\x96\x7a\xc8\x6b\x03\xf0\x31\xf8\x5b\x41\xa1\x96\xd5\xaa\x3d\xa4\x41\xed\xcf\x8f\x69\x09\xf8\x1a\x92\x9b\x85\x4d\x22\xd1\xda\xfc\x5b\x07\x8a\xf2\x45\x00\x09\xbb\xaa\xc2\x79\x0b\x3b\x0e\xa0\xce\xd0\x7a\xfb\xcd\xcd\x2d\xeb\xfa\xa0\x37\x0e\x58\x66\x8a\xa9\x89\xad\x99\x41\xf5\x54\x8c\x49\x94\x8f\x1d\xf5\x59\x07\x12\x2d\x3c\x1e\x57\x9d\xe2\x50\xb7\xe9\xea", 125, { 0x8e, 0xb8, 0x75, 0x22, 0x66, 0x98, 0xd0, 0x80, 0x2d, 0xcc, 0x7a, 0x6e, 0x92, 0x96, 0x2e, 0xe8 } },
|
||||
{ "\xb5\x37\xfe\xd6\xa3\x0f\x84\x94\x70\x46\x6f\xa9\x55\xe9\xb5\xf9\x6e\xe7\x1a\x35\xdd\x8c\x26\xe1\x0f\x98\x38\x00\x16\xfc\xb5\x5f\x36\x30\x59\x7c\x7b\x33\xad\x11\x87\x20\x99\x40\x6a\x6a\x11\x5c\xaa\xb4\xeb\x51\x62\x50\xd1\xb2\x86\x51\x52\x5d\x44\x4e\x13\xcd\x86\xb6\x22\xfc\x94\xcb\x6b\xf3\xd7\x3d\x43\xef\xb8\x64\x22\x32\xa7\x18\x6e\x63\x38\x30\x72\xa2\x67\x96\x6d\x2c\xfc\x04\xc7\xa8\x0a\x5d\x5e\x0c\x91\xaa\xff\x2f\x43\xaf\xf1\xeb\x64\x29\xab\xee\xca\xa7\xa5\x1e\x04\x02\x4b\xa6\x97\x7b\x0e\xa2\x63\x6f", 126, { 0x97, 0xa7, 0x1a, 0x12, 0xd4, 0x55, 0xc2, 0x52, 0x09, 0xa9, 0x14, 0xbd, 0x78, 0x17, 0xf5, 0xd7 } },
|
||||
{ "\x95\x63\x25\xb9\x12\x5f\x16\xa4\xaf\xb8\xb0\x8b\x26\x67\x90\x10\x70\x05\x76\xf5\x95\x36\x6a\x9a\xa2\xb2\xfa\x13\xb9\xf1\x9e\xe5\x42\x73\x3c\x5e\x3f\xa9\xc6\x8e\xbe\x83\x01\xe5\x67\x97\x61\x6b\x35\xea\x11\x96\x42\x5f\x0e\xcb\xba\xba\x73\x74\xf2\x4f\xcf\xba\x91\x4b\xb2\xdf\xec\x9e\x47\x3b\x70\x84\x1b\xd2\x38\xaf\xfc\x8e\xbf\x13\xfc\x1d\xaf\x4d\x95\x69\xd8\xb1\xe6\xb0\x3c\xee\x1c\x41\x47\x60\xec\xd2\x1c\xf2\x3c\x80\x0a\xae\xe1\x63\x1d\xe3\x83\xcd\xd1\xf2\x9d\x20\xe2\xb5\xa1\x49\x3e\x8b\x38\xdd\x1c\x04\xa7", 127, { 0x94, 0x7d, 0x6b, 0x70, 0x52, 0xe6, 0x4a, 0xbd, 0xc1, 0x5b, 0xbc, 0x11, 0x26, 0x8c, 0x48, 0xb3 } },
|
||||
{ "\xce\x26\x26\x4d\xca\xd2\x5a\x49\x30\xcf\xf6\x38\xaf\x9a\x68\x1c\x7d\x2f\xfb\x58\x31\xdd\x49\xd7\x3e\x32\x3e\x4d\x0d\x16\xc4\x96\xb6\xf4\x10\x3a\x5a\x13\x89\x12\x1f\x03\x50\x04\xc9\x32\x70\xe9\xf2\x9e\xa4\x90\xe6\xa5\xbf\xdc\x1d\xf8\xbc\x08\x55\xae\x62\x0b\x4c\x75\x93\x16\x17\xe3\x32\x3b\x22\xea\xaf\x27\xc5\x6a\x31\x10\x7f\xe1\x5f\xaa\xd1\x3d\xca\x52\xb9\xd2\xfa\x4e\xc9\x67\x13\x2c\xe4\x6b\x23\x46\x95\x45\x0b\x67\x0c\xc9\x08\x88\xb6\xc6\xde\xb3\x78\xbc\xa0\x09\x87\xab\x1e\xdf\xe7\x06\xeb\x02\x7d\xc7\x09\x1b", 128, { 0x14, 0x39, 0x8a, 0x7a, 0x34, 0x95, 0xeb, 0x11, 0x5f, 0xf6, 0x04, 0x23, 0x14, 0xa9, 0xb1, 0x51 } },
|
||||
{ "\xd3\x9c\x34\x2e\x69\x3f\xc8\x3c\xb2\xe3\x4f\x09\xb2\xca\xab\xf8\x31\xf3\xdc\x12\x9c\xf1\x6f\x25\x79\xd7\x84\x09\x85\x50\x7a\xfe\x6d\xcb\x39\x31\x25\xd3\x1b\x5d\xe7\x7c\x78\x8e\xcb\xf9\xcc\x02\xff\x4b\x87\x28\xa4\x14\x72\xca\x46\x8a\xb9\x46\xf5\x87\x99\xf7\x04\xbc\xa6\xb4\x5e\x06\xb9\x6e\x80\xd9\x76\xfd\x16\xd8\x76\xf4\x36\x87\x15\xb0\x33\x18\xd9\x70\x1f\x61\x7d\x9e\xe1\xef\x9a\x2c\xee\x34\xf1\x1a\xa7\xdb\x57\x14\x4f\x3c\x3d\x37\xa8\xeb\xdb\xf4\x29\x6b\xf9\x0d\xdd\x00\x5a\xbd\xda\xa2\xc5\xf4\x5d\x0e\xb1\xc0\x7f", 129, { 0xa6, 0x03, 0x6e, 0x71, 0xb9, 0x65, 0xc3, 0x1c, 0xaa, 0x8e, 0x3b, 0xc0, 0xab, 0x74, 0x07, 0xf0 } },
|
||||
{ "\xf6\x8c\xc7\x96\x58\xa8\xf1\x2b\xec\xc3\x22\x93\xb6\x31\x25\x2c\xbc\xa8\xa4\x36\xd2\xa8\x53\x4b\x91\x85\x2d\x7c\x66\x12\xd7\x0a\xc6\xec\x20\xbe\x7f\x60\xaa\xe5\x2a\xfa\xa2\xec\xbd\xab\xaa\x93\x3d\x95\xd9\xd1\x90\x77\xd8\x45\x70\xb0\x2d\x54\x7c\xf1\x94\xe3\x68\x84\x89\xb2\x55\x33\xe3\x53\x3c\xd6\x9a\xc7\x83\x7d\xa9\xb4\xb2\x36\x0f\x44\x3f\x7b\xef\x9c\x85\x3b\xd7\xf7\xd3\x83\x1d\x5f\xa1\xc9\x65\x08\xde\xd5\x40\x49\x65\x4c\xef\x37\x8d\xdb\x45\xe0\xdf\xfc\xaa\x21\xe3\x68\x3b\x25\x13\x19\x0f\x7a\xf1\xfb\x95\xd1\x34\x2f", 130, { 0x93, 0xfb, 0xf2, 0x73, 0x89, 0x24, 0x2e, 0x2d, 0xf7, 0xf6, 0x94, 0x0b, 0xfe, 0x0f, 0xfc, 0x89 } },
|
||||
{ "\x19\x52\x1e\xfa\x65\x9a\xe9\x50\x84\x52\x5f\xf9\xa2\x6d\x89\x5e\x0f\xfd\x7f\xf3\x62\xb3\x5e\x40\xba\xf1\x58\x8d\x20\x8e\xe6\x29\x08\x25\x18\x57\xf7\x1a\x0c\xd6\x3e\x2b\x7d\x0c\xe4\xae\x73\xce\xa2\x6d\x18\xce\x07\x1a\xab\xa2\xbc\x70\x8d\x6d\xe2\xe9\x79\x2c\x97\x16\xd1\x9f\x98\x9e\x13\xd1\x00\xd5\x6a\x46\x2f\xf8\x61\xc1\xc6\x03\xb2\xaf\xce\x2f\x3d\x33\xf8\x0b\x14\xcf\xff\x36\xb3\xab\x2a\xb7\x4d\x86\xed\xf9\x41\x36\xaf\x66\xac\xdd\xa7\x9e\x18\xaa\xdf\x54\x51\x49\x5b\xc5\x58\xe9\x53\xd6\x71\xe7\x9b\xca\x57\x1c\x23\x9d\x90", 131, { 0xf0, 0x21, 0xdf, 0x96, 0x22, 0x89, 0xf7, 0xca, 0x7b, 0x3d, 0x32, 0xbe, 0xc3, 0x70, 0x87, 0x87 } },
|
||||
{ "\xc0\x9b\xff\xdb\xf9\x2f\xf0\xc5\x04\x70\xf4\x5a\xfe\x52\xf4\xf9\x50\x52\xb1\x41\xb5\xb0\xe5\x27\xea\xda\xf8\x2a\xf1\xe9\x5c\x9d\x01\x44\x85\x23\x0d\x62\x88\x3a\xef\xae\x4f\xed\x31\x83\x77\xad\x78\x56\xc6\x3b\x8e\xf3\x4c\xbc\x0a\xe0\x15\xee\x9e\xde\x87\x7a\xfd\x8d\x5f\x5f\x67\x2f\x42\x8e\xd2\x85\x03\x95\xb7\xd5\x70\x73\x76\x0d\xd9\x8a\x66\x02\x1e\xb2\x7d\xd1\x74\x69\x99\x66\xb4\x29\x69\x1b\x5f\xd2\xfa\x78\x32\x47\xe2\x19\x62\x15\x03\xad\x75\x4c\xfc\x1a\xbd\x72\x32\xbe\x71\x8d\x76\xd1\x69\x5f\x53\xe6\x76\xaf\xf7\x90\x5b\xc1", 132, { 0x6e, 0x38, 0x9a, 0xae, 0x82, 0xdf, 0x52, 0xff, 0xe8, 0xed, 0xfc, 0x75, 0xe6, 0x9a, 0xdc, 0x14 } },
|
||||
{ "\xbc\x21\x6c\xe7\x51\x8e\xc2\x30\x89\x6e\x19\x3f\xc0\x21\x46\x38\xe6\x0e\x57\xd3\x29\x04\x49\x92\x43\xc2\x60\x0f\x5d\x92\x27\x6f\x9e\x0f\x04\xf3\x55\x08\x77\xad\xbf\x7d\xef\x4f\x75\xc6\x49\x1e\x75\xd3\xe6\x06\xcb\x8e\x67\xc8\xdb\x5d\x08\x4f\x4e\xc3\x96\x20\x97\x26\x0e\xee\x21\xab\xd4\x4d\x17\x3d\x8c\x7f\xcf\xad\x99\x6b\xd4\xf4\x30\xab\x8e\x93\x18\xc4\x90\x1b\x00\x71\x7e\xc9\x7c\x18\x99\x49\x9e\x5e\xe9\x9b\x2d\xd6\x06\x13\x85\xd4\x82\x7a\x0a\x60\xf6\x53\x4a\x46\xa8\x38\xaf\x4b\xd6\x62\xdd\x7a\xa1\x46\xae\x9c\x99\x5d\xc7\xc5\xe1", 133, { 0xc4, 0xd1, 0x37, 0xe5, 0xf5, 0x29, 0xa4, 0xa2, 0xf0, 0xf2, 0x27, 0x54, 0x17, 0x1f, 0x12, 0x2c } },
|
||||
{ "\xfd\xd7\x0b\xff\x63\x6c\x52\x42\xd2\x71\x43\xd0\xd4\x48\x5b\x4b\x9f\x80\x1f\x20\x93\x33\x6e\x6c\xe0\xff\xee\x8a\x45\x9f\xa8\x3d\xf3\x25\xb0\x77\x90\xd6\xfd\xc4\x57\xa2\x57\x56\x5c\x3e\x6e\xad\xed\xe0\x06\xe3\x14\x96\x50\x91\x3a\x44\x55\x62\xe6\x38\x8b\x32\xa2\x6c\x8a\xe2\xfe\x57\xd8\xbb\xae\x70\xe0\x7c\xce\x40\x02\x01\x46\x22\xc4\x92\x49\x9a\x25\xc6\xf7\x50\x12\x12\x23\xa8\xf2\xf3\x2e\xfe\x5c\xb3\x12\x83\xe8\xda\x7b\xaf\x23\x35\x0f\x62\x9c\x7c\xcf\x9b\x1b\xa2\x95\xd3\xf1\xbe\xbd\xf7\x6b\x91\xe1\x01\x60\xb3\xbc\x32\xea\x5f\x30\xee", 134, { 0xec, 0x22, 0x50, 0xb3, 0x22, 0x24, 0x26, 0x6d, 0x36, 0xda, 0xd2, 0xa4, 0xc6, 0xc7, 0xd1, 0x20 } },
|
||||
{ "\x31\xd7\x62\x33\x63\x75\x03\xb7\xc0\x50\xaa\x9e\xd1\x87\x5d\xd5\xb8\x2d\x2f\x0e\xa3\xd1\x03\x58\x5a\xa8\x6e\x5a\xf8\x5a\xbb\x2b\xb7\x66\x08\xd1\xe4\x32\x8d\x55\xf1\xb3\xfd\x7f\xa9\xb5\x04\x34\x7e\xc7\xf1\x68\xfe\xc7\x6e\xc1\x64\x05\x6a\xca\x4b\x17\x17\xd0\x7e\x39\x0f\x5d\xea\x5e\x92\x4e\xb5\xd7\xea\x93\x67\x9f\xef\x83\x46\x41\xa7\xda\xc1\x66\x05\x50\x02\xff\xd2\xd6\xa6\x0b\xa9\x70\x89\x05\x1c\xaa\xba\xee\xf5\xb8\x8e\xf2\x96\x2e\xd0\xba\x82\x58\x16\x4d\xf4\x37\x2f\xa3\xad\x19\xb8\xc8\xcc\xd3\xce\xa9\xd5\x9e\xdd\x7f\xd4\x8c\x97\xd5\x9a", 135, { 0x24, 0x9d, 0xa1, 0xd8, 0x65, 0x77, 0x2f, 0x84, 0x7f, 0x6b, 0x6a, 0xc7, 0xec, 0x38, 0x7c, 0x68 } },
|
||||
{ "\xa5\x01\x37\x26\xa2\xa7\x79\x20\x45\xf0\xa1\x7e\x53\x8c\x72\x49\x2f\x09\x96\x7a\x15\x85\x67\xfe\xef\x7e\x5a\xd9\xd7\xc5\x08\x66\x2a\x91\xda\xbd\x45\xb0\x51\x2d\xdf\xd9\xf0\xe8\x03\x1c\xc6\xbe\xa8\x7a\x9c\x02\xef\x91\xb7\x89\xf8\x70\x4a\xd0\x60\x89\x7b\x3d\x5b\xc4\x10\x7e\x6b\xb0\xb6\x0e\xbb\xd4\xee\xd6\x1a\x24\x94\xf0\x97\x8f\x0d\x86\xb5\xb5\x0d\xd9\x4b\xb6\x03\x5e\xfb\x26\x21\x02\x4c\x1c\x0b\x8f\x67\x6a\x1b\x27\x6b\xe6\x4f\xec\x6d\xe7\xd0\xc2\x0f\xcc\x1f\x2c\xbb\xb6\xde\x53\x7d\x55\x39\x25\x7b\xe0\xef\x9a\x11\x1e\x01\x12\x8d\xa2\xf5\xdb", 136, { 0x77, 0xfc, 0x95, 0x17, 0xdd, 0xeb, 0xc5, 0xa5, 0x2f, 0x8d, 0x90, 0xd8, 0xd1, 0x38, 0x80, 0x09 } },
|
||||
{ "\x84\x14\xc7\xce\xcf\xa9\x6d\x18\x26\xb4\x06\x16\x56\x56\x9e\x5a\x22\x51\xa0\xcb\xb4\xfb\xd9\xe9\xbe\x4e\x25\x2d\x32\x1c\xb8\x8e\x9a\x60\x0b\x20\x14\xaf\x60\xd7\xee\xcd\xf4\x6a\xda\x5b\xc1\x53\xce\xae\xed\xf2\x7b\xbc\xd2\xd1\x67\x30\xab\x03\xa9\x9d\xd7\xa5\x41\xce\xcd\x86\x11\x3b\x9d\xe3\x7c\x99\x1f\x4b\x9a\x89\xba\xa1\x15\x70\xd2\x40\xa3\x66\xcf\x39\x20\x47\xc7\xb7\x46\xe8\xc7\x84\x0c\x64\xc3\xa4\x99\x94\x17\x1f\xe4\x9c\xb9\xdd\xea\xa2\xfe\xa9\x8a\x9a\x05\x58\x00\x3d\xc4\x03\xfc\x18\xad\x6f\x5e\xc1\xfc\x8e\x91\x24\xa0\x1e\x81\xfb\xc3\x70\x3a", 137, { 0xd2, 0x39, 0x29, 0x3a, 0xe7, 0x3c, 0xc8, 0x48, 0x93, 0x9d, 0x84, 0x3d, 0x11, 0x7c, 0xd9, 0x72 } },
|
||||
{ "\x5c\xf8\x43\x1f\x6c\x00\xcf\xc3\x31\x39\xdd\x67\x86\xa4\x13\x11\x27\x91\x4e\x45\xec\xe9\x28\x62\x13\x18\x99\x9c\xb6\x95\xb9\x92\x5b\x0f\xa3\x8c\xaa\x36\x76\x52\x39\x23\x75\xab\x83\x64\x4e\x71\xf8\xa8\x78\x4d\x2e\x03\xb5\x15\x35\xdf\xb7\xbf\x08\x80\xdf\x00\x1e\x32\x20\x85\x20\x11\x02\xcd\xb6\x75\xc3\xa1\x7b\xf8\x98\x31\x0f\x25\x11\xcd\x4a\xbe\x9a\x3c\x8d\xaa\x1d\xbd\x35\x79\xc5\x97\x29\x96\xde\x5f\x93\x08\xd8\xc6\xac\xe4\x6a\x1c\xaf\x53\xd4\x65\xef\x3c\x3c\x16\x04\x8d\x3a\x6d\x21\x2b\x6f\x6a\x81\x74\x50\x6d\x00\x6d\x01\x6d\xc6\x8d\x5c\xd2\x1e\x25", 138, { 0x0e, 0xfb, 0x6c, 0xcd, 0xb4, 0x7f, 0xb9, 0xa7, 0x2b, 0xcc, 0x94, 0x5f, 0x1f, 0x1c, 0x9b, 0x52 } },
|
||||
{ "\x10\xf0\x65\x6a\xe6\x21\x1d\x21\x1f\x7e\x21\xe5\xfa\x3a\xf3\x18\x52\x9b\x31\x64\x63\x95\x27\xed\xad\x04\x7d\x15\xf1\x85\x11\xeb\x58\xf2\xe0\x31\xb3\x79\x1d\x08\xdd\x59\x64\x3a\x3d\x38\x08\x24\x68\x23\x88\x3e\xe3\x22\x21\x48\x06\x77\x7d\x13\xfb\x73\x89\xea\xe6\xf6\x64\x9b\x1f\x81\x73\x25\x9a\xf9\x91\xff\x68\xfb\x64\x03\x56\xd6\xcb\xf6\xb3\x29\x73\xb4\x30\x1a\x89\xfc\xdf\x30\x89\xd6\x5e\xce\x35\x9d\x0d\x4d\xa2\xad\x7a\xb5\x6c\xa9\xde\x17\x0a\x69\xc1\x89\x3c\x7f\xb8\xbf\xa1\x65\x4f\x42\x65\x44\x01\x50\x17\x63\x64\x51\x98\x2a\x62\xf1\x2f\xd2\xa1\xde\xba", 139, { 0x7c, 0xea, 0xd6, 0xf2, 0x79, 0xc5, 0xbc, 0xa4, 0x89, 0x86, 0xfc, 0x29, 0x94, 0x1c, 0x8b, 0xee } },
|
||||
{ "\xac\x04\x20\xff\x0a\x4b\x0f\x21\xce\xd6\xf6\x2e\x8d\x87\x43\xd5\x5f\xc4\x67\x35\x45\x9c\x50\xd0\x38\x01\x80\x9e\xca\x33\xca\x3e\x7b\x3e\xa9\x48\x9b\x99\x3d\xbd\xd6\xf0\xe3\xa0\x61\xfc\x6f\x9e\xc0\x8d\x09\xe8\x31\xa9\xa1\x21\xb8\xcf\x10\x73\xc8\x54\xcd\xbc\x8b\xef\x48\xe6\xce\x50\xe6\x55\x8c\xea\x9a\x79\x16\xd2\x1c\x83\xdc\xbf\xc9\x34\xda\x31\x17\xd0\xa1\xaf\xb3\x32\x00\x29\x39\xf9\x50\x7b\x8f\xe0\x59\x12\xdf\x2c\xe4\xa9\x2f\x3e\xde\x2d\x9e\x48\x26\xbf\x3d\x1c\xf4\xd7\x87\x20\xe5\x86\x7f\x5e\xa7\xd4\x65\xb8\x3d\x47\x14\x38\xef\x85\xfb\x86\xd2\x11\xb5\x73", 140, { 0x2d, 0xe4, 0xcd, 0x76, 0x59, 0x59, 0x50, 0x08, 0xc3, 0xaf, 0xda, 0xd6, 0x68, 0x92, 0x96, 0xd3 } },
|
||||
{ "\xef\x31\x48\xb1\x13\xf0\xf7\xa5\x33\x40\xc4\x55\x79\x37\x86\x7c\xef\x7a\xa2\xbd\xc7\xb7\x69\xf4\x44\x4c\x0e\xa7\x49\x05\x42\x9b\x7c\x02\x6e\x83\x17\xb7\x8c\xd4\x4b\x0e\xa3\xb4\x50\xa7\xdd\x10\x0e\x3f\x46\xcc\x61\x2e\x23\x16\x0d\x0a\xed\xd4\x3e\x6a\xe9\x3b\xba\xc5\x65\x81\xa5\x78\x91\xaa\xf0\xe6\xf7\x7f\x60\xb9\x98\x9e\x36\x47\xa5\xaa\x80\x11\xd6\xa2\xfc\x65\x6b\x4f\xa4\x23\xbd\xd7\xdb\x9c\x80\x70\x32\x96\x98\x2e\xd7\x6c\x94\xfc\x9a\x52\xcb\xa9\x9d\xb7\x12\x1a\x98\xc3\x17\x9e\xc7\xff\x5d\x5f\x70\x14\xd4\xf3\x14\xac\x14\x12\x32\x75\x36\x62\xb2\x44\x4f\x6f\xf5", 141, { 0x5c, 0xf1, 0xaa, 0x0f, 0x1a, 0x4b, 0xef, 0x0b, 0x9d, 0x3e, 0xba, 0x20, 0x09, 0xb6, 0xbe, 0x59 } },
|
||||
{ "\x56\x8a\xb6\x76\xb1\xe1\xe0\x1d\xa9\x78\x0c\x20\x7e\x96\x45\x96\x23\x40\x13\x9a\x19\x74\x2d\x18\x7a\xff\x4c\x37\x12\xfb\x1a\x63\xa8\xe9\x49\xf6\x5a\x66\xc1\x82\x26\x8d\xf1\xbd\x85\xea\x47\x0a\x31\x16\xba\xa0\x08\xf4\x84\x59\x09\x86\xee\x19\x7b\x6d\x43\xd9\x2c\xfb\xe6\x4f\xd7\xf6\x80\x3c\x9f\xec\x51\x51\xb8\x2e\xa8\xbf\x25\x6a\x6e\x5a\x9b\xe9\xdc\x69\x85\x61\x4c\x0c\x21\x78\x2d\x4a\xc7\xd6\x11\xb7\x4a\xe5\xe1\xbe\x77\x28\x30\x91\xba\x35\xac\xaa\xe1\x50\xb1\xfc\xf8\xa6\xf7\xbb\x52\x23\x6c\xc5\xa9\xf0\x1d\xab\x5d\x8c\x4d\x60\xd8\x86\xa8\x7d\x13\xd4\x91\x2f\x31\xd4", 142, { 0xcb, 0x47, 0xda, 0xb2, 0x8e, 0x25, 0x2b, 0x75, 0xc9, 0x37, 0x45, 0x95, 0x31, 0x20, 0x1f, 0x6c } },
|
||||
{ "\x98\xbe\x49\xdc\x07\xba\x41\x7f\x9b\xc4\xd5\x5f\x50\xf6\xb7\xaa\x56\xf0\xd1\x33\x1f\x80\xa6\x2d\x9a\xed\xd6\x86\x7a\xe0\xc0\xde\xaf\xf0\x42\x22\xf6\xc9\x9c\xc9\x8c\xf8\x72\xab\xfe\x55\xf0\x79\x1c\x0c\x08\xdd\x0b\x4a\xd6\x2f\x7a\x82\x25\xd0\xed\x59\x0b\x27\x35\x34\xaf\x36\x00\x5b\x2b\xd8\x8c\xca\x8c\x99\x77\x94\xf6\x32\xb3\xf5\xe5\x9f\x95\xf2\x8e\xdf\x0c\xaf\x64\x48\xee\x4d\xb6\x84\x6e\x7d\x75\x2c\xaa\xa6\x14\xff\x61\xaf\x88\xbe\xc2\x69\x6f\xa8\x5f\x9c\x4d\x8d\x41\xad\xf1\x91\x15\xe8\xf6\x80\x83\x70\x65\xc8\x9f\xc0\x78\x17\x78\xdd\x79\x92\xce\x1a\xc9\xae\xe2\x87\xfd", 143, { 0x25, 0x55, 0x2f, 0xfb, 0x95, 0x22, 0x2a, 0xea, 0xac, 0x33, 0xb7, 0x28, 0x61, 0xa0, 0x65, 0x9b } },
|
||||
{ "\xaf\x65\xf8\x23\xbb\x92\xad\x22\x9a\x57\xa3\x3f\x0d\xae\x76\xbc\xc8\x0b\xf1\x9b\x0d\xee\x34\x80\xe5\x98\x81\xb4\xfe\xda\xa3\x46\x1c\x08\xfb\x4c\x3d\x0d\x28\x47\x4e\x98\x52\xa4\x83\x74\x13\x5f\x57\xf6\x03\xc2\x20\x8f\xdf\x4b\x4d\x82\x55\xac\x40\xaf\x6f\xec\xc2\x8d\x99\xab\x27\x36\x51\x82\xff\x9c\x6a\x89\x76\xd9\xfc\xf2\x49\xa5\xeb\xd2\x65\xe1\x13\x00\x1e\x50\x0d\x16\x08\x65\xa1\x95\x76\x36\xc8\x25\x8d\x90\x5c\xf9\x03\x25\x5e\x51\x7a\xe1\xe3\x19\x73\x5a\x9d\xaf\xf0\x66\x02\xc2\xab\xc6\x1b\x55\xec\xff\xeb\xe3\x0b\x49\x7a\x9d\x82\xa1\x7d\xcf\xae\xf9\xa3\x60\x22\x90\x7e\x78", 144, { 0x6d, 0xea, 0x3a, 0xd4, 0x25, 0x47, 0x84, 0x4e, 0x6a, 0x6c, 0x75, 0xcd, 0x94, 0xd4, 0x93, 0xef } },
|
||||
{ "\xa8\x5c\x0c\x3c\xd5\xa2\xe2\xb5\x48\xa8\xf4\xce\x7f\x83\x03\x7c\x55\x0a\xa3\xf8\x1c\xeb\xe8\x28\x53\xdb\xad\x1c\x04\xe9\x80\xb3\xbd\xec\x2d\x5e\x28\x1b\xe6\xfc\x4a\xbb\x0c\xe5\x54\xf3\x9c\x02\x29\xbb\x39\x19\x6d\xf3\xd1\x27\x46\x90\xef\xe6\xb3\xf1\x9d\x6e\x85\x50\xf4\xf8\xfd\x53\x42\xbd\x04\xc2\xd6\xfd\x01\x54\x6a\x1b\x5b\xa2\x2e\xe5\x8b\x3d\x6d\xf2\xdc\xdb\xde\x24\xc2\xac\x89\x4e\xd4\xcb\x54\xef\x68\xd0\x2a\x1b\xca\x82\xc7\x7a\x18\xa9\x22\x6a\xbd\x02\x76\x40\x88\x4c\xef\xac\x68\x80\xee\x3a\xc6\x1d\xf9\xf5\x7f\xa1\x42\x26\x7d\x13\xd2\x3a\xf1\xbd\x52\xc1\x2f\xf8\x76\x93\x25", 145, { 0xdb, 0x35, 0x6a, 0x9a, 0x9f, 0x39, 0xbc, 0x4e, 0xdc, 0xf9, 0x16, 0x44, 0xc7, 0xfb, 0x4d, 0xb9 } },
|
||||
{ "\x1f\x06\x0d\x79\xa6\x8b\x79\x3f\x43\x92\x8c\x54\x4a\x9f\x08\x5a\x16\xb2\x82\x50\xa3\x6f\x3e\xcc\x39\xec\x36\xd8\x43\x1c\x39\x67\x3e\xd2\x30\x72\xcd\x75\x7d\xb4\xe9\x3f\x7c\xfe\x35\x31\x2b\x37\x6f\x97\xe6\xf4\x03\x33\x4b\xb0\xba\x09\x3c\xa8\x8f\xc6\x02\x56\xa2\xce\x8f\x87\x46\xe1\xdc\x1b\x35\x69\x71\x59\xe3\x62\x03\xec\xef\xe6\x37\x7e\xb6\x54\x85\xf0\x02\x1c\x37\x33\xe0\x2a\x91\xc6\x8f\xed\x0b\xcc\x94\x03\xba\xc9\xeb\x83\xcd\xf9\x58\xe6\x32\x4d\xdb\x92\x58\x03\x41\x05\x10\xe0\xd7\x9b\x8d\x0d\x3a\xfb\x8a\x8c\x4a\x24\x8a\x55\x3d\x10\x3b\x11\xcf\x02\xf4\x72\x97\x71\x5d\x2d\x75\x91", 146, { 0x31, 0x6e, 0xe6, 0x46, 0x65, 0xc8, 0x63, 0x25, 0x2b, 0x8f, 0x01, 0xbd, 0x64, 0x08, 0x2c, 0x6e } },
|
||||
{ "\x2e\x95\x28\x7a\x10\xd5\xfc\xf7\x9f\xca\xa0\xee\x91\x7b\x16\x67\xf0\x36\xc3\x3a\x83\x48\xa6\x59\x4b\x58\xa5\xb8\x29\x60\x03\xd5\x9d\x49\xee\xe7\xa9\x23\x35\xa7\xd3\xfe\x17\xb5\x4a\x67\x37\xa9\x20\x82\xab\xb7\xb6\xc1\x33\xfe\x35\x3e\x86\x6d\x38\xbb\xc8\x52\x87\x33\x19\x81\xff\x1c\x47\x1d\x8d\x3c\xa3\x06\x59\x25\xf1\xdf\xff\x4f\x79\xba\xf8\xd0\x3a\x63\x17\xba\x3e\x46\x30\x11\x09\xfd\xd3\x67\x2b\x7a\x36\x16\xf5\xce\x30\x1a\x48\x93\x62\x89\x89\xfc\x70\xaf\xb0\x77\x6d\xca\x80\xfc\x55\x5f\xd1\xf6\xb3\x37\x09\xca\x63\xf9\xa9\x08\x72\x65\x03\x2d\x21\x2a\x0a\x12\x09\x65\x41\xf5\x58\xb8\xd6", 147, { 0xea, 0x55, 0x9c, 0xa7, 0x61, 0xf9, 0x9e, 0xc7, 0x2a, 0x9a, 0x54, 0xba, 0xa7, 0x5b, 0x37, 0xfd } },
|
||||
{ "\x23\x39\x02\xc8\x3e\x52\xc0\x42\x30\x67\x00\x0c\xad\x1c\xfd\x17\x5e\xd7\x5c\x36\xaf\xc4\x02\xec\x36\xf2\x90\x60\xbe\x9a\x7c\x6d\xf0\x80\xcd\xd6\x9d\x73\x72\x97\xab\xee\x40\x56\x99\xe1\x87\xf8\xb0\x89\x4f\x50\xc8\x7b\x34\xf3\xb4\xc1\xdb\x27\x4b\x1b\x10\xfa\x14\x67\x7e\x6e\x8d\x1b\x0a\xd2\x18\xee\xcc\x2c\x83\x96\xaa\xd2\x32\xad\x93\x17\xeb\xad\x55\x23\x3e\x1a\x1c\xdc\x8f\xbf\x88\x00\xc1\x10\x69\x55\x81\xae\x1a\xf7\x2c\x0a\x77\xd0\x5e\x21\x7c\x27\x18\x65\x7b\x4f\x8d\xbc\xf9\x7f\x89\xa1\x26\xc2\x7f\x69\xf8\x05\x2d\xa0\xe3\x4e\xee\x92\x37\x0c\x9c\xe5\x15\x89\x1f\x63\x0f\x7b\x97\xd6\x5c\xba", 148, { 0x0f, 0x9d, 0xb8, 0x04, 0x8a, 0x9f, 0x75, 0x74, 0x4a, 0xcd, 0xdd, 0x47, 0xcf, 0x76, 0x81, 0xfa } },
|
||||
{ "\x22\x0c\xb4\x0d\x4a\xfa\xce\x1d\x0e\xfd\x74\x8b\x8b\x3b\x3f\x1d\x47\x28\xf5\x13\x1b\x25\x7b\x98\xba\x42\x78\x54\xe2\x24\x89\x1e\x1d\x02\x1a\xcf\x34\xc9\xe7\x32\x31\x60\x10\x17\x10\x06\xd2\x87\x02\xd7\xe8\x11\x5d\x6d\x7d\x43\x23\xa2\xcc\x35\x2c\x74\x56\x3f\xf3\x02\xbf\xca\xfb\xb3\x46\x44\xdc\x76\xdf\x2d\xee\x23\xef\x4e\x90\x00\xa3\x0a\x16\x60\xee\xcd\x4d\x67\x1d\xa1\xab\xe8\x18\xdf\x18\x6f\x37\x02\x53\x5a\xbe\x97\x03\x22\xf7\x51\x5b\xb7\xea\x39\x68\x0a\xbc\x02\xfa\xa4\xa2\x7a\x2c\x73\x80\x1d\x92\xa6\x22\xc4\xff\xad\x15\x7a\xf0\x63\x23\x6f\x99\x48\x6a\x06\x89\xe7\x18\x09\xfc\x56\xc6\xfc\xbd", 149, { 0x76, 0x46, 0xa2, 0x5b, 0x70, 0xce, 0xd9, 0x5e, 0xe2, 0x86, 0xf5, 0xb1, 0xc2, 0x39, 0xd9, 0x4d } },
|
||||
{ "\xdc\x6d\x8f\xb6\xad\x09\x2d\x16\xd0\xc8\xb1\x1d\x21\xef\x38\x87\x73\x4a\x11\x92\xcd\x4e\xd1\xae\xd5\xcd\x84\xc1\x4b\x54\xfd\x14\xac\x24\x4f\xdd\xf7\xcc\x54\x69\x8b\x5f\x6a\xe6\x2f\x57\x3e\xca\x2c\x06\xc0\xe4\x95\xb5\x36\xfd\xa7\x5b\x6d\x2a\x4b\xfb\x09\xb1\xb8\x9b\xfe\x96\x35\xdc\x17\xc1\xfc\x3b\xb4\xcd\x3a\xe3\x91\x6f\x33\x2c\xc0\x81\x83\xb4\xb9\xaa\x7f\x18\x88\xac\xba\x50\x24\x4a\xa4\xa5\xe0\xd4\x4c\x4f\xfb\x50\x46\xaf\x52\x47\xa7\x25\x34\x29\x2d\x8f\x56\x5e\x7c\x5f\xdd\xea\x83\x58\x99\xbb\xfd\xe5\x52\x92\x14\x16\x3a\x8c\x1f\x37\x81\x4c\x8c\x0f\x08\xc7\xd9\xb2\x2d\xac\xbc\x03\xc5\x6e\x63\xca", 150, { 0x63, 0xf7, 0x3c, 0x3f, 0x15, 0xc6, 0x1c, 0x37, 0x20, 0x84, 0x1a, 0x45, 0x07, 0x6f, 0x04, 0x5b } },
|
||||
{ "\x28\xef\xd6\x6e\x65\xca\x78\x4f\x96\x3d\xac\xc2\x4f\xb2\x93\xaa\x30\xe8\xf4\xaf\x9a\xc3\x35\x1e\x7e\xac\x86\x5d\x51\xa6\x1d\x09\x1c\xef\x9b\xae\xaf\x4f\x8e\x22\xf5\x00\x10\x7e\x63\x39\x8c\xba\x8b\x59\xa0\xe4\xcd\xad\x1e\xfd\x2c\xde\x2d\x70\x3e\xfa\x8d\x30\x3d\x1d\xf8\x6d\x3c\xbb\xa3\xf2\x73\x8d\xe4\x1e\xbb\x16\xed\x7d\x15\xd1\xb6\x02\x64\xf9\xf9\xe3\x3b\xf4\x57\x11\xd1\x5d\x98\x53\x11\xad\x10\xfe\xce\x85\x1c\x53\x14\x9a\xcc\x75\x99\x3d\x9b\x05\x53\x86\x59\x5c\x23\x1c\x29\x64\xaf\xa4\xa6\x13\x4d\xc4\x21\x85\x1a\xd3\x06\xb6\x2b\x1f\x5d\xd9\xdb\xd9\x6c\x57\x44\xa1\x79\x67\xc9\xaa\xac\x46\xcf\x8a\x13", 151, { 0x62, 0xc8, 0xb6, 0x40, 0xbc, 0xc6, 0xa0, 0x0a, 0xa7, 0xd0, 0x3e, 0x39, 0xf2, 0xb0, 0xea, 0x37 } },
|
||||
{ "\x14\x8b\xa1\xc0\x4b\xf6\x23\x0d\xdc\xde\xc3\x00\xe7\x16\xfd\xc9\x17\xce\x00\x68\x99\xfd\x37\x6b\xb7\xfa\x73\xd5\x15\x2a\xb7\x1b\x86\xd4\x9f\x48\x8c\x11\x6d\x40\x6a\xdf\xb1\x21\xe8\x54\x95\xc5\xa3\xef\xc2\x64\x0e\x0a\xf3\x57\x09\x6c\x14\xf7\x1c\xfb\x16\xa4\x50\x8e\x52\xe1\xaa\xe0\x97\x9d\x45\xa1\xd2\x8d\x0b\xa7\x59\xb4\x0f\x43\xd4\x04\x8a\xae\xc8\x1e\x71\xa1\xc1\x36\xaf\x03\x1c\x12\x04\xbd\x6e\x31\x79\xaa\x95\x08\x7f\xaa\x59\x67\xa4\xd6\xbd\xfb\xf1\xcd\xe8\xec\xe2\x2d\xab\xa7\x02\x1e\xaf\xb6\x23\x08\x3c\xca\x37\x64\xa8\xdb\xcf\xb0\x5a\x66\x2d\x7c\x7a\xd5\x07\xa2\x37\xfd\xdb\x93\xb4\xc1\xe9\xcb\x90\xd3", 152, { 0x37, 0x36, 0xc5, 0xe7, 0x36, 0x49, 0xee, 0x57, 0x1d, 0x40, 0xa0, 0x4c, 0x9e, 0xde, 0x94, 0x3a } },
|
||||
{ "\xd2\x66\x10\x9b\xcb\xcd\xeb\x30\x7e\x89\xb2\x83\x7d\x38\xdb\x9b\x63\x9c\x69\xfa\x89\xd0\x39\x1f\x62\x97\xea\x25\x74\xcd\x6a\x89\xf3\xff\x1a\x09\xfc\x16\x9d\xa7\x6b\x2e\x42\xcc\x59\x85\x0b\x8a\x35\x8e\x5a\xfa\x7e\x25\x37\xc4\x1a\xde\x40\xbd\x56\x76\x2e\xab\x7b\x6b\xff\x23\x09\xa7\xc6\x93\x93\x57\x0b\x5c\x36\xdb\xe0\x17\xb7\xd6\x81\xf9\x38\x64\xa7\x51\x97\x6b\x69\x2e\x64\x0b\xcf\x1d\x7c\x2f\xf5\x0f\x46\x45\xd9\x5a\x8a\x0a\xc1\xd6\xe9\x7e\x4b\x28\xfd\xf7\x13\x1b\x0e\x52\xfa\x2a\x6d\x44\x19\x1a\x71\xce\x43\xc4\x0b\xcf\x2f\xf0\x08\xb3\x4a\x5d\xe4\x49\x18\xde\x45\xb3\x43\x9e\x1b\x77\x42\x84\x51\xb2\xa7\xb1\x30", 153, { 0x1b, 0xaf, 0xb0, 0x43, 0x8c, 0x29, 0x50, 0xc6, 0x5f, 0x88, 0x3c, 0x47, 0xe5, 0x59, 0x28, 0xf0 } },
|
||||
{ "\x6b\x05\x26\x51\x05\x7b\x83\x3d\xcf\xe2\xeb\xa3\xb6\x8f\x03\x34\x1a\xc5\x18\x1f\xbd\xba\x60\x24\xd8\x44\x58\x57\x48\x20\x4d\x74\xe5\xdf\xf7\xd9\xf3\x6e\x3f\x24\xb2\x40\x22\x69\x10\x1a\xad\x10\x7f\x7a\x28\x4a\xe0\xa5\x4f\x2e\x9e\x4c\xbb\x74\xd8\xda\x60\xcc\xb6\x5d\x2f\xdc\xdd\x0e\xdc\xd5\xfd\x7f\xba\xb0\x87\x60\xc2\x0b\x7c\xed\xb2\x9a\x61\xf8\x52\x4b\x4f\x8e\xd1\xfa\x27\x49\x4e\xce\xe2\x32\x74\x2e\x06\x50\x3d\x64\x34\xd1\xd7\xcc\xde\xd4\xa3\xb8\x17\xd1\x5a\xe4\x83\xa6\x4a\x90\x6d\x3f\xbf\x40\xf7\xe0\x7d\x0c\x6c\x12\x68\xa4\xb2\x28\x46\xe4\xdb\x6c\x9d\x10\xda\xeb\xb7\xac\x52\xda\xc4\xfb\x8a\xa4\x1e\x12\x7d\x91", 154, { 0xee, 0xd2, 0x3f, 0xfe, 0x5e, 0xf6, 0x9b, 0x93, 0x25, 0x36, 0x5e, 0xa2, 0x89, 0x96, 0x1b, 0xe0 } },
|
||||
{ "\xa7\x97\x0f\x14\x4e\x1b\x59\xb1\xb1\x12\x25\x89\xdd\x6b\x75\x83\x30\xd0\x3e\x19\x5f\x7c\x32\xbc\x94\xb3\xbb\xe5\xb0\xe3\x03\xba\xae\x55\x30\x58\x27\x90\xad\xc3\xf2\x4a\xa4\x68\xe3\x0c\x88\x4a\xb4\x61\xce\xd1\x02\xba\xbb\x2c\x6e\xe1\x58\x5e\xe4\x18\x83\xec\xf8\xce\x20\x22\x6c\xfd\x6c\xfd\xce\x23\x72\xb8\x3e\xda\x96\xf6\x4e\x16\x4e\x88\x02\xfb\xf1\xdc\xf6\x59\xa7\x03\x9f\xc5\x80\x5d\xa9\x55\xa2\xe3\x80\xf7\x9a\x11\xeb\x6e\xd3\x6e\xd2\xea\x24\xb9\x20\x44\x83\xb2\xc3\xd3\xd7\x82\xd0\xed\xec\xc8\xc4\xfe\x80\x40\xe6\x3e\x7a\x12\xc8\x12\x3a\xb5\xec\x01\x0b\x7e\x82\x51\xb5\xc9\x4f\x3e\x30\xc2\xaa\xd6\x72\xd1\xa1\x74\x69", 155, { 0x71, 0x8e, 0xdb, 0xc9, 0x57, 0x5f, 0x0d, 0x0c, 0xec, 0xbe, 0xde, 0xdc, 0xa1, 0x2e, 0x69, 0xb9 } },
|
||||
{ "\xa0\x38\xd6\x05\xca\xd1\xdd\x6c\x21\xa7\xe2\x51\x9c\x74\xb0\x5f\xdb\x33\x21\xcf\x59\x00\x58\x19\x2d\x1b\x98\xc6\x7d\x0b\xbf\x64\x7f\xdf\x63\x94\x2d\x90\x88\x3d\x85\x82\xfa\xe3\x7a\x29\x4d\x12\x7a\xc8\x6f\xf4\x9d\x55\xe7\x02\x67\x79\xac\xd7\x3a\xb3\xa4\x20\x5b\x9c\xb8\xb0\x9f\x45\x90\xb0\xb1\xbc\xf0\xf4\x03\xae\xae\x68\x4f\x26\x4f\xa9\xc9\x74\x3e\xb0\xe3\x28\xa8\xa9\xbc\x3d\xf7\xe2\x26\x54\xe8\xdf\x52\x15\x4b\x8a\x1b\xba\x57\x87\xeb\xa7\xa7\xa6\x4e\x31\xd5\x72\x11\x7f\xb1\xe6\x16\x8e\x1f\x3f\xb7\x4e\x8a\xed\xd5\xea\x09\xa3\x7c\x25\x0c\x8d\x34\xdf\xc2\xa1\xe7\xb8\x0b\x0f\x6a\xcb\x15\xd2\xaa\x9b\x95\x68\x74\x0c\xa4\x9e", 156, { 0x28, 0x35, 0xde, 0xdd, 0xce, 0x7d, 0xf6, 0x36, 0x34, 0x58, 0x67, 0x85, 0xef, 0xd3, 0xd0, 0x4b } },
|
||||
{ "\xe0\x88\x34\x85\x5b\x42\x2d\x81\x50\x97\x28\x7f\x73\x90\xc7\x46\xaa\x84\xaf\xe7\x97\xdb\x23\x4f\xc6\xed\x3e\xfb\x70\x08\xcc\xca\xea\x91\xc6\xee\xad\x41\x69\xfc\x02\x91\xf2\x24\x4a\x31\xf8\x7a\xe7\xb1\x65\x72\xcb\x43\x12\x6b\x9b\x97\xff\x62\x7f\xe6\x2c\xc7\x89\x0b\x16\x6c\xbf\xcb\xd1\x9a\xc7\x35\xbe\x3e\x2e\x25\xea\x41\x54\xe2\x04\xf5\xf8\xe7\xf8\xab\x5c\xbf\x2c\x61\x15\x09\x56\x98\x71\x9b\xf8\x44\x84\xc3\x79\xdd\xd1\xa9\xe1\x93\x92\xd0\x31\x9e\xa5\xbb\x5d\xb3\x13\xac\xe7\x92\x3d\x88\x19\xbc\xa5\xd6\xdf\x43\x56\xe6\x3f\xb9\xf1\x0e\x75\x4a\x56\x10\xaf\xe6\xeb\x97\x61\x96\x8c\xe0\x46\xf0\x0f\x76\xf5\xa6\x72\x15\x1c\x38\xa4", 157, { 0x11, 0xb8, 0xb0, 0x6e, 0xcf, 0xbf, 0xc1, 0x00, 0x35, 0x81, 0x35, 0x3d, 0x73, 0x40, 0x71, 0xab } },
|
||||
{ "\xb0\x5b\xca\xec\x8e\xbf\x10\xfa\x8f\xd9\x65\x89\x8d\x7a\xfb\xad\xde\x0e\x2d\xbe\xf5\x93\xf1\xe1\x28\x34\x69\x30\x8c\x86\x98\x85\xfc\x5e\x31\xe8\x39\x4c\x8b\x92\x2b\xb9\xb2\x9e\x46\x99\x97\x4b\x08\xcc\x67\xf0\x9e\x17\xf9\x7d\xa6\xb9\x60\xa9\x10\xad\xa0\xbd\x1e\x7c\x7e\xfd\x8a\xbb\x70\xae\xc6\x28\xb4\xc9\x5e\x5d\x7d\x3a\x7a\x2f\x47\xd5\x7f\xa6\x4c\xd6\xd6\x98\x0f\x13\xc4\xe4\x15\xc0\x78\x48\xb3\xdf\x24\xe0\x03\x42\x43\x3c\xf0\x3e\xf8\x1c\x71\xee\x97\xca\xd3\x21\x3d\x14\x2e\xe1\x99\xe5\xf9\xa1\xce\x80\xba\x02\x71\x58\xd6\x42\xad\x8e\x86\x41\x86\x07\xea\x31\x3a\x29\x37\xda\xc3\x33\x0d\x88\x7a\x37\xe4\x92\xd5\xb4\xa4\x87\x51\xd4", 158, { 0x88, 0xe5, 0x0c, 0x22, 0xb2, 0x63, 0x28, 0xbd, 0x76, 0x62, 0x67, 0x97, 0x24, 0xc6, 0x2a, 0x19 } },
|
||||
{ "\x53\xf6\x6b\x3e\xe8\xda\xc8\x99\x3f\xa0\x74\x9f\x26\xd7\x47\xd9\x94\x73\x64\xfc\xf9\xbe\xdb\xe0\xb1\xdc\x6e\x19\x92\xf9\x71\x34\xa4\x11\xca\x90\xf0\x5b\x18\xd6\x71\x53\xf0\x16\x28\x63\x43\x7f\x4b\x2d\xdb\xbb\x9d\x77\x04\xe5\xd9\xb4\x47\x28\x48\x2b\x52\xf5\x72\xc6\xf3\xe0\xf1\x79\x43\x18\x60\x4d\xe0\x81\x73\x08\x52\x70\x21\x7b\x8f\x02\xfb\x68\x99\x19\xa0\x0d\x45\xf4\x49\x52\x18\x6a\x80\x8a\x4a\xc3\xee\xe9\xec\x33\x51\x83\x25\xf4\x8c\xfd\x98\xff\xd8\xd2\xe1\x66\x19\x44\x3f\x51\x4b\xdd\x4c\x93\x1b\xa0\xe6\xe8\x92\xd1\x32\xcd\xec\x5e\xb7\xfc\x87\xe9\xa5\x83\xf7\x73\x39\x80\x36\xa6\x38\x7b\xf9\xbe\x98\x60\x1d\x16\x3e\x17\x40\x4b\xe2", 159, { 0x5a, 0xc3, 0xb5, 0xfd, 0x87, 0xbf, 0x56, 0xbf, 0x6f, 0x69, 0xe7, 0xac, 0xf6, 0xb7, 0x50, 0x26 } },
|
||||
{ "\xc2\x6d\x0f\x10\x92\xef\x8c\x47\x47\x46\x72\x44\x42\x38\x9f\x59\x48\xfe\x6a\xf6\xd5\x9f\x8c\x49\x1a\x5b\xac\x02\x96\x3d\x86\x2f\x4c\xd3\xb7\x47\xa6\xfa\x27\x42\xe6\xd3\x13\xe5\x45\xd2\xb6\x1c\xaa\xf5\x93\x7f\x08\x11\x62\xf7\x54\x47\x94\x7a\x22\x96\x85\xf1\xdb\x8b\x3e\x3b\x9d\x13\xe3\x4b\xaf\x71\xbf\x6d\x9f\x4a\xea\xa6\xfb\xdd\x95\x38\xa8\x51\xf2\x44\xe2\x27\xc2\x8a\xd0\xcf\x7c\x4c\xc3\x56\x17\x52\x0b\x3c\x75\x06\x76\x64\x6c\xbf\x66\x24\x71\x1b\x8e\x7c\xe3\x85\x49\x64\xf2\xd6\x96\x3e\x2a\x17\xb4\x6b\xa0\x65\x56\xfa\xb7\xed\x84\x7a\x8f\x17\x0e\xf0\x0b\xc0\xad\xe4\x7e\x9f\xb7\x96\xf2\xc9\x7e\x4e\x14\x4f\x47\xd1\xbf\x05\xe2\xef\x23\x5e", 160, { 0x59, 0x21, 0x8f, 0x6b, 0x10, 0x2a, 0x92, 0x6c, 0x6c, 0xbd, 0x52, 0x03, 0x5c, 0x47, 0xa6, 0xc0 } },
|
||||
{ "\xeb\x39\x92\x73\x9b\xd1\xe7\x22\x4b\x5a\x93\x53\x87\x0e\x45\x56\xcb\xed\x35\x68\xdd\x13\x0e\x55\xc6\x23\x76\x37\x6e\xdf\x3b\x5c\xd3\xda\x1b\x45\xe6\x44\x30\xcb\x02\xe4\xf6\x5d\x09\x25\xfb\x64\x1d\x47\x22\xc7\xf8\xb6\x93\x8a\xe9\x78\x42\x91\x6c\xbf\x1b\x83\x64\x9e\xc7\xca\xf7\xd9\x1e\xb6\x06\xd5\x29\xc1\x48\xae\xd2\xed\x02\x67\x2b\x4a\x65\x3c\x57\x94\x83\x14\x19\xf8\xef\x12\xf7\xf7\xf1\x4b\x0a\x64\x63\x92\x65\x87\x2c\x6e\x20\x64\x56\x2d\x00\x15\xcd\x12\xc4\x54\xb6\xa9\x0e\x15\x69\x3c\xec\x50\x0d\x5e\x03\xdc\xcf\xa4\x57\x77\xbf\x74\xb9\xe2\x47\xf5\xce\x29\x48\x26\xb7\x01\xd2\x0a\x62\x49\x80\x01\x6d\xb3\x6e\x33\xb2\x7c\xd9\x25\x73\x57\x51", 161, { 0xfd, 0x5f, 0x53, 0x55, 0x7c, 0xa6, 0xcc, 0x9a, 0x93, 0x96, 0x50, 0x2d, 0xe3, 0xbc, 0xde, 0x90 } },
|
||||
{ "\x6d\x23\x68\x9d\x82\xcf\x6b\x2b\xad\x27\xf5\x32\x1c\x2d\xd3\x66\x15\x79\x8f\x57\x48\x26\x11\x67\x3d\x5d\x61\x66\xec\x7c\x8a\xcc\x6b\xe2\x9a\x92\xc2\x5a\xc7\xad\xda\x21\xac\x28\x94\x95\xb0\xdc\xf7\x7d\x87\xcf\x81\xef\xd2\x27\x9e\xe2\xe2\xc9\x36\x50\x9a\x93\x61\x07\x72\x32\x36\x0d\x98\xa0\xc1\xae\x31\x3d\x12\x24\xbd\x89\x72\xe1\x98\x7c\xb1\x7b\x9c\x82\x9b\x34\xe4\x16\x89\x25\xac\xfa\x13\x07\x54\x10\xe3\x9e\x83\xd9\xa5\xc3\x68\x87\x1a\x0c\x1c\xc0\x4c\x1a\x23\xf2\xdc\x7e\x12\x4d\x77\x48\x4a\x62\x67\x2e\xe2\x56\x45\x56\xa3\xc2\xcd\xc0\x2c\x2b\xca\x53\x36\x19\x30\x83\xf2\xd6\x48\x9b\x8f\xc4\x06\xac\xd8\x5b\x76\x12\xf9\xbf\x55\x9f\x61\xfa\xbc\x67", 162, { 0xb5, 0xc0, 0xce, 0xe9, 0x9a, 0x70, 0x42, 0x5b, 0xc4, 0x6d, 0xf4, 0x0e, 0x8c, 0x2a, 0xf1, 0x63 } },
|
||||
{ "\xc3\xdb\xf7\x28\x38\x6a\x74\x53\x7f\x06\xd7\xbb\x64\x1d\x2a\xd9\x3e\x88\x32\xba\x91\x81\xdd\x86\xd4\x42\xd7\xad\x4e\x3b\x3b\xaf\x1a\xee\x67\x88\x49\x6b\xe8\xb7\x26\x63\x94\xea\x94\xec\xb7\x48\x94\xd0\x65\x5a\xe3\x92\xef\x97\xc0\xfe\x70\x8a\xcb\x6c\x87\xa2\x09\x91\x1f\x96\x04\x01\x69\x73\x10\x45\xeb\x43\xa8\x94\xb2\x5b\xf6\x32\xa3\x42\x71\x62\xf0\x39\xa1\x09\xa6\x6c\xfe\xe1\x62\xb3\xf6\x56\x24\x05\x0e\x01\x3b\x7a\x20\xbe\x60\xfa\xc2\x6c\xdf\x87\xc7\x40\xf0\x25\xdf\xc6\x24\x62\x5a\x76\xfb\x85\x09\xef\x92\x57\x45\xd2\x79\x88\x09\x3e\xa3\xc0\x3a\xe3\x77\x44\x08\xc5\x03\x40\x6c\x8f\x50\xb7\xd1\x91\xd0\x04\xcf\x58\xf4\x0b\x12\xe9\xda\x02\x59\x99\x24", 163, { 0x62, 0xcf, 0x51, 0xd0, 0xdd, 0x5e, 0xaa, 0x1d, 0x2e, 0xbc, 0x45, 0xe8, 0xbe, 0x1e, 0x27, 0xc5 } },
|
||||
{ "\xd6\x9b\x8c\xe4\x3b\x44\xc8\xb3\x53\x9c\xf5\xe1\xfa\x49\xb3\xc6\xac\xeb\x98\x37\x13\xe5\xc5\x14\x31\x3c\x24\xff\x27\x97\x40\x27\xa0\x66\xc0\x42\xdd\x20\x81\x99\x5d\xa4\x4f\x3d\x28\xc1\x40\x57\xb8\xd1\xae\x9d\x85\x80\xcf\xe1\x2c\xaa\xf3\xc3\x3b\x62\x59\x87\x9b\x10\xad\x01\x9a\xb2\x22\xad\x95\x43\x28\xdb\x3e\x38\xca\x07\x90\x27\xa7\x47\x4c\x83\x8b\xdd\x2e\x82\xaa\xec\xb1\x1f\x78\x48\x7c\x3b\x28\x66\x68\xdf\xbf\x72\x2e\x9c\xd3\x80\xb2\x13\xe5\xda\xe6\x91\x58\x78\x5c\xd2\x0e\x8d\x6d\xe7\x9e\x3e\xff\x32\x33\x6d\xf5\x8d\x04\xb4\x39\x8a\x6b\x6e\x5f\xd5\xa5\xef\xf6\xb6\x25\xd3\x70\xb3\x95\x74\xab\x52\x6a\x75\x1b\xfc\x22\x7b\x96\xfd\x1d\xfc\xbc\xa8\x15\x2f", 164, { 0xd4, 0x4e, 0xcd, 0x21, 0xa5, 0x2f, 0xe7, 0xf0, 0xee, 0x4c, 0x55, 0xcd, 0x8a, 0xa7, 0xdc, 0x4c } },
|
||||
{ "\x01\x98\x3c\x23\x59\x11\xf1\xec\x7f\x84\x1e\xf7\xe1\x31\x30\x7f\x2b\xe7\xb4\x18\x6e\xe7\x8b\x69\xed\xe7\xc9\xf7\x84\x32\x30\x1c\xb6\xec\x44\x16\x51\x74\x0b\x3b\xc0\xe2\x63\x4b\xed\xaf\xff\xde\xd0\x74\x00\xfc\x99\xcb\x2c\xcb\x76\x52\xcd\x63\x01\xce\x28\xbe\x4a\x6b\x99\xcb\x7c\x21\x48\xa1\x2e\x33\x8a\xd0\x48\xd2\xd6\xd4\x90\xde\x61\xa3\xd0\xcc\x59\x65\xa6\xa2\xbb\x44\xe8\x1f\xd2\x59\xb1\xf9\x4d\xc5\x0d\x3e\xfb\xe1\x3d\xdc\x25\x8d\xa7\x3c\x88\xa5\x5d\x08\xed\x92\x48\x0e\x67\xfc\xf0\x3c\x29\x9d\xeb\xcb\x01\x31\xe1\x79\x75\x8a\x37\xee\x78\xbf\x60\x40\xc9\x84\xbc\x92\xe9\x95\x2b\xd7\xb7\x4d\x33\xb4\xa9\x53\xca\x84\xa9\x73\xc0\x75\x8a\x8b\xcb\xcf\x25\x9c\x31", 165, { 0x92, 0x9b, 0xb5, 0xb5, 0x6a, 0x86, 0x10, 0xb0, 0xb7, 0xe5, 0x9a, 0xc2, 0x89, 0x26, 0x9a, 0x48 } },
|
||||
{ "\x55\x14\x00\x0c\xc4\x0a\xbb\x3d\x78\xce\xe9\xf0\x2e\xd2\x57\xc7\xe4\x74\x2e\xa5\xdd\xd0\xca\x1a\xc1\x40\xaa\x66\xe0\x71\x7f\x2c\x97\x23\x67\xb4\xcb\x7c\x33\xdd\x93\x0a\xe4\x9d\xf2\x54\x35\x36\xc1\x1b\x52\xf8\xac\x32\xa6\xad\x53\xf7\xd2\xa4\x90\x6d\xb9\x5d\xd8\xf7\xb8\xce\xba\xb3\xf3\x50\x85\x71\xcb\x29\x07\x4f\x6b\xb6\x6f\xf3\x82\x35\x54\x63\x0b\x2d\xce\x84\x47\x7a\xc2\x2d\xcd\xf9\x3c\xe7\xb7\xcc\xf5\x43\xfe\x4a\xf3\xd8\xe0\x86\x50\xd8\x7d\x7a\x12\x4e\x82\xd1\x39\xf7\xfc\x4e\xd8\xba\x4e\xdc\x5b\xc4\x3e\x32\xe7\x44\x29\x22\xdf\xc0\x57\x7f\x82\x13\x69\xa9\xb1\x03\xef\xb7\xce\x83\x16\x3f\xc1\x82\x7e\xc4\x14\x6d\x2a\xbd\x3e\x48\x91\x3e\xfd\x64\xd1\x46\xdc\xbe", 166, { 0x34, 0x76, 0xd8, 0x8f, 0x60, 0x2b, 0x1e, 0x31, 0x24, 0x84, 0xf7, 0xc0, 0x6c, 0xe6, 0x88, 0x4d } },
|
||||
{ "\x03\xa4\xd4\xf4\xa9\x86\x0f\xe5\x44\x9f\xc7\xe3\x03\xf4\x4d\x97\x95\x44\x26\x72\x1f\x12\x50\xcc\x4a\x50\xa2\x9b\x73\xa9\x51\xd0\x06\x6b\x8f\x51\xe5\x10\x4d\x8f\x01\x68\x22\xc5\x0c\x64\x44\xcc\x45\x81\xb2\x9c\x72\xce\x74\x63\xec\x9c\xfa\x3b\xd4\xc2\xa2\x8c\x64\x8a\x55\xfe\x60\x3c\x51\x18\xaa\x44\x01\x7a\xf5\x02\x07\xb3\x92\x2f\x5c\xc0\x66\xe7\x8f\x22\xfd\x57\x29\x9b\xb7\x03\x32\x84\x20\xb4\xcc\xce\x5e\xfd\xfc\x93\xc3\x69\x89\x58\x82\x43\xfd\xe2\x7f\x02\xc8\xb1\x3f\x4e\x84\x1d\xff\xb3\x54\x0c\xe0\xe1\x65\x4e\x3f\x9d\x96\x95\x23\x48\x34\x14\xd0\x0a\xde\xb2\x78\x9b\x88\xeb\x11\xae\x9a\x44\x42\xfa\x38\x69\x77\xe6\x9d\xe4\x13\xd0\xa0\x7c\xc5\xfa\x59\x28\xf4\x11\xdd", 167, { 0x8e, 0x0a, 0xc8, 0xfc, 0x3e, 0xdd, 0xb3, 0xf5, 0x3b, 0x8d, 0x4d, 0xfd, 0xac, 0xbe, 0x7e, 0x2e } },
|
||||
{ "\xae\x54\x5b\x24\xdd\x9a\x7d\x0c\x63\x4c\xe7\x77\x4c\xb1\xdd\x8f\x18\xe8\x22\x29\x77\x15\x43\x47\xa3\xb6\x7d\xb8\x5a\x14\x4c\xda\x77\xd4\x91\x80\x2c\xad\x5e\xee\xde\x34\x62\x01\x9d\xd2\xec\x6c\x3f\xd8\x9d\x1c\x18\xa9\xaf\xbd\x57\x15\xdc\x56\x00\xc7\xec\x10\x81\xd4\xde\x14\xf4\x73\xb2\x91\xf0\xcc\xd1\xdd\x0c\xe9\x1a\xb3\xf1\xc9\x8a\x9b\x1b\x93\x87\x67\x2c\xe8\xc9\xd9\xed\x51\xe6\x62\xe2\xd8\x78\x05\x88\xb2\xec\x5a\x2d\x19\xea\xaf\x6c\x38\x5c\x49\x44\x40\x1e\xc8\xd5\x98\x40\xa8\xb6\x31\xfa\xe4\xf5\xf7\x2d\xb5\xac\x63\x92\x78\x3c\x2d\x81\xad\x29\x1f\x60\x1b\x92\x05\xa6\x12\x4b\xc1\x8b\xc8\x99\x7b\x4e\xe5\x89\xf5\x22\x1a\xed\xfc\xb6\xec\xf4\xfa\x60\x8f\x65\xa9\xe5\xed", 168, { 0x77, 0x8c, 0x9e, 0x7c, 0x8c, 0x2b, 0x00, 0xa3, 0x26, 0x62, 0x11, 0x70, 0x3a, 0xe1, 0x62, 0x5b } },
|
||||
{ "\x78\xe2\xe7\xc6\x51\x93\xec\xf1\x19\xcf\x07\xc0\xbb\x00\x25\x81\x38\x37\xf5\x21\xa8\xa4\x75\xec\xce\x21\x16\x6f\x56\xe8\x8b\x7f\xad\x66\x33\x52\x7d\x27\x21\xca\xc4\xf0\xc4\xd2\x90\xeb\x38\xe1\x59\xfd\x28\x9c\xfb\x34\x5d\x98\x4e\x5c\xe8\x3d\x64\xb1\xe8\xc6\x5e\xae\xf9\x64\xeb\x04\x39\x82\x5e\xa6\xf8\x24\x6b\x01\xfc\x69\x7f\x49\x6d\x2f\xb9\xef\x63\xd5\x88\x2e\x0b\x1b\xe2\xc5\x70\x26\x1d\xbf\xec\xa1\x6e\x6e\x2a\xfd\xfd\x76\xd6\xd8\xa1\x05\xe4\x7b\x3d\x20\x7a\x7e\xb6\x19\x7b\x86\x90\x1d\xb1\x2f\x24\xe9\x96\x04\x80\x9d\xbf\xab\xdb\xa9\xe6\x1e\xb3\xe4\x92\x14\x85\xbb\x65\x7e\x28\x86\x02\x2d\xc7\xf6\x99\x90\x79\xab\x10\x9b\x7f\xe2\xcf\xc4\x19\x4c\x28\x27\x05\xf9\x62\xca\x95", 169, { 0x0c, 0xf1, 0xe5, 0x46, 0x88, 0x85, 0xe9, 0x7a, 0x00, 0x08, 0xbf, 0xe5, 0x0b, 0x81, 0x55, 0xec } },
|
||||
{ "\x73\x61\xfa\x6c\xe8\xf3\xd4\xd4\x7f\xb9\xe0\xbf\xcb\xb0\xd7\x59\x5d\x5b\x85\x46\x73\x8f\xc9\x7d\xcf\xda\xba\xc0\xa3\x91\xe4\xb7\xa8\x75\xb0\xa8\x4e\x01\xe1\xd6\x0e\x53\x3b\x73\xdb\xb4\x3e\x42\xb6\xc6\x10\xce\x61\x49\x78\x40\x2b\x8a\x06\xe1\xea\x68\x51\x2d\x07\x04\x59\x90\xb3\x04\x0a\xc0\x38\x84\xe2\xb6\x6a\x9b\xa9\x4a\x3c\x85\x5f\x6a\x6f\x72\x34\xf6\x64\xea\xb1\x3b\x13\xdb\xf4\x0b\x14\x41\x18\x75\xdb\x70\xb3\x27\x01\x01\x79\x5c\xbd\x57\xfd\x83\x71\xcc\x98\x6e\x61\x7d\x62\x33\x7e\xaf\x5d\xa3\x60\xdd\xb2\x64\x53\x5f\x13\xae\x88\xb8\x3f\x9e\x6d\x7c\xa4\x3a\x17\xdc\x1e\x02\xda\xd0\xde\x2f\xfb\xe0\x66\x8b\x7d\x8e\xb0\xec\x17\x63\x6e\x4e\x47\x95\x6d\x8c\x80\x51\x13\xbb\x7f\xab", 170, { 0x46, 0x56, 0xb9, 0xc5, 0xa9, 0x38, 0x86, 0xec, 0xb8, 0x20, 0x03, 0xdb, 0xb1, 0xc2, 0x84, 0xd8 } },
|
||||
{ "\x07\x23\xbc\x20\xef\xdb\xfb\xc4\x54\x00\x01\x0c\xa3\x92\x64\x3a\x4d\xeb\x7c\x61\x0d\xdc\x76\x14\x49\x65\x87\xaf\x92\x11\x3c\x41\x46\xec\xf0\x15\x55\x22\x58\xdc\x20\x36\x38\x78\x7d\xdb\x38\x67\xd7\x72\xd1\xca\x73\x21\x62\x11\xcd\x8c\x5f\x45\x21\x33\xa8\xf2\x05\x68\xf8\xaf\x33\xeb\x74\x4c\x65\x24\x63\x96\x59\xfc\xfd\xc9\xf4\x58\x5c\x93\x83\x32\x8f\xc1\x1c\x56\xce\x88\x23\xb7\xc7\x72\xe8\x6c\x17\xe4\x6e\x4a\xd4\x48\x47\x1e\x47\xdb\x9a\x87\xb7\x14\x47\x6e\x60\xb0\x21\x24\x83\x57\x5a\x16\x97\xec\xfd\x2f\x9d\x76\x94\xca\x91\xa6\xe9\x53\xfc\x04\xea\x79\xa6\xba\xa5\x11\x69\xfd\x73\x8a\x21\x14\x32\x09\xc0\x06\xab\x21\x7e\xe4\x12\x30\x2d\xb0\xab\x59\xaa\xe9\x89\x19\x70\xb4\x71\x88\x46", 171, { 0xea, 0xdb, 0xc3, 0x9a, 0xf7, 0x45, 0x25, 0xa6, 0xbb, 0x14, 0x02, 0x97, 0x30, 0xae, 0x75, 0xc7 } },
|
||||
{ "\xa9\xde\x2f\x19\x37\x1e\x80\xe4\xb4\x9a\xf6\xcb\x04\x33\xca\x48\xe5\xc7\x4f\x7c\xd6\xd2\xea\xa7\xa2\x31\xb2\xb3\x8d\x02\xa0\xeb\x19\xa8\x73\xc9\x75\xeb\x23\xec\x83\x3c\xff\x28\x85\x15\x65\xb8\x63\x7f\x1e\x8e\x9b\xad\x54\xcb\xc5\xc6\x30\x4a\xc2\xc0\x14\x57\x81\x68\x72\x7e\x6d\x7e\x47\x7d\x77\xfc\x38\x5b\xbb\x77\x47\x92\xd1\x9f\x32\x67\xb3\xe1\x68\x5b\x46\x2b\xa8\xba\x87\xcf\x39\x50\x53\x81\xc0\x3b\xd2\x7b\xc1\xdc\x82\xc0\xb5\xe7\xdc\x7c\xc3\x9a\xa4\x8a\x1f\x0b\xd2\x10\xfc\x99\x18\x45\x2f\x84\x10\x53\x61\x99\x04\x58\xf1\x06\x59\x86\x64\x4c\x98\x69\x89\x51\x1a\x48\x2e\x95\x50\xa5\x78\x7d\xac\xe0\xe3\xcb\x30\xf8\xd7\x2f\x91\x70\xe3\xf6\x07\x50\x98\xe1\xb4\x42\x04\x11\xae\xdd\xca\x1d", 172, { 0x6d, 0xb0, 0x2c, 0x2a, 0xe2, 0xf9, 0xc9, 0xa2, 0x0a, 0x36, 0xf9, 0x94, 0x5f, 0x28, 0x33, 0xf3 } },
|
||||
{ "\xab\x00\xdb\x46\x48\x54\xd3\xc2\xf6\xf3\xf2\x34\x82\x27\xb5\x3d\x3f\x4a\x10\x2c\xd1\xcd\x4b\xd1\x99\x55\x76\x6f\xb8\x00\x8a\xcf\xc2\xc6\x1e\x71\x01\xfa\xc3\xde\x63\xee\xfc\x19\x01\xb6\xdd\x34\x4c\x06\x3f\xfe\xd6\x35\x9d\xda\xba\x62\x8e\xab\xaa\xb5\xdf\xeb\x93\xbf\x4c\xdb\xef\xfb\xdb\xd4\xa6\x76\xd6\xbd\xa2\x8a\x63\x96\xee\xc6\xc1\x30\x89\xea\x21\xff\xcd\x0d\x1f\x08\x77\xe1\xdb\xf4\x52\x0f\xb8\x47\x85\xbc\xb1\xaa\x75\x2d\x53\x64\x58\x87\x5b\xe7\x58\xaf\xec\x87\x5f\x50\x6c\x45\x85\xfb\xfd\xca\x14\x68\x93\x6f\x34\xda\xb7\x79\x38\xa1\xd7\x62\x83\xb9\x47\x52\x18\x90\xd8\xad\xbe\xe5\x13\xc5\xcc\xcc\x13\xb0\x96\xce\xfc\x35\x74\x2d\x1c\xe0\x6c\x44\x9c\x35\x7b\x0d\xe2\x01\x85\xbd\x87\xcc\xd6", 173, { 0xfb, 0x6c, 0x0f, 0xbd, 0xe3, 0x87, 0x1b, 0x0a, 0xb2, 0x35, 0xf1, 0xb1, 0x53, 0x60, 0xd6, 0xd2 } },
|
||||
{ "\x8a\xf0\x6a\x54\x8c\x8b\xb1\x44\xc1\xa8\x44\xb5\x2b\xf1\x8e\x8c\x14\x88\xcb\x2d\x72\xbb\x40\xc3\x65\x66\x8b\x2d\xdc\xe6\x15\x86\x58\xb5\xa3\x4e\xc9\xa7\x0c\x3a\x94\xc0\x05\x94\xb6\xb0\x18\x50\x02\xec\xb3\xad\x86\x69\x5d\x84\x0c\xf7\x03\x31\xbc\x39\x71\x1b\xdf\x3d\xdc\xe1\xbe\xbc\x9b\x22\xa8\xef\xf6\xe9\x13\x0b\x17\xb4\xda\x5b\x1e\x1f\xa5\xf9\x50\x32\x67\x29\x6f\x44\x00\x52\x24\x89\x02\x9a\x99\x3f\x90\x1d\x23\x72\x62\xc9\x1d\x67\xe6\xd9\xd0\xab\x81\xeb\x8e\xb8\xf3\xc0\xde\x40\xd9\x90\xd1\x19\x4b\x08\x73\xc6\xa5\xe1\x5d\x9e\x64\x1e\x68\x9c\x26\xe2\x7c\xc2\xd3\xeb\x86\x2a\xdb\xaf\x87\xaa\x95\x11\xc9\x23\xc7\xc0\x2e\x66\x43\x2d\xa1\xc4\xae\x26\xad\x31\x5c\x14\x2c\x14\x57\xcd\x17\xae\x7f\x17", 174, { 0xf9, 0x28, 0x28, 0x66, 0x7b, 0xe7, 0x4e, 0x18, 0xda, 0xce, 0xe9, 0x8d, 0xff, 0xab, 0x12, 0x98 } },
|
||||
{ "\x7d\x24\xcb\xba\x8f\x2a\xad\x41\xd8\x4e\x94\x4d\x89\xdf\x8b\x95\xf2\x78\xff\x7d\x0d\x2c\x9d\x52\x35\x4f\x5a\x20\xf4\xdf\x8c\x30\xf9\x8e\x35\x22\x28\x6d\x61\xa3\xcc\x36\xa5\xca\xe8\x36\xc7\x14\xab\xd5\x7c\xfa\x01\xc4\x4c\x2d\x46\xc1\x92\x6e\x15\x0a\x9f\x0b\x3f\x5c\xff\xf9\xd8\xa6\xd3\x8b\x6b\x4f\x5d\xcd\x4d\x21\x9b\x7f\x0f\xd0\x0a\xb1\x0d\x2b\x8b\xf8\x23\xde\x63\x4a\x7f\xe1\x5d\x7b\x92\x81\x0a\x55\x21\x09\x29\x4d\x78\x0d\x21\xe8\xbd\x52\xaa\xaa\x62\x5d\x8c\xb6\xb4\x97\x80\x07\x91\x19\x33\x49\x36\x1a\x68\x55\x36\xf2\x3c\x48\x87\xca\x85\x3f\xb7\xe3\x54\xb0\x3c\x7f\x9a\x68\xe8\x6f\xe7\x1d\x7b\x3a\x4d\xaf\x53\xe7\x63\x00\x3e\x68\x66\x6c\x70\xa3\x79\xe7\x90\x1e\x0d\xb2\xec\x45\x5b\xba\xcd\x5b\x0e", 175, { 0xeb, 0xa1, 0xc8, 0x38, 0xbc, 0x82, 0x3d, 0x39, 0xc0, 0x92, 0xec, 0xdb, 0xa3, 0xa7, 0xc6, 0x56 } },
|
||||
{ "\x8d\xe6\xfb\xff\xf9\xe6\x4a\x18\x43\x2d\xbc\x59\x01\x9a\x7f\xf9\x95\x83\x87\xa4\x46\xbe\x37\xe3\xfc\xdc\xa9\x9a\x98\x76\x9a\xaa\xee\x9f\xf5\xb7\x60\x79\xfa\x04\x18\xe3\x0b\x79\xe1\x50\x13\xc7\xa2\xb3\x93\xa2\x79\x96\x4b\x2d\x70\x4a\x81\x74\xdf\x39\xf1\x12\x5e\x57\x51\xf3\x64\xb7\x7f\x34\x81\x3a\x49\x27\x34\x62\xd9\x72\x6a\x44\xbb\x56\x94\x9c\x8c\x0e\x63\xfb\x42\x4e\x23\x1b\x12\xea\xb1\x53\x02\x98\x1a\x25\x0b\xce\xd2\xf5\xea\xc5\x8e\xd5\x83\xa0\xbe\x7b\xf2\xa5\xaa\x54\x30\xa9\x28\xb1\x5f\x8b\xf8\x1f\xb3\xd6\xbc\xd6\xfc\x8a\x96\x47\xd3\xf5\x60\xd8\x61\xba\x83\xac\xc7\xf3\x74\x9b\x2d\x73\xd1\x41\x6b\x24\x14\x32\x4d\x8f\xf1\x4b\x86\x7b\x52\x24\x35\xac\xed\xa1\x0c\xcc\x7e\xa8\x23\x68\xa6\xed\x58\x11", 176, { 0x48, 0xe5, 0x26, 0x3b, 0x57, 0x15, 0x53, 0xb3, 0x89, 0x25, 0x12, 0x09, 0x49, 0xd9, 0xd6, 0xd2 } },
|
||||
{ "\x60\xe8\x60\xa3\x1c\xe8\x6f\xa2\x7a\x41\x80\xbf\xa4\xa1\x41\x7b\x48\x81\x9e\xe3\x31\xb7\xe9\x79\x81\x27\xa3\x33\x8d\x9a\xea\x9c\x55\xa7\x7e\x19\x9e\xcd\x71\x47\xae\xa3\x6b\x7f\xa3\x26\x97\x7b\x71\x32\x2e\x12\x76\x0c\x9e\x1f\xbc\x1c\x56\x80\xca\xb8\x31\x3a\x27\x1b\x7c\xba\x6c\x74\xa6\x36\x05\x1b\x83\x32\x84\xde\x3d\x1f\xa1\x7a\xd7\x1e\xd2\x25\x5f\xe2\x83\x48\xb0\xb3\xf3\x4a\xe1\x8e\xab\x88\x4e\x69\x9b\x60\x41\x95\xd2\x6d\x3c\x3d\xd9\xcd\xe5\x0b\xad\x9d\x8e\xea\x58\x86\x60\xe6\x2b\x71\x25\x2f\x9a\x56\xaf\x3c\xb4\x32\xe7\x0b\x3d\x17\x75\x87\x69\x5d\x09\x03\x38\xf6\x45\xe3\x69\xdf\x47\x5b\x1c\xb3\xd6\x4e\x07\x5a\x28\x58\x54\xde\x4d\xe7\x16\x5e\x3c\x84\x67\x1b\x78\x30\x1f\xaf\x5f\xe9\x33\x5e\x0f\x4c\xa7", 177, { 0x3d, 0x14, 0xce, 0xb4, 0x3a, 0x69, 0xc6, 0xb9, 0x35, 0x2a, 0x07, 0x20, 0x11, 0x8a, 0x7d, 0x87 } },
|
||||
{ "\x85\xf5\x54\x31\x2f\xf4\x40\x6c\xc7\x2e\x93\xb5\xe7\x71\x35\xa6\x4f\x41\xb7\x2d\xf1\x7e\xb4\x48\x28\xb2\x53\x5f\x09\xf9\xe8\x3d\xd2\x8d\xba\xad\x80\xed\xdf\xad\x7c\xaa\x44\x51\x75\xce\xc9\x37\x49\xe9\x89\xa3\x1c\xb9\x37\x37\x8c\x75\xa3\x50\xfb\xb6\x5c\xff\x0b\x03\x70\xa2\x28\xf7\x4f\x1f\x3e\x11\xce\xbc\x8c\x18\x47\x9e\x90\x29\xdd\xdd\x22\x5f\xdd\x40\x9d\x1d\x40\x9a\x37\xfa\x4d\xc0\x72\x4a\x5b\x25\xab\x45\xb4\x15\xd0\xd7\x96\x8a\x2f\x03\x53\xae\x69\xf4\x98\xee\x85\xa2\xca\xb7\x21\x1d\x8c\xd0\xc3\x7a\x5d\x54\x4d\x57\x5f\x4a\x8f\x0c\x32\xe3\xf7\x6f\xff\x4f\x63\x44\x91\x3c\x17\x40\x9d\xec\xca\xb8\x22\xf1\xdb\xeb\xeb\x88\xa1\xe8\x32\x90\xdf\x1d\x5f\x25\x57\x7e\xed\xde\x75\x4e\x6e\x9f\x2c\x8d\xa5\x1b\xde\xff", 178, { 0xaa, 0x31, 0x4b, 0xfa, 0x31, 0x2f, 0x20, 0xf7, 0x63, 0xcf, 0x19, 0xbd, 0x14, 0xf2, 0xac, 0xda } },
|
||||
{ "\xd1\xe9\x75\xd4\x09\x42\x8f\xf9\xc2\x55\xd6\xfa\x6e\x47\x6d\x92\x3f\xca\x86\xd1\x09\x59\x10\xe8\x46\x0d\x8e\x94\x33\x1f\x03\x25\x17\xfb\x09\x2a\xa3\xfd\x02\xbb\x75\xca\x65\x63\xb7\x4e\x3a\xa7\xe4\x4d\xa1\x37\xab\xa8\x8b\xb1\xec\x2f\x8c\x0c\xdf\x1d\xc9\xa7\x54\x34\x0c\xee\x14\x76\xf6\xa6\x67\x7d\x54\xd7\xaf\x77\x8a\x53\x32\xc2\x2b\xe6\xf5\x20\xab\x1c\xc3\x97\x2c\xa9\x4d\xe8\x74\x79\x6b\xa9\x00\x55\x81\x01\x32\x2e\xfc\x00\xa5\x0a\xfc\x99\xa1\x88\x0c\x3d\xaa\x11\x0c\x14\x33\x9d\x30\xda\x70\x1f\x21\x55\x49\x8f\x41\x6e\x6a\x92\x0c\xf3\x77\xc7\x9a\xe8\x5d\xb0\x40\x86\xc4\x3b\x56\xd1\xa0\xec\x14\xd9\xe7\xaa\x96\x8d\x5d\x23\xff\x36\x8a\xdc\xb9\x98\xce\xd8\xda\xa0\x8b\xe4\xa2\xc9\x80\x7d\x21\x12\x36\x5f\xf6\x94\x92", 179, { 0x24, 0x4a, 0x76, 0x30, 0xfe, 0x50, 0x3c, 0xd3, 0x96, 0x8d, 0xed, 0x72, 0xd2, 0xd1, 0x92, 0x63 } },
|
||||
{ "\xac\x31\xc2\x8b\xb5\x5a\x42\xf6\x67\x8b\x62\x7d\x55\xb8\x38\xaf\x5d\x0f\x5b\x31\xfa\x7a\x38\x11\x26\x42\x11\x3b\xea\xcd\x98\x04\x83\x88\x24\xe4\x32\xe0\x8e\x41\xa1\x69\xab\x66\xed\x22\x65\x92\x54\xd0\x78\x2d\x7c\x86\xc6\x16\x5e\x46\x58\x17\xcd\xc2\xf2\x7a\xa7\x3b\x52\xb5\x97\x8b\x05\x40\x84\x3d\xe5\x87\x99\xda\x32\xfb\xf2\x3f\x4c\x43\xe0\x29\x0a\x91\xd9\xd3\xbb\x0f\xff\xb6\xb7\x77\x4b\x6f\xa0\xc2\x56\xbf\x3a\xf8\xc4\xac\xe4\x26\x4d\xc4\xb3\x6e\x69\x81\x2a\x38\x97\xc8\x97\x87\x4b\x8c\x0c\x66\x72\x90\xf9\x80\xa3\x49\x63\xcf\xe3\xe1\xc3\x6d\x15\x58\x7d\x86\xfc\xc5\xfb\x6f\xee\xbb\x66\xcf\x18\xc6\x01\xfb\x68\x15\x22\x60\x1b\x31\xcd\x19\xe3\xeb\xee\xa1\xb4\x55\x33\xa2\x2b\xe6\x84\xec\x9b\xc1\x20\x81\xb6\x0f\x55\xcd", 180, { 0x74, 0x83, 0x94, 0xea, 0x7a, 0x82, 0x27, 0x87, 0x79, 0x88, 0xa8, 0x23, 0x8f, 0xc2, 0x4e, 0xaa } },
|
||||
{ "\xd5\x88\xdb\xf3\xe4\x11\xce\x42\xed\x80\x47\xc6\x3f\x7b\x96\xfb\x3b\x7e\x1d\x9d\xba\xfb\xcc\x9b\x1e\x9b\x34\x29\xf4\xa3\x4a\xf4\x43\x72\xbb\x71\x74\x26\xe6\x4f\xdd\x5f\x7b\x0b\xec\x1b\xae\xa1\xec\xc0\x17\x60\x77\x39\x29\xd7\x79\x38\x4c\xeb\xdc\x99\x9a\x0a\xd5\xe7\x33\x7a\xca\xf7\x3e\xcb\xdf\xb2\x7c\x6b\x1c\xf1\x8a\x58\x3c\x81\xb3\xf0\x15\x45\x6f\xe4\x9f\x7b\x7d\x4b\xa2\x17\x98\xd3\x00\x4b\xd9\x12\x9c\x28\xa8\xfa\xe6\x5e\x60\x6b\x05\x1f\x7f\xe3\x9f\x22\x86\x50\x48\xc4\x73\x06\x84\x48\xd9\xcc\x7b\x3f\x99\x11\x38\x03\x3f\x3c\x9d\x5d\xfb\x21\xe7\x47\x3a\x8f\xda\xcb\xe0\x06\x89\x0a\x24\x86\xc4\x58\x09\x82\x1e\x85\x75\xf4\x99\x37\xf0\x8a\xf0\x72\xfa\xfe\x81\x3a\x08\x83\xd6\x50\x1d\x5b\xcf\x17\x02\x85\x6d\x9a\x22\x94\x3d", 181, { 0x15, 0xb7, 0x30, 0xcc, 0x2e, 0x0b, 0x5f, 0x0f, 0x3f, 0x7d, 0x9a, 0x52, 0x62, 0x75, 0x4d, 0x08 } },
|
||||
{ "\xa7\x04\x9b\x5f\x13\x65\x45\x32\x21\xf1\x01\x9e\xfe\x9e\x5a\xfd\x63\xa5\x64\xa6\x5d\x1e\x52\x18\x29\x38\x25\xc0\x39\x12\x7f\x67\x53\x38\x96\x3b\xd9\xbd\x44\x78\x23\xf1\x3a\xb3\x08\xbf\x55\xc3\x7c\xa6\x09\x4c\x53\x52\xf9\xe9\x24\xd6\xa9\xf6\x48\x88\x4b\xf7\x02\x7a\xb5\xa8\xb9\x90\x74\xa1\x60\x43\xfa\xa6\xf6\xf1\xf2\x89\x29\xde\xb5\xbc\x16\xcb\xd4\x77\x2b\x31\xd5\x82\x2e\x1a\xfc\xa0\x56\x9d\x3e\x98\x97\xf4\x5b\xe1\xfb\x3b\x04\xe9\x2c\xc7\x37\x02\x0e\x21\xac\xe9\x89\x9e\x67\xf5\x64\x9c\x6e\xd9\x4d\x5b\x95\x15\xf5\x75\x75\xff\x58\xfb\x7b\x6a\x1a\x2e\x1c\xf0\x0d\xd7\x26\xe2\xcf\x44\x32\xc8\x91\xdf\x36\x96\xf2\x6c\x37\x6e\x09\xde\x1b\x0c\x82\xd7\x9c\xd3\xdf\xbb\x59\x71\xe0\x70\x07\x31\xfe\xb4\xc4\xdd\x10\x1a\x8c\x4d\x11\xa2", 182, { 0x96, 0x00, 0xc5, 0x60, 0xaa, 0xdd, 0xfd, 0x65, 0xc4, 0x77, 0x58, 0x7b, 0x27, 0x5e, 0xcd, 0xef } },
|
||||
{ "\xc4\x90\xf9\xf4\xf4\xb6\xc7\x39\x92\x39\xa0\x96\xf9\x06\x11\x46\x79\x2b\x71\x53\x87\x1e\x62\xf1\x15\xa7\x76\x77\xfd\x6b\xed\xfb\x96\x17\x9d\x88\x69\x25\xeb\xfe\xfe\x4e\xf5\x87\xcf\x8c\xd2\xb2\x5e\xcb\xf1\x2d\x62\x2b\x9e\x23\x1d\xf4\xa3\x30\xc9\x17\x0b\xfd\x30\x5d\x01\x7d\x5b\x2f\xd8\xc3\x62\x00\x24\x7d\x62\x5b\x05\x11\x8d\x84\x84\x52\x5c\xce\x15\xdf\xdf\x79\x3c\x18\x34\x45\x4d\xbe\x16\x97\x4b\x26\x8d\x47\xf2\x1a\xc3\x04\xd1\x4d\xf7\x65\x8e\x78\x8b\x8c\x4d\x15\x37\x79\x2c\xb7\x60\xe9\xe5\x04\x83\xe8\x97\x51\xcb\xfa\x9e\xd8\xc3\xe2\x9e\x98\x26\x0d\x9f\xc9\xd1\x9e\x52\xfb\xd9\x17\x72\xca\xb9\xa0\x46\x40\xa4\xf7\x43\xc7\xf9\xf5\xce\xc9\xd5\xb9\x1e\xe6\xc2\x73\x40\xd1\x8c\xcf\x34\xc8\x34\xfb\x35\xae\xfe\x57\x16\xc6\xa5\xb9\xc8", 183, { 0xef, 0xfd, 0x81, 0xc1, 0x6c, 0x60, 0x89, 0x07, 0x98, 0xf3, 0x9c, 0xe6, 0x82, 0x4e, 0x17, 0xaa } },
|
||||
{ "\x0e\xaf\x59\xf8\x36\xdb\x60\xd5\x3b\xb6\x08\xef\xa5\x4c\x6f\x3b\x59\xfc\xfe\x33\x1b\x65\x70\x1a\xa4\x7c\x82\x5d\x5c\xc0\x36\x15\xb5\x84\xc3\xaa\x24\x6b\x1c\x91\xbc\xf3\x1b\x35\x68\x28\x4a\xf4\xc4\x78\x4e\x40\x99\xa7\xf1\xe6\xf3\xd9\xca\x6b\xe1\xcc\x8b\x92\xc9\x29\xe7\xfb\x65\xef\x1e\xe5\x5e\x0f\x26\x14\x83\x17\x77\xce\xa6\x06\x74\xff\x13\x3e\x71\x7c\xae\x97\x65\x64\xa8\x8f\x2d\xa3\xdd\xa0\x7a\x90\xce\xaa\x59\xb6\x36\x90\x5d\xb0\x4b\xdf\x6b\x2e\x92\xa8\x22\x14\x5f\x6e\xe5\xc1\xe8\x3b\x86\x6d\x05\xcd\x90\xab\x87\xee\x31\x0e\x32\xe1\xc2\xe8\x58\xf8\xf5\x2d\x13\x43\x9a\x77\x1e\x62\x0e\x23\x50\x7c\x40\x98\xb7\x48\x61\xa8\x4d\x48\x28\x0e\x59\x16\xbf\x17\x65\xd7\x4d\x5e\xd8\xcc\x21\xb0\x2f\x07\x78\x0e\xdc\x3a\xeb\xd0\xbb\xab\x78\xe6", 184, { 0xe5, 0xf6, 0xa3, 0x02, 0x8d, 0x9c, 0x95, 0x97, 0xf0, 0x29, 0x88, 0x10, 0x26, 0xed, 0xac, 0x58 } },
|
||||
{ "\x2d\x43\x2a\x3a\xd3\xc6\x68\x31\xe9\x1e\xd8\x51\x3c\xd0\xee\xfd\xc9\x90\x15\x5b\xf4\xef\x78\x56\x62\x32\x6d\xbf\x73\x3f\x7e\x8e\x5f\xb1\x16\x47\xec\x0a\xc5\x78\xc9\x08\x30\x5e\x8b\x10\x98\xa8\x41\xc7\x05\x53\xb5\xc0\x0e\xb4\x42\x4f\x48\x94\x4d\x7c\x49\x75\x61\x13\x58\xf3\xeb\xd9\xb2\x46\x8e\xd9\x7b\xe4\x24\xdc\x40\x43\x53\xf6\x25\xbc\xc7\x3d\xb0\x8b\x11\x95\x30\xf3\x1c\xa7\xcb\x7f\x47\xf0\x23\x62\x24\xf5\xa5\x00\xcd\x95\x6e\x86\xde\x77\xd9\xb3\x12\xa1\xa9\xba\x7d\x2a\xd0\x40\x63\x08\xda\x80\xb4\x03\xf9\x8e\x25\xcb\xad\xb9\xec\x24\x10\x09\x18\x3f\xbb\xe7\x8a\x25\x58\xdc\x94\x4c\xc6\x72\x2c\x4c\xe2\x37\xcc\xab\xf8\xdf\xea\xd4\xc6\x89\x0f\x27\x29\x1a\x97\x2a\x67\xc6\x04\xdc\x18\xad\xfe\x2a\xb1\xa1\xeb\x7b\xae\x06\x27\x66\x5c\xd3\xe0", 185, { 0x57, 0xa9, 0xed, 0x9a, 0xe3, 0x2c, 0x62, 0x78, 0x43, 0x4c, 0x1b, 0x41, 0xd3, 0x3c, 0x09, 0xe6 } },
|
||||
{ "\x83\x40\xb5\x91\x5f\x27\x52\x19\x89\xcc\xaa\x77\xc9\x1f\x9a\x25\x71\x38\x7b\x0d\xcb\xd8\xe7\x2c\xb1\x97\x9b\xc2\x3c\xb0\x78\x33\x94\x65\xa4\x7e\xe7\x10\xcd\x57\x75\xc8\x8e\xe2\xc7\xac\xea\x0e\xff\xcf\xf5\x8c\x4b\xc0\x91\x6b\x74\xb4\x56\x52\x93\x52\x8b\x59\xe2\x1b\x51\x84\xb0\x75\xe0\xdc\x6e\x52\xe8\x2c\xe7\x81\x19\x55\x8d\x91\xbe\x4e\xee\x5e\x84\xbc\x46\x39\x59\x2a\x2d\xb8\x70\xe5\x71\x17\x60\x77\xfe\x49\x6c\xbe\xfa\x9f\xde\xa8\xed\x14\x8c\x8d\x1e\x32\x7c\x28\xf9\xa5\xa4\x33\xab\x5b\xca\x9f\xd0\x54\x8a\x6d\x44\x0b\x76\x2c\x16\x81\x57\x0f\x9b\xe2\x92\xaa\x9e\xd6\xa6\x49\xb5\x67\xd2\xed\xaf\x8a\xd3\xe4\x29\x4c\xcb\x04\x40\x9a\x3e\x83\x60\xad\x35\x76\x3b\x10\x85\xe4\xd6\x4f\x2a\x87\xbd\x3e\xcc\x1e\x57\xe3\x64\x71\x54\x01\xf8\xe3\x42\x42", 186, { 0xcb, 0x49, 0xbe, 0x32, 0xa6, 0x87, 0x50, 0x00, 0x6b, 0x95, 0x12, 0xf2, 0x40, 0x2b, 0x3e, 0x10 } },
|
||||
{ "\x82\xad\x3f\x00\xef\xbd\xc9\xaf\x43\x2a\xb1\xeb\xd9\x52\x2f\x1a\xc8\x92\x0e\xbe\x62\xa1\x08\x5a\xd6\x89\x2c\xfd\xf5\x43\x7b\x6f\x11\xef\x93\xf7\x01\xad\x83\xc7\x42\x1b\xbd\x06\x38\x6b\x29\x78\x92\x1f\x56\xcb\xcb\x64\xcb\x80\xcc\x09\x7c\x73\xae\x1a\x58\x09\x9e\x1d\xff\xf6\xda\xe8\x91\xa8\xd7\x1d\xa2\x54\x85\x44\x49\x9b\xaa\x83\x58\xd8\x6b\xfc\xa6\x09\xea\xc3\x87\x57\x08\x7a\x5d\x43\x4b\x8c\x48\x6f\xdb\x02\xf8\x07\xa7\x05\xa4\xca\xa5\xf1\x13\xb9\x36\x11\xd8\x5a\xa7\xfd\x9b\xa9\xd4\x8d\x91\x9c\xe7\x79\x0d\x52\x3e\x8f\x30\xd7\x6b\x8f\xbd\x96\x54\xa6\x07\x5c\x7b\x85\x0b\x04\x59\x1e\x9a\xc5\xe3\xfb\xaf\x14\x2e\x3b\xdf\x37\x2e\x29\xee\x68\x9a\x7a\x7d\xa2\xec\x23\xe1\x0b\x84\xd5\x10\xfd\xec\x16\xb5\xb2\x36\xfd\x63\x8c\x82\x8a\xe5\xff\x9c\x9f\xb4", 187, { 0x19, 0x6a, 0xcb, 0x09, 0x35, 0x27, 0xb3, 0x8d, 0xd4, 0xcb, 0x04, 0x0f, 0x85, 0xa6, 0x19, 0x58 } },
|
||||
{ "\x1c\xc2\x9f\x82\xba\x82\xa2\xf3\x43\xc2\x52\x6b\x18\xda\x65\x02\xa2\xdb\xb7\x94\xf6\xf3\x03\xf6\x24\xe8\x3e\x43\x1d\xc2\x90\x54\x3e\x86\xef\x4d\x7d\x1c\x5a\x54\x2f\x52\xb0\x5d\x73\xf9\x2a\x21\x3f\x2d\x7b\x2d\x05\xb3\x83\x17\x01\x7b\xaa\xcb\x22\x44\xdf\x03\x92\x5e\x2d\xd5\xe4\x8b\xf7\x66\xd9\xff\xd0\xbc\xcf\x87\xf9\xb2\xc7\xc6\x78\x04\x11\x99\xd1\x8a\x96\x9c\x64\x82\xc2\xc6\x62\x06\x0c\x30\x6d\x9c\x23\xf3\xcc\xec\xb6\x2e\x48\x8c\xe0\x27\xa6\xf8\x2f\x89\xc0\x9d\x50\xcb\x42\x14\x58\xb1\xfe\x6c\xb1\xec\xed\xa0\x9f\xdd\xc3\x27\x6e\x78\x2d\xab\x3a\x43\xaa\xd1\x5b\x7c\x03\x37\x6b\x5a\x68\x7c\xf4\x6c\x29\x78\xbb\x1e\x0e\x8c\xa3\x5b\x53\x15\x40\x4c\x43\xfa\xf9\x3d\x6f\x65\xd9\xa1\x8b\x8f\xf2\x2c\xe6\xb3\x6e\x1e\x85\x24\x33\xa0\xdb\x7a\x32\x46\x26\xe8", 188, { 0x6e, 0xa3, 0x09, 0xda, 0xde, 0xad, 0x44, 0xc1, 0x7b, 0x3f, 0xcd, 0x70, 0x94, 0x3c, 0x2a, 0x39 } },
|
||||
{ "\x4d\xb5\x68\xa9\xe3\x5e\x00\x99\xf9\x68\xe5\xe0\x06\xac\x80\xc9\x5b\xda\x23\xb1\x2d\xb9\x29\x1a\x40\x8b\xaa\xdf\x32\x8e\xdb\x82\x62\x9f\x01\xa1\x7b\xfa\x10\x88\xa1\x1c\xe4\xdf\x36\xc9\x1b\x84\x49\x2a\x8d\x74\x9b\x0e\x69\xe2\x50\x51\xed\x6a\x2f\x5a\xc1\x5f\x96\xbd\xf1\x40\xfd\x02\x85\x4a\x24\x7d\xbf\x27\xdc\x5c\xf1\xc4\x6f\xbf\xf8\x40\xae\x01\x59\x00\x95\x16\xf6\xdf\x9c\x0d\x6c\x83\x9d\xb4\x0c\xcb\x5c\x5a\x75\x64\xb8\xaf\xcb\x7b\x6d\xc8\x96\x8c\x84\x3f\x39\x59\x58\x78\x0c\xf7\x45\xfe\x19\x02\xee\x0b\x70\xf1\x2b\x26\x27\x84\x8e\xe7\xf2\x5a\x90\xd6\x5b\x9f\x5d\x72\x9e\xe2\x39\x4d\x23\x04\x8d\x54\x98\x4c\x92\x2d\xaa\x98\x99\xb9\x61\xaf\xf4\xb9\x16\xb1\x85\x8c\x11\xaf\xe1\x16\xc3\x57\x1f\xbd\x9c\xc8\x43\x8d\x8a\x84\x42\x7b\x10\x83\xb2\xc7\xfe\x64\x10", 189, { 0x84, 0x35, 0x9a, 0xad, 0x8c, 0xa1, 0x8d, 0xfc, 0x2a, 0xaf, 0xbc, 0xa9, 0x59, 0x79, 0xf1, 0xae } },
|
||||
{ "\x7a\xd3\xbf\xad\x0f\xab\x95\x35\x2e\xe6\xe9\xdd\x93\x58\x68\x29\x0e\x26\x43\x57\xa3\x43\x1e\x6b\xd1\x87\x20\xd8\xf0\x69\x2b\xc8\xb3\x59\x25\x08\xce\xbd\x75\x93\xb1\x85\x8a\xba\x71\x6d\x95\xec\xc8\xcf\x57\x28\x33\x22\x14\xfc\x39\x13\xa7\x38\xcc\x3e\xaf\x34\xc8\x89\xe7\xbb\x98\x1d\x94\x93\xf8\x02\x17\xaa\xd5\x56\xa2\xdf\x50\x2a\x07\x69\xe1\xf9\xac\xe8\x98\xc6\x9b\x06\x7f\xd1\xb6\xca\x1c\xf5\x08\x79\x13\xa1\x36\x29\xe7\x71\x14\xe3\xe1\x68\x53\x74\x09\xcc\x59\xd0\x51\x9f\x29\x24\xd2\xb5\x81\x77\x2d\x77\x03\xfc\x14\x32\x8b\xf6\xe1\x1c\x9f\x48\x63\xe5\x04\x98\xba\xf6\x6d\x1f\x58\x4a\x4f\x11\x27\xe5\xd0\xa3\xc9\xf4\xdd\xbd\xfb\x83\x5a\x3e\x13\xd5\x75\xe6\xa8\x63\x14\xe5\x50\x74\x6c\xfd\x84\x55\xb3\x56\xa0\x36\xed\xde\x07\xa1\xe3\x5a\x64\x97\x33\x0e\x0b\x49", 190, { 0x15, 0x6b, 0xec, 0xbe, 0xf4, 0xb1, 0x19, 0x29, 0x9b, 0x9c, 0x5a, 0x59, 0xd9, 0x1c, 0x8f, 0x68 } },
|
||||
{ "\x80\x05\x7d\x70\xc9\xfe\x0a\x49\xd8\xf3\x91\x31\xd1\x47\x63\xd8\xea\x8b\x46\x25\x39\xed\x95\xa6\xa8\x3d\x85\xb2\x06\x9d\x82\x1e\x38\xc5\xb8\x98\x8d\xf0\xad\xa3\x2f\x67\x0b\x2f\xb4\xa8\x7c\xd4\xd4\x33\xae\xab\x36\xf0\x76\xc9\x63\x40\x10\x59\xdc\x9e\x84\x55\x46\xf2\x25\xe1\xc3\x72\x34\x44\x5d\x35\xa1\x83\x9c\x56\xf1\x9c\x37\xc1\x3b\x5c\xe7\x9d\x4c\xdd\x56\x56\xea\xa0\x37\x45\x36\x43\x6f\xff\x2a\xdf\x70\x37\x42\x00\xa7\x51\x38\x42\x0b\x84\xe7\x84\xd6\xaa\x51\xcc\x51\xa7\xbc\xb7\xc7\x74\xf7\x9b\x9b\xc7\xba\x3b\x76\x61\x2b\x25\x98\xf3\x7d\xac\x50\xae\xb3\x7e\x87\x66\x83\xe1\x76\x61\x55\x8e\x78\xc2\x6a\x2a\xf9\x8d\x1a\x5d\x8e\x56\x36\x91\x1f\x8b\x8c\x49\x3f\x5a\x88\x1b\x9c\x40\xf7\x4c\x92\x30\xe7\x06\xda\x5c\xab\x38\x5f\xa2\xfb\x0a\x31\x96\x37\xfc\x92\x28\xcc", 191, { 0xaf, 0x3e, 0x62, 0xef, 0x2b, 0x45, 0x27, 0x17, 0x20, 0x4f, 0x50, 0xb2, 0xb9, 0xa7, 0x9b, 0x48 } },
|
||||
{ "\x9a\x2e\xf2\xaf\xde\x68\x21\x07\x22\xd0\xfd\xe7\xc0\xb0\x16\x39\x48\xc6\x0d\xb6\x5d\x0b\xfc\x11\x2c\xb2\x83\x34\x8a\x2c\x70\xa1\xa9\x68\x0a\xfb\x77\x19\xfa\x9e\x94\x2f\xd7\x68\xed\x67\x4c\x9b\xfa\xfe\xe8\xdb\x90\x81\x82\x51\x63\xc0\x47\xf2\x1c\xe0\x62\xda\x13\x90\x46\xd2\xaa\x54\x9b\xf1\x45\xfd\xc3\x5e\xe9\x39\x07\x33\x70\x46\x63\x7d\x66\xc2\xea\x60\x84\x9f\xd7\x57\xc7\x32\x32\x9a\x2b\x6a\x1c\x98\x09\x1d\xb7\xa3\x0a\x7e\xb4\xac\xc7\xab\x7a\x23\xff\x63\xf0\x00\x74\xd5\xe7\xe0\x62\x93\x27\x47\x9d\xa6\x14\x04\x46\xbb\xfd\xb2\x29\x7a\x02\x5a\xb6\xf7\x9f\x36\x9a\x41\xd9\x91\xfa\x18\x03\xca\x4c\xbd\x2d\x77\xd1\xe1\x2a\xa5\xb3\xbf\x3d\x3e\xb7\x45\x60\x84\x9e\x6d\x30\xb9\x1e\xab\x78\xe1\x78\x7f\x58\x9f\xb6\x2a\x11\x3c\x83\x7d\x70\xc7\xa6\xcc\xd5\x56\x1d\x02\xe0\x6a", 192, { 0xc8, 0x67, 0xcd, 0x31, 0xf4, 0xb8, 0x95, 0x60, 0x67, 0xc3, 0xcd, 0x10, 0xe4, 0x31, 0xe5, 0x8e } },
|
||||
{ "\xd2\xce\xb7\x71\xfc\xfc\xf5\x64\x15\xde\x32\x91\x73\xe8\x2b\x73\x86\x5c\x8e\xbd\xad\x1a\x65\x76\xb5\x99\x1c\x3d\xee\xf3\x30\xae\xec\x1a\x76\xdd\xd7\x28\x06\xff\x6f\xd5\xc2\x29\xa1\x02\x86\x30\xbe\x72\xee\xaf\x5e\x98\xbe\x26\xd0\x8a\xf2\x3f\x3c\x15\x63\x2d\x58\xeb\x13\x2d\xc3\xf8\x15\x2e\x01\xd3\x1c\x8d\x14\x4f\x9e\xf9\xb3\x30\xa4\x76\x2a\xfa\x31\x7d\xcd\xe5\x4c\x40\x1a\xee\xac\x0a\x6a\x07\x00\xc5\x54\x6f\xd8\x96\x9f\x1c\x33\xa3\xe1\x54\xa6\xf4\xb8\x5a\x25\x77\xa4\x46\x71\x1d\x80\xee\x1e\x23\x9b\x00\x40\x6b\x77\x32\xb2\x08\x1d\x90\x02\xd9\x1b\xf4\xfc\x4c\x1c\x94\xd1\x44\x22\xb5\xe4\x15\x62\x7e\x32\xac\xbc\xe7\x5b\xcc\xd5\xd0\x51\x73\xd3\x2e\x9c\x5b\xb4\x60\x47\x9c\x4b\xa0\x6b\x6e\xd9\x94\x55\x0d\x44\x04\x57\xb5\xf6\xa7\x28\xcd\x55\x16\xf8\x20\xda\xe2\x15\x46\xd0", 193, { 0x0e, 0x63, 0xa1, 0x87, 0xec, 0x2a, 0x99, 0xd9, 0x1d, 0xec, 0x28, 0x37, 0x05, 0xb3, 0xe9, 0x44 } },
|
||||
{ "\xc1\x33\x21\xab\xe3\x5b\x83\x03\x63\x73\xed\x2b\xd9\x66\x72\x72\x0c\xef\xbb\xf6\xc4\x07\x23\x20\xbe\xe9\x02\xbf\xb9\xbe\x08\xc4\xae\xeb\xbf\x98\x1c\xf3\x32\x16\x81\x09\xac\x28\xe5\x36\x99\x01\x8f\x23\x8a\xf4\xdb\x84\x54\xf0\x24\x21\x57\x99\xdb\x82\xdc\x03\xb9\x37\x98\x0d\x11\xc1\x4e\x58\x3e\x21\x90\xe3\x3c\xfa\xa5\x44\x53\x65\x86\x85\xee\x51\x03\x99\x8a\x95\x03\x7a\xca\x94\xe8\xe0\xa7\x8c\x11\x9f\xc4\x7b\x79\x9e\xdf\xae\x7c\x6f\x64\xe7\xba\x90\x1c\x2a\x14\x3d\x02\x24\xd4\xf0\x36\x39\xe9\x77\x0b\x29\x4f\xaf\x3b\x5d\x8d\xe2\x3a\xd4\x58\xbb\xa7\xa5\x55\xe2\xdf\x30\xfc\x38\xac\xe5\x98\xb0\x1b\xb0\x6b\xc8\x6b\x00\xee\xa3\x21\x73\x35\xc5\x39\x20\x71\x6a\x77\x80\x90\x83\xdb\xf9\xff\x4e\x32\x09\x8f\x91\xc9\x0b\x75\x72\x3d\xa9\x6b\xf6\x6e\xdf\xf5\x14\x92\xa7\xbe\x75\x65\x47", 194, { 0xa3, 0x61, 0x94, 0x86, 0x67, 0x56, 0xab, 0x69, 0x85, 0x9b, 0xbc, 0xa2, 0x1c, 0x09, 0x1e, 0x31 } },
|
||||
{ "\x21\xcb\x7e\x33\xc3\xcb\xbd\xa0\x5d\xc8\xe1\xa6\x97\xee\x36\x10\x10\x17\x6b\xc4\x7a\x4d\x82\xc9\xe3\xdd\xe0\xfa\x0e\x14\x84\x46\xff\x99\x54\xa1\x96\x66\x93\x8b\x53\x65\x70\x3b\x38\xa3\xb7\x68\xcc\x33\xaa\xb3\x3b\xa2\xeb\xb4\x9b\x12\x90\x9f\x49\xf5\x59\x93\x72\x68\xfd\x7f\xae\x29\xa0\xb1\xc6\x37\x62\xfc\x96\x05\x11\x86\x0e\x5a\xfe\x2c\x52\xc8\xed\x92\x01\xc6\x26\xca\x93\x6c\xa8\x9f\xdc\xcb\x7d\x80\xad\xe7\x29\x04\x9a\x53\x3c\x1e\xd5\x67\x07\xde\x39\x1f\x6b\xe1\x63\x93\xcd\x57\xfb\x0f\x25\xaf\x11\xce\x36\xe1\xa1\x58\xd8\x57\x39\x75\x71\x79\xb2\xcc\x82\xd4\x19\x1d\x5d\xe6\xb2\x18\xf5\x88\x12\xd8\xce\xf8\x6b\xff\x13\x82\xe5\x6e\xc6\xcb\x27\xa1\x11\xba\xf4\xa6\xbc\x04\xf2\xb8\xb8\x52\x87\x7c\xd8\x10\xdc\xd7\x9f\xd4\x03\x6a\x34\x69\x35\xab\x72\x78\x34\xa1\x1c\xd2\xcf\x3c\x2e", 195, { 0x6f, 0x1c, 0xed, 0x06, 0x68, 0x7c, 0x13, 0x93, 0x1d, 0x84, 0xbc, 0xd5, 0x40, 0xbb, 0x5a, 0x78 } },
|
||||
{ "\x5c\x84\x4e\x4e\x98\x3f\x2a\x61\xcc\x41\xd8\x3a\xd1\x1c\xf1\x6e\x79\xda\x1d\x43\x9e\x3e\x27\xc7\xc3\x22\xba\xfc\x6a\xff\xbb\x31\xf2\x8b\x42\x6c\x29\x7d\x35\x03\x76\x6c\x83\x4a\x9c\xd5\xfb\x66\x2c\x3c\xc6\x40\x8a\x69\x87\x95\x99\xd3\x0e\x2b\x06\x1b\xb3\x1e\x2e\xaf\x55\x59\xad\x8f\xef\x20\x84\x2c\xd3\xc9\xe6\x6c\x87\x8b\x9f\xcb\x39\x6e\x22\x9b\xdf\x62\x2d\x6c\xef\x6c\x1b\x86\xb8\xfb\xc6\x93\x5c\x59\x16\x5a\x6a\x3d\x2b\xa6\x1c\x7d\x23\x45\x2a\xe0\x88\x2c\x48\x11\x59\xb8\x43\xb0\xb3\x0f\xb4\x83\x1c\xa5\x5e\xca\x6c\xda\x2a\xb0\x59\xc1\xbc\xdd\x9d\xfc\xb1\x28\xc6\xc3\x78\x6a\x9a\x03\xca\x6e\x24\xa3\xc7\x04\x5f\xe1\xae\x35\x7e\xdb\x39\x90\xd6\x2a\x93\xa3\x69\xa9\xf7\x86\x10\x53\xe6\x91\x44\x4a\x04\x2d\x89\xf4\x90\xc8\x77\x40\x7e\xe2\x66\x07\x33\x45\xb5\x8d\xdd\x51\xb7\x26\x6c\x75", 196, { 0x26, 0xa3, 0xf1, 0x62, 0xb9, 0x04, 0xc2, 0x92, 0x0c, 0x08, 0x6f, 0x8a, 0x4a, 0x9e, 0x80, 0xaf } },
|
||||
{ "\x3b\xf5\x30\xba\xb7\xd0\x10\x79\x11\x3f\x64\x2d\x09\xa4\x70\x63\x45\x74\x7e\xce\xfa\xa3\x97\x77\x35\x1e\xdd\x11\xc4\x72\x88\x6a\xc3\x8a\x7b\xfe\xc6\x95\x82\xa6\xa0\x06\x2b\x6d\xce\xb5\x3e\x83\x83\x23\xda\x4b\x51\xda\x2d\x8f\x71\xf3\xcf\xd3\xaf\xb2\xbc\xc7\xf5\x4b\xec\xd6\x72\xc8\x91\xdb\x66\x02\xec\xf3\x8d\xcc\xcc\x6d\x25\x30\xa5\xde\x9e\xd1\x49\x52\xde\x6f\x45\x9d\x2d\x89\xdb\xcf\xc4\x1d\x97\xc5\xed\x8b\x90\xdc\xd6\x98\x3d\xc1\xf8\x8e\xf1\x64\x1f\x80\xf4\x0b\x15\xaa\x40\x83\xef\xf7\xd5\x71\xf3\x9d\xb9\xc6\x24\xe4\x90\x50\x6d\x04\xd3\x6e\x66\x2b\xb0\xdc\xc5\x9d\x7e\xac\x64\xf6\xdb\x56\xea\x8b\x65\xe6\x19\xef\x11\x53\xb4\x91\x2b\xf0\x0b\x82\xea\xfc\x24\x55\xaf\x54\x88\x20\xda\x48\xa7\x9e\x49\x8a\xe8\x76\x6f\x42\x51\x97\x0c\x3f\xd0\xba\x8e\x49\x24\x09\x04\x92\x6b\xde\xbb\x4a\x48", 197, { 0x8e, 0x2a, 0x66, 0x4b, 0x0e, 0xe7, 0x3f, 0xaa, 0x95, 0xa8, 0x6c, 0x1d, 0xeb, 0x22, 0xdb, 0xd8 } },
|
||||
{ "\xa4\x77\x52\xb0\xda\x4f\x08\x52\x36\x26\x41\xa1\xe6\xc2\x55\x7f\xf1\x8a\x53\x87\xbc\xe0\x55\xf7\xa9\x19\xef\x39\xda\x15\xc1\x0c\x13\x80\x2c\x53\xbe\xa4\x21\x7a\x07\xe8\x15\x81\x27\xe8\x11\xa7\xbf\x32\xe5\xb3\x5a\x9b\x7c\xe1\x15\x3d\x4b\x68\x5b\x0e\xe4\xa4\xc8\x1d\xa7\xe5\x2f\x6b\x97\xd4\xb7\x63\x4a\x7c\x20\xf7\xfa\xfc\x23\x59\xba\xc8\xf8\x53\xc2\x97\xf1\x44\xeb\xed\x44\xb8\x36\x45\xe6\xa2\x86\xda\x92\x38\x6e\x12\xe8\x6b\x25\x88\xb3\x02\x96\xb4\x43\x52\x94\x39\xf9\x9c\x2b\xcc\xe1\x03\x12\xbc\x79\x28\x3c\x21\x90\x64\x8d\xa5\x4a\xa1\xaa\xea\x40\xd6\xe9\x97\xc4\x1d\x68\x02\x42\x72\x39\x7b\xc2\x0a\xbb\x33\x89\x4d\x04\xc8\xdf\x72\x7a\x6e\xec\xb6\x81\xbb\xbc\x39\x4e\x0f\x62\x75\xda\x9d\x38\x5b\xf3\x1b\x44\x0c\x6c\x02\xb6\x31\x75\x82\x8d\xf7\x05\x06\x5a\xaa\x73\x5f\x1d\xed\x25\x8f\x4b\x93", 198, { 0xfd, 0x93, 0x65, 0x5a, 0xe8, 0xb0, 0xde, 0x62, 0x06, 0x84, 0x76, 0x4f, 0x5b, 0x47, 0xf7, 0xd4 } },
|
||||
{ "\x5f\x35\xf1\x1e\x3d\x90\xf2\xd2\xbc\x31\x6c\x74\xf2\x42\x39\xa4\x5e\x6c\x92\xd4\x5a\x6a\xcd\xe4\xad\x28\x47\x5c\x3d\x97\x5c\x45\xe1\x10\x93\xa4\x55\x62\xd7\x94\x46\x7a\xe0\xff\x8e\xae\xb1\xf9\x7a\xa6\x3a\xb9\x46\xe7\x1d\x34\xaa\xfd\x8d\x57\x8d\x45\x53\xe1\xd8\x54\xeb\xdc\x66\x07\xcb\xb6\x17\x28\xc3\x00\x04\xba\x7f\xc2\xcc\xe2\x2a\x78\x0d\x72\x2d\xae\xef\x12\x15\x33\xda\x0d\x93\xfd\x47\xb6\x9c\x99\xb4\x75\xb1\x4c\xb1\x71\x39\xcc\x18\xdb\x0a\x94\x5a\xd5\x06\xe8\xf3\xfe\xe2\x65\xff\x9c\x02\x44\xe7\x64\x80\x2b\x34\xe8\x4c\xaf\x84\x9e\x6d\x6b\x99\x88\x66\xb6\x8f\x85\xb3\x03\x26\x34\x73\xda\x3d\x81\x1f\x6f\x60\xcd\x78\xdc\x78\xbe\x7f\x00\xa1\xa0\x9e\xf3\x19\x76\xe4\x25\x53\xa2\x6e\x12\x2b\x2c\xe1\xa3\x35\xb2\x13\x25\x2e\xed\xc9\xde\x94\xdb\x9b\x51\x51\x8e\xf4\x10\x93\x91\x36\x39\xb7\xf2\xfa", 199, { 0x05, 0x5a, 0x5c, 0xa0, 0xac, 0x17, 0x39, 0x3b, 0x11, 0x90, 0x08, 0xf7, 0x91, 0x12, 0x33, 0xbd } },
|
||||
{ "\x8e\x63\xf1\x75\x35\xb3\x43\xf6\x08\x8a\x03\x8b\x9a\x0b\x36\xc4\xc8\x20\xf9\x8f\xf7\x37\x4a\x42\xef\x0d\x6f\xb8\x53\xa2\x06\x92\xbc\x4c\xaa\x9f\x72\xe8\x3f\x56\xc6\x2b\xdb\x80\x0f\x16\x51\xf2\x3f\x88\x5b\x78\x21\xed\x63\xce\x31\x15\xee\xc8\x17\x1f\xa6\x91\xc2\x94\x02\x10\x1e\x90\x94\x66\x71\x1a\xef\x94\x57\x95\x32\x3a\x58\x50\x36\x7a\x23\x38\x50\xfb\x6a\xad\xc3\x09\x59\x71\xc5\xda\xb3\xbd\x2c\xec\x8c\x6e\xb5\x89\x9d\x5c\xf1\x6c\x47\xcb\xcd\x7e\x27\xfb\xbc\xb9\x52\xda\x83\x2e\x2d\xda\xa0\x21\xec\xdd\x58\x52\xa5\x4b\x5c\x57\x10\x46\x17\x24\xdd\xf5\x97\xad\xb2\xfd\x15\xa2\xc0\x0e\x22\x59\x01\x99\x71\xca\x10\x9f\x3b\xb3\xa4\xa5\x52\xdc\xaa\xc4\xc6\x75\xff\xdd\x2e\x9b\xc7\xe9\x94\xf9\x6d\x6e\xff\x8b\x37\x0d\x9d\x7e\x84\x38\x8d\x34\xa5\x02\x47\x63\x56\x0f\xa9\x5d\xd8\xaa\x9e\x6a\xac\xf5\x6d\x51", 200, { 0x09, 0x82, 0x5e, 0x9d, 0x4d, 0x7d, 0x4f, 0xf4, 0xcb, 0xc6, 0x86, 0xe7, 0xc4, 0xdb, 0x1a, 0xb4 } },
|
||||
{ "\xed\x3b\x9c\xf6\x4b\x62\x7e\x1d\xa0\x7c\x60\x4d\x30\x7c\x4c\xcf\x82\x05\x78\xd6\xd5\x5e\x4e\xb8\x41\x82\x19\x5a\x6c\x55\x49\xab\xe5\xf0\x63\x47\x20\x1d\x88\x3b\x0e\xde\x9f\xe8\x59\x28\x22\x00\x39\xad\x82\xae\xf6\xd7\x38\xd2\xfa\xd0\x69\x6a\x92\xbe\x35\x0c\x41\x0c\x9d\x8f\xc1\xe4\x0e\xca\x97\xb9\x8e\x74\x51\x00\x82\x2a\x5f\xfe\x19\x90\x8c\xbc\x59\x8f\x17\x18\xc4\xbc\x72\xf6\xa6\xd8\x96\x93\xfe\x74\x01\xfa\x07\xad\x4d\x8f\x62\x15\x6e\xc8\xe1\xb2\x88\xfc\xf2\x20\x6b\x53\xa6\xd1\xac\xde\x5d\x75\x61\xc0\x10\x75\x78\x89\x3b\x98\xb4\xa3\x65\xc9\x46\xe5\x4d\xf0\x04\x45\xb3\xfc\x48\xaa\xc0\x02\x68\xe0\x12\x7f\xcd\xa5\x68\xb9\xb2\xe0\xe7\x44\x7b\xf1\x07\xa1\xaf\x23\x1d\x01\x94\x3e\x85\x27\x66\x3a\x6b\x6b\x33\x0e\x36\xda\x56\xa5\x93\x7b\x8e\xf2\x19\xad\xba\x1a\x9e\xac\x33\xd0\x16\x32\xc6\xbf\x22\x3a\x4c", 201, { 0x67, 0xe6, 0x8a, 0xc1, 0xa4, 0x4c, 0x07, 0xb7, 0xd2, 0x7e, 0x82, 0x85, 0x0f, 0x8c, 0x27, 0xed } },
|
||||
{ "\x20\x3d\xdf\xe8\x6b\x7e\x63\xdd\x2a\x0a\x4c\x0a\xe8\x1a\xa9\x02\x49\xa5\x73\xcc\x33\xaa\x0e\x34\x2a\x1c\xef\xcc\xba\x69\x57\x82\x0d\xa9\x3d\xdf\x9c\x60\x49\xda\x02\xf0\xfd\x57\xec\x9e\xee\x3f\x2d\x3e\x30\x3c\xee\x7e\xd1\x11\x03\xcd\x7b\x95\x58\xe6\x3d\x4a\x8a\xfd\x63\x9e\x92\x84\x81\xbd\x9c\x9a\x8f\x11\xf6\x11\x2e\x57\x24\x1a\x09\x5f\x10\x8f\x57\x60\x5e\xdd\x7c\xf5\xde\x8c\xcf\xb8\x1b\x6d\x77\x7a\x10\x5f\x6e\x1c\xfa\xbd\xa7\x0d\x49\x68\x4c\x60\xb0\x6c\x20\x88\x5b\x51\x04\xb4\x40\x01\x95\xc1\x8f\x51\xf2\xe0\x43\x2d\x9b\xc6\xda\x65\x75\x89\x21\x0e\xea\x1e\x29\x96\x2d\x6c\x56\x68\x9b\x0c\x95\x38\x3d\xa0\xad\xeb\x6a\xcd\xaf\x26\x89\xd6\x88\x72\xf5\xd6\xb5\x09\xf9\x9a\x15\x40\xfa\x19\xda\x90\xb4\x90\x99\x42\x9c\x3e\x82\xb7\x65\xb9\xa9\x51\x9f\xec\x82\x02\x79\xae\x6c\x6f\xa7\xff\x64\xc0\x5f\xe1\xda\x07", 202, { 0xee, 0x3e, 0xeb, 0xd8, 0x7a, 0x38, 0xa2, 0x68, 0xcc, 0xf5, 0x88, 0x6a, 0xe0, 0x3a, 0xba, 0xac } },
|
||||
{ "\x7d\xd1\xa0\x4a\xc6\xe0\xff\x2e\x49\x73\xe4\x42\xe1\x93\x38\xe6\xd8\xf2\x4d\xd7\xa6\x7b\x74\x58\xd7\x94\xab\xfd\x0a\xf3\x73\x17\x15\x1a\xc0\xb7\x46\x70\x0a\x61\xc5\xfe\x81\x4f\x15\xc3\x5d\x5e\xb9\xb4\x53\x99\xf3\x53\x23\x61\xa7\xea\x4e\x36\x5f\x64\xe6\x24\x68\xc9\x7d\xcc\x19\x54\x3f\x0e\x33\x33\x1c\x50\x64\xdb\x1d\x6e\xe6\x05\xd8\x3e\x44\x48\xff\xbe\x3d\x54\x12\xdc\xc1\xc8\x35\xe2\x18\xb1\x1c\x7d\x22\xa0\x22\x68\xb9\x67\x79\xba\x32\x6f\x7c\xc8\x03\xb9\x21\xb8\x7e\x6f\x8a\xa3\xbc\x26\xba\x66\x95\xb3\x64\x06\xcb\xa7\xdf\xbd\x46\x68\x37\xa5\x7a\xed\x5d\x00\xe4\x15\x7e\x22\xb4\xa5\x71\xfb\x85\xdd\x49\x45\x47\xb5\x0a\x46\x3e\xb9\x79\x42\x23\x7e\x0c\x81\x68\xc0\x01\xf8\x99\x19\x8b\x97\xde\x60\x26\x2f\x9d\x9c\x0c\xfd\x3c\xa4\xc0\xd7\x04\x54\xc7\xf1\x21\x6e\x76\x4c\xc6\x0a\xe7\xbd\x6d\xbb\x05\x96\x3c\x40\xc7", 203, { 0x5d, 0x3b, 0xc3, 0x5e, 0xdc, 0x45, 0x22, 0x74, 0x96, 0x59, 0x61, 0x19, 0xb7, 0x97, 0x5f, 0x60 } },
|
||||
{ "\xf3\x83\xe4\x7a\xa2\x62\x73\x36\xb0\x88\xd9\x72\x8c\x16\x58\xb4\xdb\xa1\x65\x61\xd7\x56\x20\xb2\x64\x39\x6f\xc7\xb1\x86\xb6\xd6\x87\x38\x34\x7c\x32\xa7\xfd\x34\x08\x4c\x90\xe5\x9a\xa1\x14\x95\x77\x23\x34\x3c\x97\x79\x93\xb3\x6b\xaf\xee\xcb\x7f\x9b\xcd\x7a\xc8\x60\xe6\x31\x90\x10\x0e\x49\xfb\x6d\xdc\x9b\x35\xc8\xdc\x2e\x3a\x0b\x6d\x0b\x41\xd2\x38\x2d\xc6\xb3\x4d\x95\x32\x9e\xdc\x79\x2a\x60\x8c\x9c\x71\x42\x7b\xb9\x7b\xce\xd3\x19\x8f\xb1\x05\x44\x97\xbc\xa5\xd4\x87\x05\xe2\x65\x68\x2a\xa0\xa8\x00\xb5\x34\x97\x20\x9b\xbb\xc3\x8a\xdf\x17\xc8\x7c\x54\x88\xe3\xdd\x7f\xe3\x9a\x03\x9a\x71\x99\x1f\xb5\x66\x9d\x46\xf8\xfb\x89\x1c\x03\x2b\x96\x1f\x76\x08\xa8\x8d\x8c\xb7\xbb\xf3\xe2\x0e\x7c\x54\x56\xc8\xf4\xf2\x0b\x63\x5f\xbc\x88\x97\x1b\x53\x00\x72\xbc\xbb\xac\x14\x3c\x9b\x54\x05\x50\x30\xee\x2e\xd5\xd4\x5d\x7b\x69", 204, { 0x91, 0x24, 0x52, 0x7f, 0x19, 0x7f, 0xae, 0x81, 0x27, 0xa6, 0x98, 0xe8, 0xa1, 0xc3, 0x1d, 0xf4 } },
|
||||
{ "\x27\x5a\x0a\x17\xd7\x70\x10\x2a\x12\x21\x49\x22\x85\x26\x19\xc5\x0f\xd4\x44\x4c\x07\x9a\x47\xbe\x26\xa7\x51\x5b\x13\xa8\xe1\x2e\x8a\xaf\xfd\xc6\x28\x2f\x0c\xfe\xd5\x24\x51\xf7\xce\x50\x04\x27\x4d\x9f\x0e\x8b\xd8\xac\x62\xf8\x23\x5c\xf3\x8f\xa3\xa8\x55\x4f\xb1\x79\xf4\xc5\x56\xac\xeb\xde\xb9\x35\x82\xdd\x22\x5f\x47\x67\xaa\x31\xc7\xbb\x82\xed\xe9\x00\xdc\xb2\xe8\xb7\x79\x41\xeb\x50\xd0\xdc\x43\xd8\xd8\x4a\x40\xcf\x72\xf8\xb0\x18\x76\x39\xf5\x09\x59\xae\xc2\xa2\x78\xc1\x72\xdb\x03\x4b\x05\x16\x89\x56\xb7\xb4\x1b\xfc\x3f\xc4\x20\x6e\xa1\xd5\xb5\x11\xb0\xec\xbe\xc2\x24\x91\x8e\x3a\x53\x04\x2f\x8d\x90\x8d\x4e\xcd\x1d\xf1\xc6\xcb\xcd\x00\xc7\xfd\x3b\x4c\xa3\x7b\xa1\xf4\x35\x24\x56\x9e\xee\xdd\xe6\x83\x7d\xf9\xcf\xa3\x1a\xb5\xd6\x1a\x70\xda\x04\x8b\x25\x85\x41\xb8\x07\x03\x8b\x34\xd4\xd6\xd3\x2f\xa6\xd5\x74\x71\xf9", 205, { 0xaf, 0x74, 0x5b, 0xa6, 0xbe, 0xb5, 0x95, 0xdd, 0x3a, 0xa9, 0x3e, 0x1c, 0x12, 0x8f, 0x4a, 0x81 } },
|
||||
{ "\x6f\x51\x62\x5a\x10\x89\x45\xae\x9c\xda\x85\x1d\x18\x8f\x28\x99\x68\x27\x60\x0f\x33\x84\x40\x28\xe2\xcc\x8c\xbc\xc8\xe0\xa9\xd4\x5c\x77\xb3\x5a\xa1\xd6\xad\x5f\xa6\x2e\xd3\x09\x29\x92\x0c\x17\x57\x93\x7c\x13\xaf\x7a\x35\x13\x04\x21\x0d\x2b\xa1\x6e\x8a\x72\x86\x6d\xfa\xaf\xd1\x09\xa0\xa1\x38\x67\x08\xe8\xb3\xe0\x7c\x93\x37\x98\x8f\x47\x9c\xbf\xd6\x08\xa0\x64\xb7\xa7\x04\xf1\x59\xc8\xd4\x47\xbb\x8f\xc4\x77\xe0\xe7\xb6\x19\x28\x6f\x58\x4d\xbb\x01\xeb\x4c\x1e\xdf\x1e\xa9\xe7\x7c\x18\x2a\x8d\xe5\x95\x3d\x59\xca\x28\x19\x79\x2d\x9e\x72\x33\xa6\x83\xd8\x37\x50\xbe\xad\x0d\x54\x57\xc1\xad\x10\x5a\x8c\x2d\xe3\xd3\x07\x95\x97\xf8\x27\xce\x6c\x66\xf7\xb9\xbd\x84\x51\x5d\x51\x04\x38\x38\x41\x88\xd5\xb6\x81\x61\x0d\xbf\x0c\x72\xbb\x6b\xb0\x33\x8f\xd1\x73\xd1\x82\xfd\xa1\x73\xf5\xff\x73\x98\x65\x20\x5e\x9c\xcd\x30\xf5\x5a\x99", 206, { 0x69, 0x2b, 0x76, 0x76, 0x70, 0x75, 0xc8, 0x00, 0xd0, 0x62, 0xd9, 0xc8, 0xd8, 0x37, 0xe6, 0xe6 } },
|
||||
{ "\xfb\x7b\xea\x42\xda\x09\x8b\x8a\x65\x58\x9c\x56\x46\x2c\xc5\x23\x29\x5e\x33\x26\xcf\x84\x00\x04\x42\x3e\xb0\x2b\x23\x20\xd7\xcb\x1f\x37\xd9\x75\x80\x3a\xca\x4e\xe0\x4f\x73\xef\xf8\x76\x76\xdd\x96\x96\x89\xa0\xad\x22\xde\x82\x86\x68\xa3\xe6\x15\x76\xa5\x42\x66\xa9\x10\xba\x36\xd3\x51\x5a\x9e\x08\x1c\xf0\xea\x06\x89\x84\x88\x3e\x59\x75\x1c\x83\x57\x32\xb1\x4e\xda\x91\x09\xab\x67\xcf\x15\xc4\x73\x25\x80\x08\x45\x03\x65\xf8\xfa\xec\x22\x8e\xa3\xed\x44\x4a\x89\xbb\xa1\xda\x90\x68\x85\x65\xb9\xc2\x04\x74\xc1\x48\x6f\x7d\xe7\xca\xe1\x0e\xcb\x9c\xf9\x93\x72\x76\xa2\xc4\x66\xeb\x0d\xad\xfa\x84\xc0\x5b\xab\x79\xc8\x20\xa2\x0b\x0a\x84\x57\x81\xb8\xc8\x4f\xbc\xdf\x17\x05\x79\x1c\x4c\xe7\x23\x6f\x5a\x77\x53\x27\x5c\x92\xe5\xfd\x3a\xce\xb8\x3d\xf4\xfc\x01\x1f\x8e\xcd\x4c\x34\x99\x90\x11\xfc\x59\x19\xef\x94\x98\xbe\x88\x8c\x06\x7b", 207, { 0xdc, 0x06, 0x1a, 0x7c, 0xe0, 0x3b, 0x42, 0x40, 0xac, 0xe3, 0xdd, 0xf7, 0x63, 0xae, 0xaa, 0x36 } },
|
||||
{ "\xf8\xd7\x4b\x35\xf2\xdc\xab\x1b\x79\xa9\x55\x29\x39\x47\x48\xc6\x80\x28\xe3\x8e\xdc\xbd\x07\x2a\x51\x24\xea\x5a\x37\xff\x7b\x14\xae\x60\x6d\xc6\xbf\xe0\xe3\xb8\x11\xcf\xb6\x8d\x45\x85\x66\xe8\xee\xd7\x9a\x2c\x30\xa5\x55\x5b\xf4\x91\xb8\x20\xc5\xca\x6e\xe8\x4a\x06\xb7\x2a\x60\x8e\x15\xc8\xd4\x73\x8d\x8d\xba\xde\x9a\xd6\x6c\x85\xb4\x4e\x22\x3a\x77\xd2\x2b\x9d\x74\x73\xc6\xf2\x91\x99\x9f\x0d\x1d\x44\xe9\x6a\x74\x6e\x14\x59\x4b\x8d\x2c\x56\x99\x35\xce\x77\x23\xd9\xc7\xfe\xa2\xb1\x4a\x0e\x92\xb8\xce\x7b\x9a\xcd\x82\xba\x93\xf9\x6e\xf7\x36\xd0\x27\x46\x67\xf0\x2e\xf1\x18\xa7\xe7\xf0\xdb\xb1\x31\x76\x08\x1e\xa6\xa8\x87\x52\x70\x68\x3b\x26\xc6\x50\x0c\x2d\x02\xbb\x8e\x11\x61\xfd\x53\x1b\x56\xb2\xca\xd1\x8b\x34\xd2\xb9\x75\x26\xdf\x3c\x92\x2d\xc7\xa6\x42\xbf\x2a\x4a\x40\x13\x7c\xc2\xbb\x38\xb1\x54\x15\x42\x83\x71\x37\x9f\x63\x57", 208, { 0x90, 0x71, 0x3e, 0x92, 0x18, 0x0b, 0x7f, 0xec, 0xf7, 0x44, 0x3a, 0xd3, 0x5c, 0x05, 0xb4, 0xfe } },
|
||||
{ "\x8f\x87\xfa\xd6\xa7\x92\x5a\x2f\x63\x63\xc6\x17\xd7\x82\x1a\xdc\xc2\x48\xd8\x9f\xab\xf3\xd1\xbf\x97\xd9\x6d\x57\x64\xba\x97\xdd\xc6\x2e\x47\xeb\xdb\x3d\xad\x1a\x6c\x0d\xf7\x0a\xc2\xb6\xbf\x7f\x23\x32\x14\xa6\xe8\x70\x24\x75\x3c\x87\x83\x30\x73\x07\x1a\x07\x04\x6c\xaf\xdd\x25\xac\x0c\x23\x01\xf0\xcf\xe3\x99\x5f\xce\xd9\x34\x15\x24\xbb\x84\x32\xdc\x9a\x57\x0f\x39\x60\xf6\x8c\xa0\x79\x1e\x85\x23\x8f\x98\x63\xab\x6d\x77\xce\xc1\x05\xee\x80\xf9\x8d\xcb\x35\xfb\xc3\x94\xbf\x2f\x52\x3d\x35\x05\x4d\x83\x4b\xde\xd8\xe7\xbd\x9a\xe6\x4a\xe6\xbf\x1c\x22\x6d\x42\xd4\x56\x1e\xf6\x3f\xbc\xd7\x8e\xa2\x2c\x99\x50\xc1\x41\xbe\x59\x59\xac\x4a\x87\xc6\x34\x59\x06\xc5\x4e\xb8\x7a\x54\x54\x90\xc6\xb6\x65\x3d\x77\x92\xda\x3e\xd1\x3b\x60\x45\x74\x0b\xb7\x6d\xa9\xe8\x06\x8b\x4f\xe8\xd8\x9c\x5c\x11\xb7\x5e\x12\x39\x63\xfc\xc1\x0c\xaf\xe1\x32\x2c\xf9", 209, { 0x72, 0x27, 0x02, 0xd5, 0x86, 0x5b, 0x0b, 0x2b, 0x77, 0x13, 0x3a, 0x71, 0x39, 0x5b, 0x88, 0x5d } },
|
||||
{ "\xae\xb7\x73\x44\x46\xcd\x54\xf4\x06\x6b\x5f\x25\x12\xea\xe3\xa8\xcb\x90\xad\x9a\x5c\xba\xef\xa3\x74\xa6\x3c\xc8\x0e\xda\xb0\xee\x6b\x35\x2d\xec\x22\x90\xc0\x4b\x4e\x11\x21\x9d\xe5\x0c\x59\x77\x28\x95\x7e\x0c\x36\xa6\x9a\x67\xbc\xe9\xaa\x44\xc7\x24\xc2\x8c\xba\x3f\x4e\x6c\x5b\xf2\x73\x11\x07\x0f\x93\x01\x06\x69\xef\x19\xf9\x60\x68\x1f\x70\x0a\x5e\x03\x98\x00\xb9\xb7\x11\xc2\x06\xa8\xde\xc8\xb9\xd7\x76\x26\x91\x99\xf7\xda\x19\xe7\x7a\xb6\x4a\x63\x81\xe4\x4e\xe8\x8d\x1b\x5f\xcc\xcd\x5d\xce\xb5\xf0\x6a\x20\x14\x1c\xc5\x52\x43\xf7\x60\x3e\x37\xe2\xe6\x16\xe2\x45\xa5\x0c\x28\x05\x17\x14\x7b\x12\x0b\xc1\x15\x1e\x75\x4c\xd1\x68\xce\xb4\xa7\xb6\x29\xff\xc2\x61\xd4\x9e\x40\x8a\xa7\xee\x85\x6b\xec\xdb\x3c\xc8\xeb\x9f\xec\x83\x10\xa8\x32\x4f\xbb\x98\xa1\x7d\xa4\x66\x33\xf2\xe9\xa2\x6a\x3a\xb6\xd5\x07\xb5\x90\x06\x66\xef\x3e\x59\x74\x0e\x54", 210, { 0x00, 0xbf, 0x87, 0x36, 0xd5, 0xe8, 0x54, 0x2f, 0x00, 0xca, 0x28, 0x9c, 0xe1, 0x28, 0xe5, 0x7e } },
|
||||
{ "\xd3\x4e\x64\x5d\x38\x78\x24\xa4\x15\xb7\x32\x9f\xda\x8c\x13\xf9\x1f\x4d\x04\x3b\x07\xe1\x26\x16\xc2\x17\xd6\x4f\x2c\xa4\x1b\x47\x93\xb7\x39\x26\x96\x3b\x62\xa4\x28\xa8\x8c\x74\xb4\x86\x5e\x4d\x5b\x80\x44\x95\x58\x21\xa2\xac\x85\x2d\x24\xd3\xf7\x9e\x34\xb8\xc3\x3a\x85\x9f\xe4\xcd\xcc\x2e\x35\x09\x8f\xd5\x98\xf6\x15\xd8\x39\x17\x7d\xfa\xed\x1b\xeb\xc8\xb4\x3c\xdd\x7f\x5d\x38\x9c\x9b\x49\xea\xcd\xfd\x47\x85\x27\xb7\x9f\x6c\x3f\x77\x2a\xb0\x7f\x8f\x9e\x26\x35\x9d\xe8\x24\xc7\xdc\xb2\xd9\x05\x05\x04\x46\x97\xe3\x06\xdd\x95\x72\xe3\xb4\x35\xb3\xca\x66\x9f\x0f\x0e\x86\xdd\x65\x6e\xc1\xee\xb2\x6e\x8f\xf9\x5c\xe4\x95\x9f\x1b\x8f\x9b\x69\x84\xe0\x25\x61\x34\xdd\xb0\xbc\x95\x1b\x8b\xb4\x50\xe9\x4f\x74\x4f\x8c\xfc\x2d\x6d\xa4\xb1\x46\xbd\xad\x07\xb0\x74\xa1\x0b\x57\x74\xbb\xd7\xb4\x76\x57\xcc\x7f\xd2\xf5\x6e\x82\xee\x5d\xdc\x89\x41\xdc\xea\x76", 211, { 0xfa, 0xb4, 0x08, 0xeb, 0xfa, 0x54, 0xe3, 0x20, 0xe9, 0x99, 0x17, 0x29, 0x29, 0xf5, 0xeb, 0xb1 } },
|
||||
{ "\x03\xac\xdd\x71\x73\x72\xc2\x3c\xc4\xe0\x6b\xa4\xa5\x7b\x07\x13\x6c\x77\x5d\x43\xde\xbe\xa5\x0d\x9d\x0f\x03\x5f\x2e\x43\xa1\x4c\xa6\xab\x67\x3e\xf1\x96\x5a\x47\xbf\xef\x8e\x94\x0c\x02\xc9\x02\x4a\x5f\xb6\xcb\x2c\xd7\xc3\x59\x11\xa3\x98\x3b\x0c\xa5\x33\x35\x8c\xc6\xa4\x71\xad\x7e\x62\xd4\x1a\x72\x49\x6c\x9c\x37\x31\x05\x44\x34\x2c\xdb\x31\xa6\x5b\x69\xff\xbe\x6d\x60\xcc\xe5\xb6\xb3\xe8\x1f\xe8\xcf\x18\x8d\x70\xe8\x87\x0c\x6f\x6f\x4a\xfc\x53\xa0\x8e\x1b\x12\x37\x61\x8f\x03\x42\x19\x02\x59\x12\x65\xe7\x3c\x4b\xee\xdc\x85\x1b\xa9\x28\x16\x87\xbc\x63\xd4\xe1\x0a\x35\x43\x56\x5d\x36\xbc\xa3\x2f\xf5\x4d\xe8\x15\x15\x2d\x95\xc9\x91\xda\x81\xd2\x1f\xd1\x19\xd2\xb2\xea\xb5\x6c\x1a\x4d\x06\xcf\xc7\x14\xac\xe4\xab\x7f\xe4\x10\x3d\xce\x5f\xa6\x99\xbf\x2d\xec\xc4\xa4\xd8\xc8\x0e\x20\x8e\x08\x90\x7e\x76\x4b\xd5\xad\x23\x8e\x95\xdc\x26\x57\x9d\xae\xbd", 212, { 0xe8, 0x18, 0xd0, 0x40, 0x9b, 0xb0, 0x23, 0xd1, 0x12, 0xb7, 0xa8, 0xcc, 0xdb, 0xb8, 0x5e, 0xb0 } },
|
||||
{ "\x78\xca\x1a\xaa\x80\x33\xe3\x1f\xc4\x67\xae\xd5\x05\xcb\xc5\x3c\xbe\x26\x67\xcd\x0d\x38\xc9\x7b\x3b\x84\xae\x48\xea\x2f\x9e\xf3\xda\x01\xc6\xce\x57\x88\x6b\xae\x43\x5b\x0c\xfd\xbc\x7c\x14\xe9\x69\xd7\x39\xbf\x66\xe7\x74\x52\xc9\x78\x9d\x95\xd1\x87\xa2\x49\xab\x45\x63\xcf\xe0\x3a\x2e\x1f\x5e\x87\xd2\xd1\x20\x44\x62\x59\x7d\x08\x88\x50\x0b\x86\x83\xed\x2d\x54\xbe\x92\x40\xc7\x0e\x83\x5e\xfb\x88\xb1\xcd\xef\xfd\xb5\x08\xcd\x14\xd8\x67\x46\x02\x4e\x6d\x1c\xe8\x84\xae\xb9\xc8\x8f\x5b\xfd\x25\xc3\x6c\x15\x37\x65\x68\x86\xc8\x78\xd4\x4a\xae\xb3\x36\x11\xe5\x94\xc4\xa8\x48\x8e\xae\x77\xec\x5e\x05\x24\x1a\x7c\x46\x56\xe6\xac\x87\x94\x70\xb3\x3d\x4b\xb7\x27\xa8\xee\x15\x60\xdc\x38\x5b\x8b\x6c\x8d\x89\xdd\xb4\x7e\x2a\xe3\xc3\x6c\x4a\xf8\xe3\x43\x15\xd1\xc7\x68\x0e\x32\x51\xae\xe8\xc3\xfd\x81\x05\xfd\xed\x25\x88\x3f\x91\x19\x19\xfd\xf2\x95\x35\x17\x9c", 213, { 0xc0, 0xa9, 0x36, 0x91, 0xae, 0x59, 0x54, 0xe1, 0x90, 0xbf, 0x8f, 0x65, 0xc7, 0x08, 0x89, 0x62 } },
|
||||
{ "\x33\x2e\x48\x26\xaa\xc6\xb5\x5f\xb4\x64\xa5\x17\x12\xf1\x50\x87\xa6\x52\xd0\x5e\xbd\x82\x34\x69\x6f\x4a\xb4\xdd\x1f\xa0\xfe\x44\x1e\x9a\xaf\x02\x6c\x0d\xdd\x83\x9e\xc7\xd1\x04\xdb\x64\xd2\xfa\x00\xd1\x1c\x22\xe4\x5b\xf0\x26\xb5\x73\xc5\xe9\x81\x00\x9c\x70\xd1\x61\x71\x6c\x70\xfe\xcd\x68\x49\x89\x78\x8b\x6e\xd7\x4c\x0b\x35\x55\x26\x2f\x7d\x28\xf5\xfe\x0e\xe5\xf4\x89\x1e\xea\xf4\xd2\xf0\x57\xd2\x58\x97\xac\x09\x40\xd9\x01\x60\x21\x2f\xdc\xc4\x6c\xe8\xb2\x30\x77\x6c\xfd\xc8\x24\x9e\xf6\x06\x32\x5b\xf0\x0b\x20\x20\x51\x17\xb9\xc8\x2d\x14\x41\x72\x80\x4d\x3a\x81\x08\x3c\xd3\xbd\xbd\x80\xee\x96\xee\xed\xcd\x89\xfa\xbe\x58\x9c\xa7\xe5\x0d\x03\x22\x83\x84\xe5\x93\x74\x9e\x38\x5c\x01\x4a\xc8\xef\xb9\xf3\x57\x49\x59\x89\xdf\x0f\xe8\x2b\xf3\x43\xe0\x6e\x43\xa3\x86\x4d\x3e\x9e\x5b\xad\xd2\xf4\xab\x8b\x4f\xe9\x42\xc4\x69\x25\x3e\x80\x5c\x2b\x00\x3c\x2a\x74", 214, { 0x60, 0x47, 0x87, 0xbd, 0xbc, 0x4a, 0x9d, 0xcc, 0x51, 0x19, 0xbe, 0xfd, 0x54, 0x82, 0x87, 0x82 } },
|
||||
{ "\x3c\x73\x00\x28\x30\xe9\xb7\x78\xf2\x94\x76\x9a\xe1\x27\x74\x62\x3d\x3c\xdb\x7a\xd3\x1d\xc8\x3e\xd1\x2e\x6f\x36\xb8\xfb\x5c\x31\x6f\xda\xd4\xfa\x73\x3d\x5a\xba\x2c\x96\x4d\xea\x5b\xe7\xae\xf2\xb0\xe5\x00\x63\x78\xc8\x48\xce\x74\xb2\x34\x3f\xc5\xb9\x58\x59\x03\x93\x93\x0f\x6c\xdd\x90\xfc\x39\x08\x69\x60\x0c\xe0\x65\xb8\x86\xba\xe2\xf9\xf6\x3a\x4e\x68\x2c\xbe\x4f\x19\x6b\x6b\x03\x02\x7c\xd2\x61\xbb\xdf\x3e\xbe\xd4\x1d\x9c\x6c\xd2\x39\x08\x7d\xc8\x45\xf0\xa5\x8f\x10\xe7\x3d\xa2\xfd\x08\x64\x98\xef\x05\x40\x3e\x60\xcb\x62\x50\x91\xd3\x48\xd4\xdc\x08\xfc\x14\x25\x50\xd9\x36\x6f\xba\x6d\x79\x8a\x42\x7a\x0e\xea\x43\x17\x91\x94\x7a\xf4\x22\x31\xb2\xba\x25\x45\x12\x91\x92\x79\xff\xbb\xf9\x14\xaf\x5d\x16\x88\x4c\x5e\x0c\x29\xc0\x68\x42\xf8\x23\x0c\xd7\x9e\xbf\x02\xc3\x74\xbc\x8e\x8b\xbf\x6d\xfd\xa0\xf9\x35\x4f\x55\x4a\x17\xef\x7c\x16\xda\x9d\x9c\xb0\xd5\x6c", 215, { 0x9f, 0x07, 0x30, 0xc6, 0x81, 0xe5, 0xb3, 0x2c, 0x28, 0x8e, 0x78, 0x51, 0x93, 0xde, 0x42, 0x5f } },
|
||||
{ "\xd0\x2c\x5c\xe7\x3f\x51\xc7\x4f\x33\xad\x1b\x00\xd8\xc3\x58\xf2\x93\x60\x5f\x5a\xfd\x0c\x7d\x70\x7b\x9b\x98\x4c\x7b\xe3\xf4\xea\x4d\x87\xa3\x4c\x9b\xf2\x87\xbe\x87\x60\x05\x35\x60\x16\x48\xd1\x00\xb2\x2f\x82\xc4\x9d\xd4\xc6\x29\x9c\xba\x90\x00\x86\x92\x45\x4d\x10\xaa\xdf\xc2\xc4\xf3\x34\xd3\x10\xad\x51\x76\x7b\xb1\x00\x79\xf2\x5b\x6a\x7f\x41\x12\xd5\x98\x9d\x75\x8d\x7c\x5e\x23\xe1\x64\xc9\x27\x45\x86\x0b\xfe\x95\x2b\x43\x47\x79\x6e\xb6\x07\xe3\x93\x26\x95\xb5\x01\x3c\x28\x80\xdd\x22\xfb\x68\x45\x2d\x1a\x23\x26\xb8\xcd\x20\xbb\x0c\x9e\xc4\xa2\x7b\x07\xcf\x9c\x8c\xbd\xdd\xe1\x50\x93\x09\x1e\xd3\x0d\xac\x0d\xae\x82\x43\xae\xba\xec\x6f\x27\xdf\x50\x15\x35\x0a\xc4\xa5\x4e\x3d\x22\x78\x55\xc0\x48\x53\xf9\x75\x08\x09\xab\x49\xb3\x3c\x3a\xc6\x3d\x43\x0c\xc6\x0d\x28\xfb\x42\x64\xc8\xc9\x49\x67\x1d\x42\x0c\xca\x99\xed\x16\x1b\xa8\x6e\x98\xa8\x58\x7b\xe2\x0f\x15", 216, { 0xa6, 0xa5, 0x85, 0xaa, 0x5a, 0xae, 0x5b, 0xdc, 0xc7, 0x29, 0x53, 0x55, 0x13, 0x71, 0x93, 0xef } },
|
||||
{ "\x79\xee\x60\x8d\xb2\x17\xf0\xb2\x35\xe7\xbd\xde\x4b\x0d\x79\x10\x91\x6d\x35\x54\xb7\x52\xab\x41\xd4\xbf\x28\x9c\x63\xe3\x14\x1b\xde\xaa\x1f\x43\xf5\x70\x0a\x72\x6b\xd0\x0f\xf9\x8e\x9b\xef\x61\x51\xe5\x96\xcf\x07\x39\x6c\x82\xbe\xec\x3a\x78\x36\x8f\xb7\x30\x7d\x7e\xaf\x8b\x28\x95\xcf\xcc\x2f\x02\x0f\xbe\x66\x36\xbc\xf5\x94\xf6\x21\x2c\x32\x8e\xd1\xce\xc1\x24\x94\x90\xc8\x2a\xec\x3b\x69\xed\x42\x87\x9f\x4b\xb2\x23\x17\x81\x70\xd2\xa7\x22\xd5\xaf\x6f\x24\x0a\x91\x8b\x15\x50\x89\x72\x6b\xe9\x88\xee\xf8\xa6\x1e\xb8\x7c\x0e\x5d\xaf\x55\x28\xdc\xb5\x51\xe6\xd7\x26\xa4\x2e\x74\xf6\xf5\x85\x20\x66\x92\x5a\x18\x63\xc4\xed\x04\x7b\x3e\xda\xbd\x7c\xaf\x46\x2f\xab\x77\xa5\x5a\x9e\x76\x25\x73\xb7\xff\xba\x27\x3d\xeb\xc7\xff\x18\xca\x66\xde\x29\x35\x54\xa8\x44\x3f\x7c\xfd\xcb\x0a\x1e\x23\xe8\x75\x9c\x02\x66\xf3\xe1\x48\x2d\x77\x6e\xad\x58\x8b\x02\x51\xf5\x80\xe6\x41\x58", 217, { 0xf2, 0xd7, 0x83, 0x16, 0xed, 0x22, 0x8c, 0xde, 0xa0, 0xe8, 0x95, 0x2a, 0x6c, 0x79, 0xc1, 0x12 } },
|
||||
{ "\xc0\xd2\x18\x1c\x3f\x7f\xc2\xb7\x10\xca\x5c\xb9\x14\x82\x37\xa1\xcd\xce\xfc\x5c\x50\x3e\xe9\x5b\x59\x6c\x39\x4f\x79\x4e\xa2\x84\x6a\x1c\xf8\xd7\x83\xd8\xef\x56\x46\x7f\xfd\x72\x17\xca\x5e\xe3\x08\xa1\x31\x19\xcf\x1d\xc0\x5a\xd9\x38\xdd\x7c\x77\x14\x67\x41\x37\xe4\xec\x4a\x4e\x7b\x68\xba\x30\x6f\x2c\x68\x42\xea\xda\xc0\xa7\x0d\x8d\x37\x37\x00\x15\x68\x8e\x9a\x60\xd0\x40\xaa\xf4\x23\x2a\xe0\x98\x48\xe4\x5b\x13\xf8\x52\xd0\x0c\xee\x5a\x53\x10\xcc\xb0\xc6\xb2\x8a\xcc\xdb\xcd\x9b\xfd\xc7\xe5\x9e\x97\x85\xac\xbd\x48\xc3\xa0\xa6\x89\x6d\xd1\x24\x30\xd5\xc1\x59\x22\x7c\x64\x9a\x25\x80\x46\xe7\xd3\xa1\xcc\x05\xaa\xf1\x92\x3a\x41\x18\xf4\xa5\x95\x41\xa8\x37\x82\xa5\x88\x52\x4d\xb2\x6e\xfc\x5e\xd7\x39\xc0\x0b\xef\xec\x21\x8f\x47\xf5\xbc\x19\x4e\x8a\xf9\x01\xd8\x2f\x6d\x15\x0e\x55\xd0\x12\xf6\x1c\x96\x2e\x9b\x39\x2c\xd2\xd9\xf3\xd0\x65\xc7\x47\x0d\x44\xc1\x2c\xd2\xce\x10", 218, { 0xdf, 0x39, 0x06, 0xcc, 0xa4, 0x24, 0x46, 0xc5, 0xa8, 0xd7, 0xba, 0x98, 0x18, 0xc2, 0xff, 0x44 } },
|
||||
{ "\xf1\x2e\x9b\x39\xc2\xab\xcc\xdf\x49\x44\x7d\x55\x70\x03\x57\xc4\x45\x3b\x43\xf5\xf7\x5f\x39\xbc\xfd\x7e\x36\x02\x56\x5c\x4c\x6d\xeb\x2e\xd3\xae\x10\xf1\xbd\x66\x29\x67\x07\xb6\x69\xaf\x4c\x62\xb6\x80\x74\xa1\xa9\x02\x89\x83\xb1\x49\xaa\xff\x57\x6e\x18\x98\x9c\x4c\x6e\xac\x7e\xd4\xed\x59\x99\x0e\xf5\x0c\xeb\xac\x90\xa7\xb0\x4c\x29\x4e\x6c\x4b\x5a\xcf\x07\x40\xe3\xac\x12\x1c\xb6\xc5\x27\xdc\x2e\xa6\x6f\xe8\x60\x6b\x3e\x0c\x8a\x4c\xd8\x10\xa9\xc9\x57\xf5\x26\x73\xa4\xcf\xb0\x54\xa3\x3a\x25\xfc\x6b\x7a\xa9\x29\xb2\x33\xda\x12\x48\xc1\x1a\x50\xba\x35\x0b\x6a\x17\xed\x19\xfb\xcf\xcf\x30\x82\xb6\x22\x8f\xc6\x28\x08\xb4\xe4\x47\x9c\x77\xf6\x60\xa4\x33\x62\x6c\xf3\x1f\xbc\xb2\x5e\xba\x59\x8a\x58\x65\x71\x3c\x2d\x0a\xf0\x06\xd8\xfa\xd9\x3c\x81\xd5\x57\x8a\x96\xa2\x62\x55\x84\xff\x0a\x40\x12\x72\x64\xcb\x5a\xdd\x0e\x15\x66\x10\x5f\xc2\x63\x79\x30\xf7\x84\xf6\x42\x82\x76\xcb", 219, { 0x9a, 0x70, 0x70, 0xa9, 0xb4, 0x61, 0xe5, 0x09, 0x0c, 0xb2, 0x96, 0x1f, 0xf2, 0x98, 0x95, 0xe3 } },
|
||||
{ "\x4a\x17\x7b\xaf\xa0\xb6\x26\x01\x80\x28\xb2\x18\xfa\xa7\xfe\xb7\x7c\x9d\x29\xa0\xfa\x85\xc6\x3f\xb7\xee\xbc\x87\xb3\x9e\xbd\xdb\xb1\xd3\x61\x22\xe4\xa5\xde\xfd\x35\x87\x66\x15\x34\xec\x1d\x8d\x98\x06\xb6\x97\x74\xa9\xa9\x22\xf9\x4e\x13\xb1\xe2\x34\x29\x47\x80\xa1\x5a\x7e\x62\x47\x01\xb8\xa0\xc1\xc4\x6c\xc4\x3c\x8c\xa2\x56\x33\x21\x7a\x03\x52\x60\xe6\x69\x7c\x1c\x77\x82\xe8\x8f\x55\xaa\x66\x7b\x49\x4e\xc0\xe2\xf4\x33\x3b\x5e\x23\x60\x3d\x1e\x3a\xaa\x08\x7d\xcc\xda\xa4\x40\x4d\x7c\xdb\x6c\xdf\x47\x5e\xc2\x48\x24\x06\xd9\x05\xdd\x34\xd6\x78\x63\x59\xc9\x3c\xbc\x91\xa7\x99\x87\x6a\xe0\x13\x2d\xc4\x9d\x1d\xa6\xd0\x98\xeb\xe5\x3a\x97\x65\xe1\x63\x86\x37\x41\xc7\x30\x05\xa4\x7e\x9a\xbc\x8a\xde\xfc\x04\xe2\x3d\x5d\xd1\x30\xd4\xc9\x19\x5a\xbf\x32\xa0\x10\x20\xe1\xee\xd7\x64\x97\x63\xb0\x9e\x44\x61\x69\x0f\x63\xa7\x7f\xc7\xf0\xbe\xae\x64\x07\x8b\x18\xf9\x1b\x05\x0d\x0b\xcf\x01", 220, { 0x8a, 0xd2, 0x4d, 0x87, 0x81, 0x67, 0x56, 0xc3, 0xa6, 0x51, 0x29, 0xe9, 0xa8, 0x9f, 0x1d, 0xc2 } },
|
||||
{ "\x7d\xb5\x74\x2a\xf7\xeb\x20\x0c\x5d\xdb\x67\x4f\x27\x6f\xb9\x00\x50\xef\x58\x0b\xe0\xc4\xf3\xc5\x17\x57\xe4\xa6\x33\x18\x03\x14\xdf\x9b\x25\x5a\x38\xdc\x35\xb7\x7c\xa3\xec\x93\x51\x03\x30\xcd\xb0\xfc\x07\x2f\x6c\x40\x36\x03\x63\x13\x7a\xbf\x3f\x4b\x62\xdb\xe9\x77\xc7\xc3\x8c\x1c\xe9\xe8\x41\x1a\x28\xf1\x5c\x2e\x5c\x10\x52\x91\xd1\x6f\x46\xbd\xe2\xc8\x2f\x4f\x30\x14\xa6\x08\x80\x5b\x51\xed\x2f\xaa\xe8\x8f\x52\x23\xe1\x65\x6e\x2e\xbc\x55\xd0\xce\xed\x51\x8b\x0e\x61\x1e\x0c\x99\xae\x30\x5b\x69\xdc\xb2\xf0\x98\xca\xa2\x30\x52\x3f\x18\x83\xec\x8e\xa6\x12\x0d\xe5\xdb\x22\x0a\x32\xe2\x08\x50\xb1\x48\xc8\xfa\x17\xdb\x4e\x83\x54\xad\x48\x95\x09\x38\x9e\x00\x86\x9b\x8f\xc6\x7e\x03\x69\x53\x4a\x25\xe5\xca\xd6\xe7\x1d\x7a\x2c\x1e\x2a\x6f\x9b\x72\x5e\x25\x83\x5e\x1b\x58\xc0\x54\x4e\xf7\xb1\xfd\x8c\x36\xe4\x9e\xc7\xc2\x60\x96\xac\x10\x8e\x04\x9d\xcf\xc4\x85\x46\x7c\x6f\x1b\xde\x13\xdd", 221, { 0x11, 0xa3, 0xea, 0x6a, 0x2d, 0xee, 0x6c, 0xd5, 0xd4, 0xd9, 0xde, 0x9e, 0x00, 0x76, 0x0c, 0xd3 } },
|
||||
{ "\x29\xfc\xe3\xa5\x9b\x13\x7b\xb3\x22\x8c\xc0\xf4\x9d\x7e\x20\x9a\x93\x0d\xe1\x0c\xdd\x5c\x93\x6e\x61\x30\xa4\xc8\xf8\x22\x12\xd5\x71\x80\x3b\x6b\xaf\xc2\xd0\x81\xed\xa4\xe8\xe2\x22\xe4\x31\x6d\x80\x9a\x41\x06\x16\x2f\x0a\x1d\x95\xfb\x6c\xd9\x2f\x7f\xe5\xe0\x9b\x3c\x63\xc5\x35\x2e\x3a\x0f\x43\xe8\x31\xe2\x53\x4d\xb7\x4d\xc0\xe8\x33\x2f\x53\xe9\x79\xc6\x05\xbd\x58\xd6\xe2\x48\x50\x72\x0a\xc2\x61\x6a\xd2\x2b\xfe\x51\x07\x6c\x21\x29\x52\x0c\x78\xad\xb7\x8b\xbd\x3b\x38\x5f\x23\x5d\x96\x88\xec\xf3\x37\xd2\x17\xfe\x23\xa7\x37\x0b\x28\x8e\x5f\x3a\x1e\x44\x3a\xe9\x45\x75\x37\x02\xca\x17\xe1\xdf\x69\x64\x4c\xd5\x2c\x72\xab\x64\x51\x70\xff\xf9\x49\x7f\xea\x5d\xdd\x2a\xa2\xbe\x6b\x84\x01\x58\x4f\xdd\xb8\xc0\x5d\x20\xa4\xcd\x8a\xcc\x39\x23\xaa\x8d\x1b\x5d\x53\x76\xcb\xd6\xe1\xde\x7e\x15\x93\xd4\x0a\xd3\xd3\x40\xf9\xa9\x93\x97\xc0\x5a\xd3\x3a\x09\xbb\x3f\x6c\x2d\x3b\xf4\xee\xbe\x13\x63\x39", 222, { 0x88, 0x92, 0xcd, 0x7f, 0x51, 0x5f, 0xd0, 0x0d, 0x4e, 0x0f, 0x7b, 0x98, 0x75, 0xa3, 0xbc, 0x7e } },
|
||||
{ "\x3f\x0b\x4e\x57\xf7\xe5\xf0\x5f\xda\x6b\x3a\x8b\xa8\x10\x37\xf8\x12\x45\x90\xf9\x16\x5b\x2c\x17\x6c\x10\xef\xa9\x18\xb8\xa4\x0c\x20\x09\xf5\x80\x58\x83\x97\x9f\x59\x7a\x82\x7b\x90\xc2\x5e\x52\x72\xf5\xfa\xf0\xcd\x63\xf5\xa2\x3a\x97\x7f\xd2\xaf\x82\x3a\x44\x31\x47\x3a\xec\xa6\xa2\x2b\x69\xc8\xf6\x92\x22\x36\xf1\x2c\xfc\xa5\xde\x72\xb5\x33\x86\x3e\xe0\xdc\xc4\x87\x7d\x05\xa4\x48\x34\x36\x37\x80\x2e\xe5\xf6\x52\x91\x6d\xd0\x4c\x96\x1e\xd3\xc4\x48\x6d\x73\x5e\xda\x4c\x79\xab\xa5\x95\x8a\xec\xbe\x9f\x52\xf4\x31\xf3\x4e\x2b\xdc\x19\x34\xaf\xe9\x8b\xff\x94\xe9\xcb\x9a\x4c\x8a\x90\x28\x22\xf5\x1c\xee\xe0\xc6\xa9\xde\x91\xa9\x01\xc1\x61\x8d\x2d\x00\xa0\x88\x45\x0e\xe5\x47\x67\x75\x4f\x30\xc2\x7c\xe7\x16\xd2\x72\x21\x98\xa6\x9b\x82\x17\x5c\xb4\x5b\x51\xaf\x23\xb3\x9f\xa7\xc0\x43\xc7\x6f\x3a\x9a\x7f\x43\x27\x61\x7f\x88\xac\xb9\x41\xf5\xc5\xc0\x58\xef\x32\x33\x6a\xf3\xff\x2d\xcc\x2d\xae\x0e", 223, { 0x01, 0xee, 0xfc, 0xcf, 0xf4, 0x83, 0xfd, 0x73, 0xc0, 0x07, 0x8d, 0x6d, 0xe4, 0x05, 0xae, 0xc8 } },
|
||||
{ "\xb8\x25\x02\x77\x2d\x99\x6b\x71\x64\x65\x09\xad\xea\x9e\x5e\xe6\x5f\xbf\x95\x63\xc9\xfb\x69\x98\x95\xb1\xb4\xec\x2c\xfe\x95\x96\x2e\x6c\x3c\xa0\x4e\xc7\x55\x0e\xca\x10\x0e\x18\x85\x8b\xc7\x92\xc2\xf3\x55\x6d\x7f\xce\xf3\x56\x6c\xdb\xc6\x7c\x87\xa7\x0c\x6f\x55\x3f\xe0\x24\xbe\xff\xac\x15\x86\x89\x2b\x85\x64\xd2\x19\xe1\xc1\x56\x7a\x42\x0e\x6b\x84\x0f\xc2\xb3\x2b\xc0\xef\xac\x47\xbd\x80\x62\x63\x64\x11\x43\x24\x2a\x6b\x13\x54\xd8\x9a\xf6\x8a\xf7\xad\xab\x78\x47\x0a\xd8\xd1\x68\x6b\x7f\xd5\x9c\x79\x90\x7a\xa4\x03\x99\x38\xc6\xdb\x99\x71\xf0\x4d\xf2\x7c\xf7\x3d\x7c\x4d\xf8\xdc\xb6\xc2\xdf\x07\x17\x8c\x06\x3c\x82\xb8\xf5\x39\xd9\xd9\x48\x33\xa9\xd4\xae\xb0\x03\x48\x0d\x01\x6a\x98\xc3\x60\xe8\x96\x08\xa2\x3b\xcd\x6f\x98\x2d\x6b\x8b\x08\x01\xc9\xae\x43\x09\x99\xcd\x63\x55\xab\x7f\x23\x85\x5c\x24\x5b\xc0\x9b\x23\x16\xbd\x99\x4b\x51\xfe\x0d\x5b\x53\x1d\x21\x9d\xa4\x3f\xfc\xad\xab\xa5\xed\x57", 224, { 0x03, 0xe5, 0xd1, 0xd0, 0xaf, 0x2a, 0x72, 0xab, 0x3c, 0xa0, 0xdc, 0x8e, 0x46, 0xe4, 0x33, 0x69 } },
|
||||
{ "\xe7\x61\x30\x9e\xca\x25\x61\xd9\x2d\x37\x7a\xf9\x74\x80\x8a\xe5\x40\xc4\xf5\x06\xca\xed\x62\xde\xe3\x80\x45\xd3\x85\x31\x08\x0a\x14\x91\xd8\x6f\x37\xe5\x0b\xd0\x4e\x13\x29\x29\x8f\xb6\x9e\xfb\xc0\x50\xfa\xd5\x93\x9f\xe2\xf4\x99\x08\x97\x06\xe4\x30\x20\x0b\x3e\xaa\x17\x54\xff\xca\x0e\xae\x8f\x98\x9c\x98\x79\xe1\x07\xaf\x27\x67\x8f\x2b\x40\x38\x55\x82\x9b\x1c\xe7\x2a\xde\x27\x69\x7c\xb7\x6f\x61\xb4\xb7\xd8\x1e\x15\xc6\x0b\xc6\x29\x47\x85\xfb\x26\xc9\xcb\x29\x6c\x66\xbc\x6f\x2b\xbc\xff\x28\x22\x85\x9a\x15\x82\xd6\xa4\x29\xf1\xf1\x13\xf0\xaa\xc6\xaf\x9c\xc1\x0d\x28\xad\x84\xf9\x42\x3c\xfe\x99\x2e\xe5\x95\xd0\xf5\x4f\xd3\xef\x0d\x5a\x41\xec\x0e\xe3\x6f\x42\x7e\x36\x11\x64\xc8\x11\x44\xdf\x4c\x51\xee\x0b\x90\x3c\x42\x6d\x93\x6a\x63\xac\x42\x50\x20\x2e\x04\x6a\xde\x4f\x70\x05\x93\x3e\x1e\xa6\xee\x73\x9b\x1a\x95\xd0\x76\x1b\x86\x54\x77\x9c\x9e\x76\xf0\xb2\x38\x24\x2b\x1e\xee\x57\x02\x7b\x7b\x52", 225, { 0x1e, 0x37, 0x6b, 0x9f, 0xa2, 0xf6, 0xbd, 0xe8, 0x1e, 0x4e, 0xdc, 0xe4, 0x20, 0xaf, 0x0b, 0x93 } },
|
||||
{ "\x8e\x01\xc1\x78\xf7\xf3\xe5\xc8\x6b\xab\x98\xf6\x2a\x40\x71\x27\xbd\xd1\x76\x48\x46\x71\xba\x0b\xf3\xaf\x20\x7f\x8d\xc0\x3d\x4a\x2d\x4b\x5c\x86\x0d\xd1\x9b\x36\x7c\xb7\x32\x64\xeb\xf2\xd4\xd8\x25\x4e\x2e\x76\x9c\x5b\x8c\x35\xde\xf4\x9b\xb8\x27\x6d\x49\x8a\x0f\x58\xc8\xfb\x64\xf4\xb2\x91\x12\x34\x47\x2d\x3f\x67\xd1\xbc\x74\x88\x28\x96\xf5\x24\x52\x76\x31\xe4\x42\x16\x54\xb6\xc1\x67\xfa\x9c\x6a\x6a\xff\x11\xcf\xae\x72\x13\xba\x66\xa8\xd2\x8e\x26\x6c\xf3\xcb\x3a\x54\x81\xb0\xa3\x2f\x71\xfa\xaf\x9a\xd0\xcb\x34\xb2\x8b\xa6\x69\xe3\xdb\x97\x60\xdf\x4b\x6f\x24\xab\x67\x2d\x6b\xd3\x03\x79\xf8\xbe\x25\x49\x90\x1c\x90\xa6\x96\x7b\xed\x89\x45\xf9\x98\xdf\x8a\x14\x05\xac\x7c\x9d\xce\x4c\x79\xcc\x5a\xd4\xde\x6c\x2b\x96\x62\x37\xc3\xc3\x10\x3c\x34\x2b\xdf\x7c\x43\x21\xef\x95\x38\x7a\x62\x96\x45\xb4\xd5\xf1\x90\x32\x7a\x8e\xdf\xa5\xd3\xfc\xdf\x87\x0d\xc2\x11\xc1\xf7\xd4\x52\x6d\x9d\x21\x05\xb5\x85\x49\xdf", 226, { 0xfc, 0xeb, 0xea, 0x4e, 0x08, 0xfa, 0x14, 0xd6, 0xcc, 0x61, 0x90, 0xfa, 0x48, 0x06, 0x9e, 0x7a } },
|
||||
{ "\xda\x85\x6c\x4e\x51\x3f\x1e\x87\x08\x3b\x76\x2b\xc6\x9f\x46\x95\xb0\x8d\x65\xc2\xe7\x19\x27\xde\x4f\xe6\xee\x67\x6b\x5c\xda\x00\x64\x88\x9c\xd4\x29\x8f\x68\xa5\xaf\xd0\x08\x70\x59\x96\x0e\xbf\x74\x76\x22\x8b\xd9\x4b\x79\xcb\xb5\xcc\x66\x9d\x66\xc7\x0a\x10\x7b\xfc\x28\x8c\xde\x99\x13\xdf\x0e\x4d\xc8\xe4\x84\x0a\x18\xd2\x37\x5c\xfe\x1e\x3b\x61\x0f\x0e\x85\x64\x0f\xdc\xc9\x1a\x9f\x83\x84\x78\x14\x28\x16\x2f\x64\x28\x07\xc6\x3a\xba\x6a\x52\x29\x41\x5e\xd3\xfc\x31\xb1\x2e\x2c\x9b\xa0\xc3\x6b\x56\xba\xaa\x5d\xcc\xe2\x8f\x66\x5e\x73\x27\x9e\x75\x7e\x4e\xe1\x26\x2e\xbf\x04\x81\x4d\x6f\x22\x77\xdf\x86\x14\x65\xec\xfb\xfe\x41\x5c\xca\x06\x60\xfa\xd5\x20\xe1\x9b\x55\x05\xba\x58\xfb\x43\x5d\xf6\xa7\x6d\x06\x67\xc4\x72\xa4\x6a\x3e\x0b\x61\x4d\x21\x4e\xd0\xd2\xcf\x60\xb2\x30\xdd\x47\x65\x30\x8c\xde\xea\x78\xdf\xe1\x91\xe5\x5d\x28\x43\x11\x65\xf1\x6c\xf4\x29\x56\x83\xa6\x49\xdd\x37\x42\x0c\x2e\x37\xe7\x3d\xdf", 227, { 0xe2, 0x2e, 0xd4, 0x1d, 0xb5, 0x4e, 0xf8, 0x9c, 0x90, 0x06, 0xb3, 0xdc, 0x67, 0x84, 0x36, 0xff } },
|
||||
{ "\x9e\xd8\xa0\x6c\xfa\xc3\x10\x42\xf8\x1f\x36\xfa\xad\xae\xe8\xa3\x83\x22\x1b\x38\xbe\xdc\x86\x31\xaa\xcf\xd6\x35\x63\x83\x87\xec\x40\x36\x66\xf3\xdd\x1d\xa0\xe9\xc4\xc8\x85\xa6\xb8\xa3\xdf\x8c\x9d\x98\xe9\xf5\x07\xd2\xee\xcb\x5d\x9d\x80\x37\xaa\x69\x51\x72\x00\xee\xb1\xb7\x89\x69\xa4\x59\x2b\x04\x9f\xf0\xd7\x53\xdf\xaf\x6f\xfa\x66\xd1\x51\x6d\x94\x32\x85\xd0\x5e\xfa\x7f\xfd\x2d\x74\x91\xa3\x55\xfd\xf0\x8b\x30\x17\x60\xf6\xd7\x9d\x7f\x23\x7c\x11\xac\xed\x67\x11\x92\x90\x8b\xe9\x54\x8c\xc4\x41\x57\xa2\xb0\xf7\xa6\xfb\x27\x08\x06\x68\x58\xa7\x97\xc4\x81\x70\x24\x76\x4a\xb6\x07\x13\xbf\xf8\xbc\x20\xe9\x73\x00\xf5\x08\xd1\xa5\xbc\x6e\xff\xf5\x99\xfa\x1c\xc1\xe4\x30\x8d\x05\x91\xf2\x2d\x39\xb1\xdd\xa2\x36\x11\x43\xcb\xc3\x00\xc0\x55\xbc\x2f\x7b\x6d\xde\xb1\xfb\x8f\x31\x21\xa3\x7d\x12\xe2\xcc\x4c\xdc\x81\x7d\x99\x33\x38\xc9\xd8\xed\x8c\xc6\xcc\x9c\x15\x25\x13\xbc\x5e\x73\xd9\x76\xe2\xeb\xad\x0f\x37\xf5\x70", 228, { 0x55, 0xd9, 0x74, 0x7a, 0xdd, 0xdb, 0x7e, 0x9a, 0x38, 0xc0, 0x19, 0xe1, 0xa7, 0xca, 0x59, 0x91 } },
|
||||
{ "\xf0\x47\x3f\x69\x52\xb8\x77\x76\x86\x6d\xa2\x5e\xde\x26\x1c\x41\x3b\x43\x2c\x30\x34\xa6\x43\xd9\xe0\xb5\xd2\x5b\x41\x7f\xc5\x38\x4d\xf6\x9f\x68\x9a\x5a\x33\x8a\xa5\xb7\xfc\x36\xbe\x85\x1a\x6d\x94\x6d\xe9\x32\x59\x2b\x40\x32\x91\x8e\x43\x9e\x7d\x9d\xe6\x1a\x1e\xd4\xfe\xcd\xe8\x8c\x05\x99\x05\x78\x6a\x65\x42\x4b\x93\x95\x9a\x77\x70\x9b\x5d\x11\xbd\xa7\xfd\xd0\xd4\x7a\x75\x35\x2c\x58\x57\xc4\x72\x1c\x70\x70\x42\x65\x19\x14\x82\xee\x1d\x1e\x5b\xfc\x42\x46\xd5\xf0\x76\x7c\x0f\xfc\x98\xe0\x17\xf2\xdf\xeb\x6c\x38\xeb\xab\x0d\xd8\x66\x2b\x3d\xb4\x56\xf1\xd6\xd7\x03\xa0\x47\xe6\x7f\xbe\x2c\xb5\xd7\x90\x88\xf6\xd5\x22\xa2\x0c\x6e\x63\x79\xfd\xcf\x6c\xe4\x86\xff\xe1\x4b\x49\x30\x70\xfc\x22\xa8\x77\x2b\x97\x47\xc2\x89\x6d\xb4\x71\x7f\x57\x28\xf8\x07\xca\xd6\x41\x27\xec\xf6\xec\x0c\xaa\x6d\xb6\xbf\xe9\x1b\xf7\x86\xd4\xc0\x45\xd9\x54\x8b\x37\xff\x9e\x41\x44\x46\xe5\x07\xc9\xdb\x31\xcc\x29\x4b\x48\x55\x0e\x97\xc8\xe6", 229, { 0xd9, 0xf5, 0xd6, 0x7b, 0x77, 0x59, 0xa0, 0xb5, 0x8b, 0xaf, 0xaa, 0xc9, 0xea, 0x60, 0xdf, 0xe2 } },
|
||||
{ "\xce\xed\x56\x8a\xea\x09\xf1\x00\xb0\x28\x60\x42\x00\xa4\xca\xb2\x2b\x31\x64\xe4\xf7\xb2\x44\x02\xbf\xb9\x55\xe0\xb7\x9a\x63\x9d\x4e\x2a\x56\xf2\xac\x19\x7c\x1a\x5b\xe9\xff\x5e\x02\x8a\x75\x3c\x4b\x94\x96\x33\xe6\x20\x09\x2e\xa7\x44\x57\x8b\xcb\x28\x01\xc6\x58\xc9\xac\xc6\xa2\x4a\x7a\xc4\xe9\xf2\x75\xd4\x20\xc7\x25\x12\xc9\xc4\x41\x6a\xfb\xb9\x82\x03\x85\xc0\x92\x49\x2d\x57\x24\x95\x11\x1f\x1d\x7c\x2f\x30\xef\xb1\x00\x17\x07\x97\x3f\x6d\x5d\x67\xc7\x15\x28\xfb\x9a\x11\xb4\x35\xfe\x01\x4b\x0e\xc1\x3a\x50\x3f\x9e\x7f\x6c\x85\xb8\x5f\xdf\x95\x43\x2a\xf8\x9c\x42\x91\xa0\x71\x6a\xd9\x10\x5a\x26\xbc\xa3\x78\xb4\xdc\xc5\xd0\x6c\xe4\x0b\xf6\x21\x3e\x5d\x58\xa0\x6a\x4e\x24\x56\x02\x8c\xd7\x0e\x47\x73\x64\xd7\x66\xbc\xfd\x03\x4d\x52\x80\x4c\x25\x45\x81\x12\x6b\xd7\xf0\xc0\xae\xb4\x67\x4c\xe7\x3f\x13\xdc\x70\x08\x3c\x86\xa3\x5a\x72\x30\x10\xf0\x56\x97\x5a\xc7\x02\x6b\xae\x0e\x16\x96\xe1\x3a\x60\x9d\x26\x36\x27\x1f\x69", 230, { 0xc7, 0xb4, 0xa5, 0x2d, 0xd4, 0x3e, 0xbe, 0xcb, 0x90, 0xc5, 0x10, 0x56, 0x22, 0x68, 0xc4, 0x02 } },
|
||||
{ "\xb8\x14\x7b\x4a\xaf\xbe\x8f\xb9\xd8\xd0\x9b\x2a\x70\xd9\x43\x75\x04\xb0\xb3\x4e\x64\x82\xdd\x5c\xb6\x7a\xde\xf7\xa6\x0b\x7e\x83\xbb\xdd\xd6\x64\xc5\x51\x0c\x9c\x72\xb3\x3a\x08\x01\xfb\x6d\x34\x0e\x40\xc9\xd6\x8b\xba\xca\xee\xcf\x72\xa5\x78\xc8\x88\xcd\xca\x4d\x21\x91\x90\x8e\xeb\xe2\x62\xad\x4e\x33\xff\x65\x30\x79\x29\xe8\x65\x52\x1c\xc7\xb2\x42\xac\x0b\x7c\x18\xfa\x61\x12\x6f\xd2\x71\x94\x50\xa5\x4f\x7e\xf5\x1e\x0a\xd5\xa8\x62\x63\xec\xca\xe9\x98\xd3\xf0\xf4\x5d\x5d\x28\xaa\xec\xcd\x59\xd3\x33\x1c\xc8\x30\x2c\xea\xb7\x74\x4b\xff\x28\xe3\x10\x7c\xbf\x86\xbc\xa2\xc5\x08\x20\x3e\x49\x31\x90\xb0\x61\xfc\xf7\x97\x8e\x56\x05\x1c\x3d\x76\x83\xd7\x6a\xd3\xc6\x61\x5f\xc7\x42\x77\x9b\xbe\x36\xc7\xcd\x1a\x85\x5b\xff\xa7\xa5\x9f\xd0\xb6\xb0\x10\xda\xd8\x98\x83\x32\x38\x78\x0f\x0d\x96\x05\x99\x7f\xdc\x23\xfa\x5f\x5e\x94\xcf\x47\xb3\xcb\xdc\xb8\x2a\xdf\x1d\x5a\xeb\x9b\x6b\x60\xac\xb2\xc8\x0a\x0c\x0f\x47\x44\x90\x4b\x9b\x6c", 231, { 0x40, 0xc0, 0x57, 0x95, 0x6a, 0x81, 0x82, 0x29, 0x3b, 0xd0, 0x98, 0x14, 0x84, 0xa7, 0xa4, 0xd1 } },
|
||||
{ "\x37\x38\x3a\x31\xbb\x9a\x2d\x97\x67\xf5\x77\x16\x90\x82\x1f\xe2\xb1\x3b\xdc\x46\x27\x15\x5d\x2a\x85\x4e\x32\xb3\x95\xdc\x5a\x09\xec\x05\x69\x34\x29\x0c\x56\x1f\xca\x09\xdf\xbf\xaa\xd2\x99\x4d\x1b\x15\x98\xaf\x9c\x88\xb6\xf5\x37\x37\x84\xfe\x7a\xfc\xcb\x3b\x0f\x0d\xbd\x8b\xfa\xaf\xbd\x46\x6f\x09\xc8\x56\x4e\x13\x7e\x7f\x3c\xad\xd1\xbe\x5f\xcc\x49\xcf\xb5\xcf\xf1\xc9\x12\xf0\xe1\xe5\xb4\xd6\x69\x5c\x84\x46\xd7\x6e\xec\xfa\xe6\x7e\x4f\x8a\xc3\x5a\x29\x87\xbd\x99\xc5\xa7\x88\x1e\x95\x1a\x2d\xb9\x31\xfb\x92\xec\xef\xe2\xa1\xca\x1b\x96\x18\xfb\xd3\xe0\xed\xdd\x82\x7a\x5c\xc5\xf7\x26\x8e\x63\x21\xdc\xe7\x43\x69\x1b\xed\x70\xac\x61\xd0\x33\xd4\xb6\x9a\xf9\x12\x62\xf4\x52\xb9\xbe\x92\x16\xba\x28\x3c\xa2\xb8\x10\x7a\x40\xc7\x2f\xdc\xa5\xc6\xd8\xe3\x93\x56\x66\x8f\x9f\x76\xd5\x86\x0d\xbd\x6d\xde\xd7\x33\x99\x87\xcd\xcb\xd6\x58\xd6\x81\xc7\xb4\x54\x0c\x65\xd9\xa5\x41\x53\xc5\xc6\x04\x4f\xc5\x13\xeb\xc5\x9b\x2a\x70\x7e\x4b\xed", 232, { 0x0f, 0x8c, 0xf7, 0x8f, 0xe2, 0x33, 0xb8, 0xdb, 0x7b, 0x4b, 0x15, 0x6c, 0x88, 0x92, 0xce, 0x22 } },
|
||||
{ "\xd3\x75\x82\xa5\x8a\xca\xa4\x44\x66\xd0\x70\xc3\x44\x41\x52\xaa\x6c\x91\x46\xae\x89\x5f\x64\x74\x45\x08\x0c\x74\x81\x56\xae\xf9\x2e\x56\x36\x44\xcb\x47\x13\xd0\x7b\xae\xe3\xb1\xc2\x87\xbd\x16\xdc\x96\x1a\xed\xba\xdb\x60\xa5\x99\x23\x0d\x0f\x41\xbb\x7c\x5e\xd8\x40\x57\x4d\x60\x92\x9a\x5f\xd4\xe7\x3f\x42\xda\xfb\x8c\x4d\x24\x65\xf5\x28\x69\x05\xae\x8b\xfc\x9a\xd2\x1f\x06\x70\x29\x80\x65\x36\x99\x64\x1f\xee\x2c\xd5\x84\xfd\xba\x9a\xe0\x62\x33\xb4\xda\x03\x8b\x04\x6d\x23\x42\x0a\x80\xf1\x8f\xc8\x23\x3a\x28\xc5\x68\x3d\xb1\x2d\xdc\x9f\xbf\x15\xa1\x75\x87\xdd\x29\x7f\x27\xae\x91\x75\x91\x23\x98\x78\x10\x05\x3a\xab\x78\x2e\xed\xdb\xee\x8e\x77\x59\x51\x4c\x6a\xe9\x44\x04\x3d\xd3\xda\x2f\x09\x16\xdc\xa0\xdd\xbc\xb9\x2b\xbe\x49\x0b\x60\x3e\x4d\xc2\x75\xb7\x19\xef\x42\x25\x8e\x2f\x65\x9d\x11\xb2\x85\x6e\x9a\xe7\xb4\xd3\xec\xc6\xee\x51\xdf\xb9\xbe\xb3\xd9\x28\x00\xa0\x5b\xa0\xc1\xd6\xb7\x9f\x42\x05\xe0\xfe\x1c\x4a\x5a\xfb\x7d\x46", 233, { 0xe5, 0x61, 0x01, 0x70, 0x0e, 0x76, 0x73, 0x8d, 0xa8, 0x90, 0x1c, 0xda, 0x14, 0x27, 0xde, 0xf4 } },
|
||||
{ "\x50\xe2\x90\xdb\xc4\x58\xfb\x83\xe0\x44\x82\x4c\x6c\x5a\xc9\x74\x59\x45\x36\x9c\x7a\x71\xf5\xac\x52\x72\x15\x44\x08\x14\xcf\xda\x77\x00\xe7\x75\x62\x07\x2c\x05\xc5\x0e\x19\x5c\x46\x96\x9e\xcd\xca\xe7\xf8\x60\x25\xd9\xbd\xaf\xe9\x3f\xf4\x60\x5f\xf0\x60\x3f\x94\x73\xde\xf6\x8a\x46\xe4\x6c\x90\xcb\x29\xb8\xac\xd0\x63\xc1\x34\xba\x2c\x74\x7c\x4d\xfe\xa0\xa9\x1a\x5d\x71\xa4\x85\x14\x87\x2a\x71\x97\xb2\x01\x8b\x87\x4c\x45\x30\x55\x33\xe1\xfc\xfe\x62\x19\xf0\xf4\x2c\x43\x3f\x1d\x14\x96\xb5\xf4\x4b\x1a\xc4\xce\xc7\xbf\x2d\x37\xfc\x8a\x48\x7b\x39\xea\xef\x40\xa2\x29\x0d\x50\xc6\xfe\xbe\x75\xdc\x3f\x23\x7d\x9f\xb3\xc6\x5d\xc3\x05\xa4\x72\x12\xd5\xdb\xe2\x28\xe9\xf1\x21\xc7\x81\xbe\x90\xd8\xc8\xf8\x40\xff\x66\x59\xd4\xd9\x32\x6f\x83\xd5\x05\x00\x3d\xac\xaa\x17\xe5\x7e\xf1\xaf\xbd\x8b\xe3\xfb\xe0\x8a\x0f\x50\xe8\xa9\x03\xb0\xaf\x22\xd7\xf4\x33\x77\xe3\x95\x93\x4a\x90\x17\x36\xdb\x4c\x12\x0b\x1e\x97\xde\xea\x78\x3b\xda\x19\x16\x98\x59", 234, { 0x2d, 0x01, 0x5b, 0x45, 0xca, 0x44, 0x57, 0xf8, 0xea, 0xbb, 0x14, 0x25, 0xd1, 0x7b, 0x62, 0xec } },
|
||||
{ "\xeb\xea\x1d\x2a\x84\x43\xd3\xc3\xb7\x08\x13\x09\x10\x91\x58\xbf\xed\x23\x2f\x88\xc7\x05\x4b\x9a\x8f\x43\xb5\x01\x33\xff\x20\x8d\x3f\x6e\x5a\x5a\xa0\x76\xdf\xfa\x85\xe2\x88\x41\x5e\x40\x61\xac\x06\x58\x97\x6e\xfd\x49\x90\x19\xce\x41\x15\xe6\x90\xd8\xaa\xa1\x87\x0a\xff\x33\xea\xcf\x7f\xcd\xbf\x59\x05\xaf\xe3\xea\xae\x92\x26\x4f\xc9\xb8\x92\xfc\xeb\x8e\xcc\xc5\x20\xfa\x94\x37\x3c\x47\x67\x91\x4f\xab\x44\x62\x36\x71\x8b\xc0\x4e\xc7\x00\x22\x44\x26\xef\xdb\x08\x59\x6a\x34\xe0\x2d\xae\x24\x99\xb4\xa4\xae\xd8\x35\x83\xd7\x8e\xb3\x92\x43\x8a\x18\x0b\x6b\x28\xff\x1b\x7d\x27\x1b\x07\xd1\x98\x46\x68\x03\xf3\x2a\x97\xb1\x44\x86\x23\xd2\x82\x1e\x7f\xb1\x00\x42\xb9\x86\xfd\xf8\x65\xaf\x56\xc8\x98\x90\x5b\x25\x10\x04\xbe\x73\x71\x7e\xa7\xb9\xaa\xc1\xe5\xe5\x76\x38\x40\xb6\xff\xf2\xea\x4a\x9d\x3e\x14\x44\xbb\xdf\x9c\x99\xda\xed\xe3\xf8\xaf\x48\xbd\xd4\x68\xb9\x82\x0f\x0d\xa6\x41\x44\x01\x72\x14\xb1\xa7\x6f\x8f\xbf\x21\x81\x52\x30\x33\x50\xbe", 235, { 0x92, 0x09, 0x96, 0x7f, 0x5b, 0x1d, 0x4f, 0x40, 0xe8, 0xc7, 0x0d, 0x8f, 0x7e, 0xd7, 0x63, 0x43 } },
|
||||
{ "\xe4\x46\x29\xc4\x48\x89\x72\xd9\x5c\x32\xc8\x06\x5e\xe2\xb7\x1b\x18\x27\x15\x03\xc3\x1b\xfb\x33\x97\x29\x61\x3d\xf0\xef\x55\x81\x1e\x3f\xd8\x02\xc9\x40\x55\x56\xff\xb2\xbf\xb8\xdc\x4f\x45\x38\xd5\x4c\xb5\x11\xa1\xff\x6b\x1b\xc4\x9a\xf3\x57\xb9\x15\x43\xa8\xbb\x2a\x8e\xa1\x30\x7a\xc6\x79\xb3\xcd\xb1\x1b\xbc\x77\xa7\x5a\xee\xd5\xe5\x42\xfd\xf7\x91\x8a\x3a\x58\x4b\x25\xbd\xc8\x6c\xf7\x2e\x6b\xde\xa5\x30\xda\x98\x85\x6a\x67\xb4\xb5\x32\x7d\x2e\x47\xd8\x26\x3b\x9a\x8d\xa7\x44\xc4\xef\x46\x7e\x2b\x32\x2c\x27\x33\xec\x64\x5e\x11\x7c\x03\x9f\xbe\x18\x62\xdb\x08\x73\x87\x30\xc2\x07\xa2\x4a\x1c\x04\xb3\x55\x0d\xd5\x49\x9e\xec\x4b\x64\xc5\x1f\x68\x7c\xa1\xea\xca\x9b\xb0\x69\xb3\xa5\x39\x99\xb1\xb8\x00\x90\xee\xae\xa5\xcd\x16\xbf\x9a\xaa\xe0\x44\xbf\xee\x3c\x96\x9c\x7f\x17\x15\x3a\x34\xce\x44\x9e\xc9\x2d\x12\xe3\xec\x22\x34\xf3\x74\x02\xad\xe2\xb1\x77\x6f\xe7\xde\x06\x1b\xf7\xb3\x39\xe5\x00\x17\x6d\x93\xbf\xf3\x3a\xa4\x3e\x22\x7a\x8d\xee\x84", 236, { 0x53, 0x0e, 0x63, 0xd7, 0x2d, 0xd0, 0xbc, 0x79, 0xa2, 0x08, 0xa2, 0x58, 0x61, 0x64, 0x23, 0x51 } },
|
||||
{ "\xf8\x1f\x5c\x32\xb7\x04\x93\xcb\xdc\x68\x0f\xed\x39\xb4\x59\xc0\x76\x75\x44\xac\xde\x5b\xc2\x2a\xc3\x5e\x63\xb8\x8f\xfb\x6c\xe6\x69\x9c\x90\x8e\x80\x16\x4e\x21\xf7\x4c\xe6\x1b\x6d\xf1\xf9\x98\x28\x6a\xbc\x01\xdd\xd1\xd8\xdf\x1e\x16\xe2\xd0\x60\x40\x72\x96\xa8\xd1\xe2\x4d\xd2\x48\xa5\xb5\x7e\xc0\x41\xad\x97\xb6\xea\xc1\x81\xe8\xbd\xda\xdf\x58\x95\x14\xfe\x70\x8e\xad\xe1\x3f\x14\x18\xe9\xe1\xa6\x31\x21\xfd\x2d\x8c\x24\x68\xf3\xe6\xab\xe8\x42\xbd\xb7\x13\x9a\xfc\x57\x55\x8d\xce\x17\x0f\x3b\x93\x05\xdd\x66\xf0\x61\xf0\x31\x01\xe0\x9a\x7a\xaa\x9d\xe9\xd0\x0b\x9d\x6a\x13\x11\xfd\x0f\xa7\x29\xba\x2b\x54\x10\x1d\x99\xbe\xc6\xc1\xfd\x7b\xa1\x42\x22\xd6\x7e\x84\x83\x20\x12\x9d\xe5\xad\x5e\x60\x21\x72\x41\x87\x00\x39\x27\x7c\x3e\x7e\xe0\xc4\xb1\xea\x8b\x09\x83\x69\xb1\xc2\x9b\xea\x6e\x81\x1b\xb2\xc9\xd8\x02\x5e\x25\xe9\xf0\x73\xd1\x89\x0a\xa3\xba\x11\xf4\x9f\x40\xc1\xfb\x93\x25\xd0\x55\x43\xa2\x14\x7f\xc0\x94\x4a\xc6\xc6\xd3\x03\xe2\xb5\xa4\x2c", 237, { 0x78, 0xa2, 0x83, 0x25, 0x5d, 0x8e, 0x55, 0xc1, 0x14, 0xb5, 0xee, 0x4c, 0xc1, 0x74, 0x53, 0x04 } },
|
||||
{ "\xbc\x2a\x44\x38\x51\x3a\xa4\xec\xae\x4b\x35\xc6\x1b\x8e\xd9\x0b\x54\x1c\xf8\x6c\xf2\xac\xb4\x54\xe9\xef\x34\xd1\x2a\x88\x1d\x1c\x69\xab\x1f\xc6\xf9\x51\xab\x81\xd3\x15\xc3\x89\xb5\xaf\xe9\xad\x67\x0a\x39\xfe\x19\x03\x93\x12\xe8\xc0\xf0\xf5\x7f\xab\xd6\xae\xda\x0a\xe6\x69\x26\x3d\x93\x46\xc4\x93\xed\xbd\x6d\xc8\x9b\xab\x6f\x1f\xe7\xfe\x16\x18\xf4\xfa\x26\xcf\x0a\x25\x84\xf1\x12\xd5\xf4\x5b\x1d\x54\xfc\x51\x1e\xad\xe8\x57\xb8\x16\xe7\xaf\x32\xf9\x53\x70\x88\xa1\x0e\x40\x9b\x7e\x07\xae\x88\x14\xdc\x2e\x15\x86\x9a\xb2\x47\xbb\x9f\xe1\x12\x2a\xa1\xf6\x28\x48\xc7\x38\xf3\x8b\xf5\x11\x9d\x19\x25\xce\x4c\x12\xf0\xf2\x6c\x77\x2d\x37\x24\xb5\xb0\x22\xea\xd2\x34\x42\x32\x33\x53\x05\x41\x07\xb1\x36\x21\x54\x39\x16\xad\x9c\x7f\x16\xcc\x2b\x45\x2f\xba\x00\x19\xdf\x82\x56\x1b\xc1\x88\xcd\xdd\xc7\x42\x3a\x63\x16\x07\x08\x49\x7d\x00\x49\x04\x93\x3b\x5d\x41\x6d\xde\x3d\x69\xf9\x78\x65\x46\xfb\x73\x5c\xbf\xa1\xa6\xe1\xbf\xc4\x07\xb4\x34\xbe\x7d\xfd\x34\xe2", 238, { 0xb6, 0xbc, 0xec, 0x14, 0x2d, 0x49, 0xb6, 0x90, 0x18, 0xf9, 0x7b, 0xa5, 0x1b, 0xe9, 0x0c, 0x12 } },
|
||||
{ "\xd4\x5d\x39\x9c\xca\x90\x8d\x26\x46\xbc\xc1\xe4\xa8\x58\x57\x5e\x3b\xbc\x7f\xd7\xc7\x41\xfe\x8e\x44\x14\x2b\x91\xa9\x9c\x14\x38\xe1\x85\xbd\x45\xdf\x69\x88\x96\xc9\x1b\xb0\x84\x4f\x8f\xef\xdc\x1f\x69\x40\x78\x71\x20\xbf\x79\xbd\xcf\xac\x22\x8d\x98\x8e\x54\x6c\xb5\x74\xa2\xfe\x1d\x57\x10\x29\xcf\x9b\x6d\x71\xbd\xb4\x4a\x62\x58\xe5\x96\x26\xb4\x24\xd7\x36\x58\x1a\x07\x2d\xa5\x46\x09\xb8\xe1\x41\xc6\xaa\xde\x1c\xe9\x2c\x4b\xe5\x33\x12\x97\x49\x7b\x48\x7d\x53\x46\x6b\x31\x53\xff\x74\x25\xda\xd3\x8f\x78\xe1\x2b\x0a\xfc\x09\xc7\x69\xe2\xfc\x74\x96\x04\xf3\x69\x35\xcf\x52\x44\x16\xcb\x6e\x9c\xc4\xc9\x6e\x42\x3a\xa8\x4f\x19\xb5\xc3\x01\x8f\xa5\xfa\xaf\xb7\xbd\x5c\x1c\x05\x29\x6e\x29\xa5\xdf\x1b\x73\x78\x0f\x37\x19\xac\xb4\xb1\x9b\xf6\x4c\x55\xdd\x6f\xa4\x3c\x4b\x08\xcd\xd1\x17\xab\x2b\x80\x9e\xf0\xab\xfc\xe9\x79\x14\x2d\x50\xeb\x77\xb5\x38\x89\xc1\x1e\xfc\x6e\x6f\xa2\xe9\x67\x60\x95\x64\x6b\xc6\x73\x27\xb8\x36\x82\xa8\x8b\xe0\x24\x9a\x7b\xd8\xbb\x8c", 239, { 0x9e, 0x1e, 0x8a, 0x93, 0x65, 0x23, 0xbe, 0x28, 0x19, 0x89, 0x4c, 0xa5, 0x58, 0xc6, 0x31, 0x08 } },
|
||||
{ "\x72\x92\x38\xb0\x49\x6d\x43\xb7\xff\x66\x01\xd7\x96\xed\x84\xee\x8b\xd4\xd5\xc0\xf0\x64\x96\x5d\x27\x8a\x57\x9e\x3d\x2f\x78\xcd\xe0\xa5\xb6\x64\xff\x3d\x53\xee\xfc\xf5\xe6\x0a\x90\x4e\xbc\x8f\x3c\x3c\xea\xc9\x68\x37\xf1\xe0\x1a\x6f\x0c\x59\x54\x1c\x18\xb6\x0a\xf3\x20\x39\xbe\xb4\x85\xc7\xba\xe0\xc6\xe7\xea\x89\xf2\xe9\x53\x41\xa7\x23\x34\x34\xc5\x57\xb7\x52\xb5\x30\x54\xa4\x4f\xeb\xc3\xc0\x6d\x13\x9b\x58\x0a\x64\x8c\xec\x15\xd1\x35\xa0\xd8\xa2\xa3\x28\x00\xb5\x68\xdf\x48\xe4\x53\xf7\xc6\x87\xd1\xcb\xd2\x10\xdf\x51\x8f\xd5\xab\xab\x17\xeb\xc7\xdc\x47\x2d\x08\x98\x24\x5c\x01\x34\xe8\x60\x17\xbc\xad\xad\x41\x23\xb5\xc1\x5f\x95\x54\xc9\x33\xe9\x7a\x64\x00\x32\xe1\x7f\xbd\x74\xcf\x5f\xf6\x74\x88\xbd\x40\xa9\x54\x0b\x57\x4e\x28\xd5\xd6\x99\xf4\x43\x91\x05\x88\xbb\x92\xcc\x24\xa3\xaf\x71\x9a\x44\xc5\x79\x22\xca\x93\x39\xba\x67\x35\xcb\x38\x98\x3a\x1a\xee\x80\x65\x1d\xf8\x70\xfd\x21\x24\x88\xd1\x3e\x7f\x76\xcc\xeb\x78\x5d\x30\xae\xb3\xd2\x72\xec\x6d\x00", 240, { 0x32, 0x30, 0x23, 0x6a, 0x09, 0x78, 0x4b, 0x95, 0x15, 0x31, 0x10, 0x58, 0xba, 0xcc, 0x32, 0x4e } },
|
||||
{ "\xb2\xde\x87\xeb\xd6\xa4\x31\xd1\x42\x74\x34\xad\x36\xeb\xdb\xd5\xc3\x84\x7f\xc3\x6b\x26\xae\xf0\x54\xd7\xf8\xdc\x29\x8f\x55\x2b\x8e\x27\x36\xe9\x3d\x70\x26\xee\xc2\x60\x1d\x5d\xcf\x68\x62\x46\x3d\xe1\x19\x6b\xa0\xa4\x70\x20\x85\xb8\x62\x4b\x4a\x26\x27\x8b\x9a\xe9\x39\x76\x85\x02\x02\xfa\x38\xa7\x27\xe4\x5d\x9b\x6b\x7f\x12\x99\x41\x55\x7e\xea\xf3\x11\x16\x16\x68\x84\x6b\xb7\x95\xc6\xac\x69\x83\x75\xc0\xdd\xf8\x19\xf8\x0d\xc5\xa8\x75\x8a\xac\x25\x16\xf1\xeb\x62\x1b\x7c\x69\xe7\x5b\xb4\x7c\xeb\x1e\x44\x55\x7f\x98\xe9\x09\xca\x03\x86\x3c\x6f\x57\x54\x6c\x0b\xa9\x37\xd7\xda\x1e\x2b\x0a\x79\x8a\xdd\x08\xc6\xa9\x56\x13\xe3\xf8\xd2\x1a\x5a\x31\xaf\xbe\x5a\x62\x81\x02\x20\xa9\x42\x8f\x71\x8e\xa7\xa2\x43\xfd\x8d\x93\x7c\xde\x92\x03\xd2\x53\xc1\xa0\xd1\x8d\x65\x97\xfb\x4b\xfe\x98\x09\xf1\x52\x7f\x50\x41\x9a\xa4\x3f\xb8\xdd\xc0\x04\x87\x5b\x7a\x4f\x2c\x1f\x8d\x2f\xad\xb8\x98\x18\x71\x01\x83\x05\xbb\x1b\x88\xba\xc3\x7c\xe5\x23\x73\x21\x1d\xd8\xbb\xdf\xe5\xc2\x91", 241, { 0x93, 0x4c, 0xcc, 0x99, 0x4e, 0xac, 0x76, 0x01, 0xbd, 0x95, 0x4b, 0x71, 0x97, 0xc2, 0xb6, 0x4b } },
|
||||
{ "\xd7\xb2\xd7\x89\x08\xdd\x01\x0c\xff\x6f\x1c\x38\xa9\x8f\x1e\x54\x49\x85\x52\xee\x84\x6a\xbd\x93\x9a\x6e\xa1\x2b\xaf\xc6\x1f\xee\x47\x30\xf7\x07\xd1\x24\x6c\xc3\x5a\x99\x43\x76\x62\x70\xe9\xeb\xcc\x81\xb4\x85\xee\x41\x42\xf6\xc9\x0d\xfe\x9b\x52\x15\xc1\x73\xef\xe7\x94\xbb\xfd\x97\x94\x27\x8e\x89\xee\xbe\x30\xdb\x0a\x52\xe8\x71\xc5\x9b\x3e\x9e\xd6\xf0\x72\x6b\x52\xa1\xcc\x88\x4a\xf3\x11\xcd\x92\xb9\x11\x6b\x9d\x8b\x5e\xb3\x84\xa6\x17\x83\x25\x60\xe2\x49\x68\x46\xf8\xb5\x9d\xd4\x59\xff\x01\xcf\x21\xd2\x60\x43\xf3\xd4\xd4\x15\x91\xd2\xab\x44\x8e\x8d\x67\xc0\x1a\x1b\xde\xe7\xfd\xfc\x82\x98\x9f\xba\xbb\xf6\x43\x3b\x70\xbb\x54\xa7\xa5\x36\xd8\xf0\x3e\xe2\x01\x02\xe2\xa5\xe2\x89\xfb\xa2\x3f\x59\xd9\xbb\x7d\x7f\xf6\xa6\xb8\xe2\x54\xaa\xf3\x94\x03\xf7\x6a\xbb\xbf\xa0\x04\x16\xb5\x36\xe5\x2e\x66\x02\x1f\x1c\xa5\xde\x88\xf1\xba\xb0\xa6\xc5\xa9\x84\xc7\x5f\x8d\x45\x2e\x7e\x1d\x18\x67\xc2\x50\x56\xbc\x3a\x1d\x24\xc0\x8b\x5c\xb0\x08\xb9\xc8\x09\xfa\x95\x25\x9b\xbd\xc3", 242, { 0x02, 0x2b, 0x4e, 0xda, 0x1a, 0x44, 0x77, 0x00, 0x7e, 0xbc, 0x69, 0xdc, 0x8d, 0x36, 0x54, 0xec } },
|
||||
{ "\x7e\x46\x50\x67\x88\x1b\xb7\x6c\x23\xb3\x4f\x70\xfe\x2b\x43\x4f\x59\xbf\x17\x4b\xe6\x02\x61\xd5\xc9\xb7\x98\xfb\xbf\x50\x05\x6d\x5a\x00\xd6\x2d\x6a\x7f\x51\xd3\x78\x5a\x26\x7a\x6c\xf4\xdd\x4b\x4e\x1d\x6e\xa3\x29\x4c\xef\xe4\x0b\x7c\x68\xd5\x2a\xa1\xc2\xb7\x21\xc6\xde\xe5\x57\xc5\xc3\x26\x81\xa2\xef\x93\x3d\x84\xce\x1f\xdf\x50\x49\xc8\x49\xe3\x75\x59\xf3\xec\x6c\xd9\x0b\x65\x39\x94\xb6\xac\xed\xc3\x74\x42\xce\xda\xa1\x1e\xaf\x6f\x17\xaf\x5b\xc2\xf1\x6d\x2b\xed\x6b\x1b\xb7\xa9\xe5\x9b\xa9\xba\x06\x6d\xad\xf8\xfd\xc6\x84\xfc\xe3\x49\x38\x63\x3d\x64\x6a\xc2\x9d\x4a\xc7\x26\x67\x88\x99\x46\xb1\x46\x7a\x48\x44\x1d\x23\x2c\xc0\x8f\x62\xd9\xdb\x27\x2a\xc2\xc9\x2e\xc4\x35\xb8\x07\x24\x40\x73\x28\x56\x40\x26\xb5\x17\x07\x41\xbb\x80\xa9\x75\x05\xdd\xe3\xdb\x9f\x9c\x29\x34\xe5\x61\x4b\x4b\x46\x37\xc3\x77\x9b\xe0\x9d\x3c\x1e\x4d\x03\x11\x08\x29\x64\x3d\xcb\x8f\x41\xdb\xe9\xdd\x94\xfc\x6f\xa0\xdd\xeb\x12\xae\xca\x8b\xe4\x53\x82\xdd\xb3\xa3\x8e\x9e\xff\xef\x64\x0d\x95\x52", 243, { 0x9b, 0x3c, 0x03, 0x49, 0xe3, 0x82, 0x8c, 0x8e, 0xfb, 0x2f, 0xc9, 0x7b, 0xee, 0x4c, 0x16, 0x17 } },
|
||||
{ "\x92\xcb\xcc\x6b\x83\xda\x5b\x25\xf1\xc8\xd6\xb1\xe8\xe5\xc3\x95\x73\xaf\x5d\xde\xe5\x4f\xe4\x71\xc5\x3c\x9f\x80\x57\xfe\x70\x18\xc3\x0d\x12\xd6\xe5\xd8\xf1\xba\xb0\xe1\xa5\x13\x3f\x05\x0d\x9a\x7a\xd9\x04\x9b\x61\x30\xc3\x4e\xf8\xba\xd3\x44\xcf\xc7\xac\xfd\x2d\x29\xef\x96\xd9\x36\x3d\x9f\x84\xec\xb2\x0b\xd6\x30\x02\x41\x13\x2f\x2e\x4f\x6a\xe5\xe2\x3e\xda\xbc\x6e\x80\xc1\x4c\x5f\x86\x03\x41\xba\x6e\xd3\x5a\xd4\xda\x21\x8e\xd1\xdc\xa0\x49\xb7\x0d\x73\xd4\x2e\xbd\x73\xd2\xd6\x44\x1f\xe6\x45\x77\x21\x72\x9b\x36\x79\x7b\xc4\x23\x48\xa8\x4a\x6d\x3b\x69\xd4\xca\x92\x35\x40\x83\xcc\xeb\x58\xa9\xf1\x5a\x33\x65\x7c\xdc\x2b\x6d\xe2\x1d\x76\x93\xc3\xf9\x63\x77\xac\x84\x33\x5d\x87\x23\x92\x19\xa0\xd7\xb0\x27\x54\x9a\x01\xd7\x58\xe2\x8d\xa5\xa3\x42\xf4\xa7\xf9\x30\x02\x1f\x16\xe1\xeb\x30\x73\x50\x23\xae\xb7\x5e\xdc\x0e\xbd\x14\x1d\x7c\x3e\x04\x7c\x0c\x1b\xcd\x78\x08\x4a\xbc\x75\x68\x5a\x8f\x54\x5f\xa4\x56\xae\x12\x10\x73\xae\x64\x81\xc0\x88\xec\xde\xcf\x9a\x08\xbe\x4c\x1d\x0b", 244, { 0x74, 0x8d, 0xdc, 0x08, 0x81, 0xb7, 0x48, 0x31, 0x0b, 0xac, 0x8b, 0x95, 0x9a, 0xee, 0x5a, 0xfc } },
|
||||
{ "\xaf\x7f\x88\x91\x24\xee\x81\xf4\xf8\x20\x80\xd7\xa3\x7b\x03\xdf\xf8\x4f\x68\x82\x98\xec\x6a\xf7\xf7\xed\x3a\x4d\x08\x98\x39\x98\x88\x5d\x50\x46\xe4\x7c\xed\x8f\xc8\xc4\x9a\x0b\x46\x76\x3b\x5d\x9f\x48\xe4\x0d\xb0\x85\x55\x74\xfb\x51\x13\xd0\x51\x0b\x24\x77\x1a\xcb\x66\x29\x41\x0b\x8c\x7e\xbe\x61\xb6\x7e\xc1\x6a\xac\x4f\x78\xc3\xb8\x09\x7d\x31\x1d\xa6\xdf\xe0\x37\x15\xcb\xc9\x30\x6d\xd8\x2c\x5c\x3e\xec\x3d\x32\x04\xcd\xdb\xe8\xb5\x48\x7b\xaa\x7a\xf8\x23\x76\x7a\xb3\x93\x97\xd1\x97\x7e\xbb\x9f\xac\xf5\xb3\x3d\x36\xe5\xc8\x8b\x9a\xb7\xb4\x65\xea\x15\x44\x34\x0f\xcd\x88\xa0\x92\xce\xb3\x63\x07\x4e\x96\x39\x16\x0e\xb4\xf4\x27\xb5\x01\xab\xa9\x59\x3c\x12\x00\x1d\xe6\xe6\x09\xf4\xdd\x7f\x4b\x84\x9a\x87\xbb\x25\x04\xc9\x2b\x08\xee\x23\x51\x75\x34\x96\x70\x2c\x6d\x7c\xa5\xed\x4d\xd9\xd0\x13\x9a\xc9\x1d\x5c\xc9\x19\x2e\xc4\x35\xf2\xe7\x8e\xfb\xb1\xd5\x64\x74\xd2\x3c\x96\x50\x0a\xbb\x7e\x4b\x73\x9e\x04\x8f\xe2\xc0\x3e\xa6\x54\x1b\x2f\x1a\x87\xee\xb0\xac\xa6\x89\x6d\x2d\x1c\xb8", 245, { 0x64, 0x0a, 0x21, 0xd7, 0x1f, 0x9e, 0xd7, 0xcd, 0x82, 0xd1, 0xb8, 0xb3, 0x7e, 0xb4, 0xa8, 0x66 } },
|
||||
{ "\x06\xfb\x8a\xca\x55\x1c\xd3\x3d\xcf\xf0\x54\x07\x03\x96\x31\x83\x40\xde\xcb\xf7\x54\xe6\x4e\xbe\x6e\x53\x66\x17\x25\x2e\x11\x88\x92\x58\x8f\xf0\x97\xab\x77\x28\x43\xaf\xe4\x55\x4e\xf6\xcc\xce\xbf\x15\x70\xa4\xad\x3f\xef\xd2\x21\x7f\xf6\x02\x1b\x92\x92\xfa\xac\x5e\x26\xa1\x40\x13\x78\xb2\xfe\xdd\xe5\xfc\x48\x43\xb5\x53\x5d\x1f\x89\x17\x1e\x3a\xf1\x5e\xee\x83\x1a\xc1\xb2\xec\xa5\xc0\xf7\xe2\x92\xd3\x33\x67\x5b\x0e\x24\xcd\x1d\x6f\x55\x10\xf1\xc7\xbf\xd1\x5a\x43\x8c\xeb\xd6\x97\xf7\xb4\x97\xc6\x4f\xd2\x4c\x90\x19\xb7\x18\x77\x55\xba\xa4\x70\xd9\xd3\x50\x23\xda\xf3\x84\xdf\x8a\xfe\x25\x1e\xdb\x66\x24\xaf\x61\x65\x30\x86\x55\xd7\x8b\x1c\xb5\xb1\xfa\x84\x89\x22\xd6\x0c\x41\x44\x40\x8c\x3b\x7f\x72\x4e\x60\x7b\x30\x99\xee\xbf\x5c\xdc\x50\xeb\xa9\x74\x29\x8e\x68\x1a\x6f\xa5\x7e\xec\xb4\xb1\x77\x16\x81\x73\xb3\x1d\xdb\x47\xbe\xc8\xe7\x1a\xbe\xab\xa9\x0a\x05\x51\xe8\x99\xc7\x05\x2e\x8c\xe5\x3d\xeb\x66\xe7\xa4\xb9\x7c\x09\xc3\xbb\xb5\x6c\x4b\x1e\xe0\x6d\x01\xc1\xb2\x13\x46\xf1\x5a", 246, { 0xb9, 0x5e, 0x62, 0x77, 0x29, 0xc0, 0xa2, 0xbd, 0x30, 0xef, 0x76, 0xa4, 0x2d, 0x67, 0xa4, 0xb2 } },
|
||||
{ "\xa2\x42\x4d\xc3\x4c\xad\xc9\x66\x07\x39\xce\xc9\x7a\x9f\x7d\x97\x11\x45\x14\x5d\x30\x89\x6a\xdf\x83\xad\x94\x15\x74\x5f\xaa\xc5\xb6\xe3\xa3\xbe\xfe\xdf\x5d\xae\xd2\xc3\xba\xa1\x7a\xd3\xe4\x16\x12\xd2\xb0\xbf\xc1\x4c\x20\xd6\x04\x81\x03\x17\x24\xe9\xb7\x5e\xc6\x68\x0f\xdd\xa1\x10\x4f\xf9\x4a\x8d\x54\xc2\x2b\x31\xd1\x0d\x92\x9d\xb3\x30\xe5\x08\xa6\x5a\xf4\x2f\xb1\x8c\x67\xd9\xfd\x38\x56\x06\xb3\x74\xf7\xb4\x03\xdb\x72\x4d\x40\x01\xd1\xb0\x28\x90\x13\xda\x42\x04\x60\x31\x60\xff\x56\x6d\x44\x49\x81\x23\x5f\x68\xea\xf0\xb4\xd8\xc6\x3e\xdc\xe8\x4f\xb6\x22\x31\xb0\x42\xce\xb3\x1a\xbd\x7f\x8d\xf4\x3a\xb1\x59\x2f\xee\x5f\x22\xb7\xbb\xc2\x02\x05\x59\x37\x5d\xd1\x23\x3e\xb4\xe5\x7c\x9e\x26\x0d\xdc\xa7\x8a\x2b\x7b\x90\x21\x67\x98\xfe\xfb\x83\x66\xa6\xe9\x4c\x94\x09\x1b\x2c\x77\x5e\x55\xdd\xd7\x8e\xd2\x38\x53\x59\xb5\x2c\x71\x96\x28\xca\x46\x97\x14\x7c\xbe\xaa\x7b\x56\x89\xbc\x75\x84\xa3\x19\xc5\xe3\x7d\x4f\x17\xad\xcd\x30\xd8\x4c\xef\xf5\xb2\x4f\xf6\x7f\xa3\x7a\x54\xb9\xb9\xf7\x21\x1a", 247, { 0x98, 0x8d, 0x87, 0xaa, 0xc7, 0xf9, 0xad, 0x6e, 0x99, 0x00, 0xf9, 0x61, 0x74, 0x29, 0xad, 0xca } },
|
||||
{ "\x6c\xab\x0b\x47\x97\xa4\xdb\xd5\x15\xae\xa0\x2c\xf4\x05\x7a\x87\x59\x24\x05\x17\xf0\xbc\x5f\x47\x0d\xc0\xd8\x1b\x64\x9d\x35\xb2\x61\x87\xa1\xea\x25\xef\x31\x22\x1e\x11\x12\x1a\x42\xa9\x52\xf7\xe8\xc5\x47\x64\x43\xb6\x9f\xd2\x7b\x20\x06\xdf\x6a\x31\x6e\xd5\xf0\xee\xfe\x49\xf3\xa9\x99\xe4\xf6\x8f\x09\x3e\x55\x5e\xc8\xe6\x1a\x33\x6b\x7e\x7f\x81\xac\x03\x01\x1e\x12\x2b\x1e\x77\x3f\xe7\xab\xe4\xd5\x08\xd4\x16\x06\xfe\xb0\xad\xb8\xbb\x7f\xe6\x51\xb5\x84\x72\x24\x0b\x79\x62\x77\xbf\xb4\x3d\x30\x21\xd4\x34\x1c\x4d\x27\x6d\xdc\xcb\x9c\x7b\x6d\x54\x5f\xef\x52\xb4\x17\x08\x60\xcb\xb8\x85\x26\xad\x05\x9b\xf7\xe9\xa6\x03\x95\xe7\xe1\x2a\x7b\x6a\xf8\x8c\xc7\x36\x1f\x1b\xc2\xcb\x19\xd9\x0d\x4f\x6e\x85\x6b\x89\x4b\x71\x25\x09\xf6\x72\x1e\x66\xec\xf2\x73\xa0\x98\x20\xce\xa4\xb2\x46\x48\xed\x32\x3a\xf8\x47\xf0\xee\x1d\xae\xda\x23\xe3\x56\xd1\x3a\xd6\xc4\x20\x2b\xe0\x19\x99\x8e\x00\x6f\x4e\xd7\x8a\x5c\xe9\x9f\x14\x94\xa9\x1d\x04\xab\xf9\xb3\xb4\xf7\xaf\xa5\x3f\x93\xde\xe4\xeb\x81\x58\x09\x33\xe7", 248, { 0xaf, 0x11, 0x9d, 0x89, 0x3d, 0x36, 0x81, 0xb4, 0x1a, 0x91, 0x0b, 0x44, 0x0c, 0xe4, 0x73, 0xf2 } },
|
||||
{ "\xc3\x5d\x6f\x7a\x56\x15\x22\xf8\x31\x9b\xe0\xcf\x57\x07\xda\xdb\x49\xac\x08\x4d\x3f\xcf\xf1\xa7\x05\x73\x1a\xe3\x71\x50\x09\xb3\x7d\xe1\xf4\xe4\x05\x9c\x0b\xdc\x1e\x3d\x5f\x42\x10\x3c\x6d\xbc\xf2\x5d\x4b\xd3\xe1\x66\x6e\xf4\xdc\xea\x16\x90\x3f\x44\x56\x62\xda\xa0\xc3\xd0\xae\x33\xb9\x6b\x43\x8a\x45\x91\xa9\x00\xb2\x32\x09\x4a\xb3\xaf\xe6\x2c\x2a\xde\xf6\x4e\x93\x2a\x97\x29\x10\xd8\xf0\x1c\x11\x64\xa5\x9b\x9f\x0a\x36\x87\x46\x60\xf5\x98\x9d\x20\xa2\xf6\x73\x04\xa4\xe7\x98\xca\xe6\xa3\x45\x57\x4c\x44\x29\xf8\xd1\xd9\x10\xc3\x3f\x9a\x32\x1c\x89\x35\x16\x53\xc8\x47\x21\x6b\xd0\xe6\xbf\xf6\x6f\x5b\x2d\x1c\x42\xed\xe0\xba\x33\xd8\x95\xa6\x92\x5d\xf6\x11\xcf\xf3\xe6\x06\xd2\x9b\x69\x0f\xf7\x51\x33\xf6\xa9\x9e\xcc\xa9\x9a\x4b\x5c\x37\x9c\x30\x19\xf7\x1f\x2a\x49\xc7\x48\x2a\xf6\x72\xaa\x6a\x2e\x2b\xa3\xbb\xf4\x36\x55\xfb\xc7\xa6\x40\xa2\xcc\x41\x79\x7b\x9a\x7f\x89\x6f\xa2\xb1\xe5\x7c\x39\x3f\x05\xc5\x44\x0a\x22\xc4\x7f\xf0\x91\x9b\x6a\x6d\xb7\x87\xd0\x5e\xa8\x75\xf5\xe1\x61\xaf\x5b\x59\x9d", 249, { 0x49, 0x19, 0x39, 0x2e, 0xe6, 0x98, 0xbd, 0xe8, 0x33, 0xe7, 0x7f, 0x85, 0xcb, 0x16, 0x46, 0xeb } },
|
||||
{ "\xaf\x31\x8e\x57\x14\x59\xf1\xde\xb2\x14\xfd\x8e\xc4\x4d\xb8\x30\x3c\x7f\x59\xf0\x3b\x43\x03\xf7\x9d\x79\xaf\xa5\xab\x13\x29\x6c\xf4\x79\x31\x4c\x35\x9c\xc2\xe6\x75\x9b\x6f\x40\x2e\x0b\xe8\x14\xa5\xe7\x9c\xd5\x5b\x14\x79\x3f\x9c\x8e\xce\x99\x34\x35\x52\x8a\x41\x2e\x3e\x95\x24\xf7\x95\x33\x91\x0b\x84\x8c\xc6\x2e\xe3\xd1\xd9\x56\xdb\x39\x29\x36\xa2\x95\xf6\x68\x62\x92\x0d\x35\x39\x8b\x9c\x04\x59\x09\x24\x5e\x4e\xd8\x8c\x9a\x60\xc6\x51\x2a\x0e\xfb\xdb\x80\xbb\xf0\xeb\x9e\x65\x0e\x31\x39\x8f\xe3\xfb\x89\x41\x03\x07\xb0\x26\x79\x79\xc4\xd3\xe9\xe8\x7b\x27\x43\x92\x72\xcd\x26\xb0\x1a\xde\xcf\xe5\x3f\xa4\xbc\xcf\x36\x7a\xe1\xc0\xa3\xcf\x86\x87\xe4\x49\xbb\x67\x1e\x05\x79\x29\xe2\xfd\x57\x4d\x7b\x83\xe5\x5c\xd6\xea\xa9\x59\x0e\x43\xb4\x56\x94\x45\xdf\x22\xf8\x46\xa7\x20\x56\x66\xa2\x33\x5f\xcb\x9d\xd5\x03\x06\x55\x47\xb8\x94\xce\xe3\x6a\x81\x52\x8d\xff\x27\x09\x48\x85\x15\x32\xe4\xfb\x0b\xfc\xd5\xb9\x21\x03\x20\x7d\x06\x6a\x6e\x12\x66\x91\x43\x9e\x65\x73\x48\x89\x49\x9f\xc4\x06\x34\xd1\x29\x3f", 250, { 0x7c, 0x09, 0xc7, 0x86, 0x67, 0x7f, 0xd7, 0x70, 0x09, 0x34, 0xc4, 0x7d, 0xa5, 0x07, 0x09, 0x7f } },
|
||||
{ "\x0e\x2d\xcb\x21\x81\x17\xab\xc1\x1e\xb1\x72\x69\x9d\xf2\x79\x44\x41\x60\x05\xa1\x5a\x6a\x90\xe7\xe4\x64\x42\x16\x4d\x1f\x7f\xf5\x54\x24\x9a\xde\x0d\x8d\xa7\x22\x01\x81\x6d\x1a\x72\x4a\x7a\xcb\xbb\x15\x51\x35\xd6\x45\xbf\x38\xf8\x73\x4c\x24\x57\x06\xcc\xdc\x0b\x6c\x15\xa5\x12\xf2\xca\x90\x6e\x46\x56\x82\x69\x86\xf5\xdd\xf9\x04\xec\xcd\x3e\x99\xd9\x31\x27\xa3\x25\x23\x35\x9c\x95\x26\x58\x58\x00\xeb\xf5\xdb\x1b\xc0\x09\xd4\x70\x96\x67\xba\x6d\xad\x1d\x82\x99\xde\xf5\xfa\xe1\x84\x17\xc5\x11\x08\xcc\xf3\x5e\x08\x5d\x3c\x20\x24\x1a\xda\x9d\x65\x76\x00\xff\x49\x4f\xfa\x68\x6f\x4c\xe2\x1c\xdb\x60\xfc\xdd\xe7\x6b\xaf\x54\xc7\xff\x21\xab\xb7\x3f\x6d\x37\xc3\xe4\x84\x53\x32\x59\x9d\x48\x90\x06\x5a\x68\x57\xab\x79\x3a\x3a\xe2\x33\xcf\x0d\xc6\x34\x33\x54\xb3\x38\xff\x66\x23\x3f\x0c\x3d\xb7\x6c\x42\xdd\x57\x80\x8e\x5f\x70\xed\xf2\x9a\x5c\x9a\xb6\x6c\xe0\x33\xbc\xaa\xce\x29\xf1\xa2\xcb\x4d\xdf\x49\x2b\x04\x60\x06\xf8\x28\x6e\x1a\x12\x7c\x15\xaa\x70\xc9\x89\x6a\x84\x99\x54\xe8\xbd\x8f\xa7\x72\x26\x61\xd2", 251, { 0xb3, 0x4a, 0x6d, 0xad, 0x44, 0xc4, 0x04, 0xa4, 0x65, 0x17, 0xe7, 0x33, 0x5a, 0xd6, 0x98, 0x59 } },
|
||||
{ "\xa5\x2c\x74\xcf\x94\x7c\x13\xf9\x91\x0b\x4b\xda\x9b\x2f\x65\x21\x64\xeb\x01\xb3\xfd\x48\xcb\xd8\x20\xde\xdd\x96\x1a\x72\xb1\x1b\x53\xb9\xc1\x53\x7b\x3b\xbd\x9a\x53\x53\x68\x8b\x15\x53\x10\xf7\x81\xc4\xa8\xf2\x86\xca\x83\x07\x89\xa6\xaf\x8b\x54\x56\xec\x0f\x9e\x57\x48\xef\x33\x8a\x58\x07\xc0\x34\x15\x86\x3d\x20\x50\xda\xf7\xdf\xd3\xcb\x39\x30\x16\xa4\x96\x7a\x9b\x8b\xd6\x76\xe7\xf2\x7b\xe9\x1d\x26\xee\x8f\x38\x05\x4b\x14\xe4\xcc\xc6\x3b\xfa\x0e\xb8\x22\x96\xc1\x4a\x9c\xd7\x73\xbc\xbe\x33\x9a\x53\x76\x74\x08\xdd\x54\x53\x7d\xe2\x6c\xaf\x57\x69\x54\x6a\x64\x64\x49\xe1\xd8\xb9\x6e\x06\x5a\xed\x34\x1b\x38\x6f\xd5\x0c\xbc\x7f\xf9\x6a\x96\xb9\x7c\x00\x78\x42\x47\x14\xc1\x8d\x5b\x3b\x51\xcb\xec\xd9\x7b\xed\xaa\x35\x18\x57\x1a\x35\xb8\x22\x23\xba\xf4\x0e\xa5\x9a\xdf\x03\x44\x36\x9b\x42\x43\xb8\x07\x2d\x8a\xeb\x96\xaf\xca\xb7\x3b\x49\xb7\x37\x80\xba\x74\x79\xb6\x4b\x0d\xd1\x47\xb4\x1d\xda\x27\xae\x90\x0b\x69\x16\x83\xf1\xee\xbb\x48\x0e\x38\xc4\x85\x4e\x5c\xc1\x7c\x22\x16\x4c\x65\x3c\xf7\x5b\xf7\xe5\xb9", 252, { 0xdc, 0x2a, 0xf1, 0x01, 0x65, 0x86, 0xb7, 0x25, 0x94, 0xcb, 0x82, 0x3e, 0x4d, 0x4f, 0xbe, 0x81 } },
|
||||
{ "\x26\x05\xfe\xb3\xaf\x45\x91\x67\xf3\x2d\x13\x39\xab\xf7\x38\x3b\xbf\xc3\x73\x23\x48\xda\x09\x5e\x40\x10\xd1\x3d\xc9\x44\x8a\x4e\x16\x02\xd9\xc6\xfa\x47\xdd\x19\x0b\x64\x70\xac\x72\xfb\xfd\xa2\x52\x26\xf9\xd3\xd3\xb8\x00\xdb\xca\x9b\x8c\x4e\x07\x58\x54\x09\x3a\xb6\x3f\xa4\x82\x79\x03\x03\x94\x4b\x5f\x0c\x84\xb9\xf1\x73\x33\x54\xb4\xb0\x56\xf8\x1a\x12\x1e\x29\xc2\xed\x89\x99\xd7\xef\x45\xc6\x04\x91\x3c\xc0\x17\xa9\xc1\x08\x31\x1c\x55\x94\xa7\xb0\x15\xf0\x79\xff\xc4\x7e\x6d\x87\x71\xde\xc7\xdf\xc5\x68\xa6\x04\xeb\xd6\xfe\xd2\x1c\xff\x2d\x8e\xc6\xbe\x3c\xa0\x58\xf1\xb5\x5e\xac\x9d\x1c\x03\x12\x2f\x0b\xbe\xf5\xdd\xed\xe7\x2d\x2b\x57\x4c\xe0\x8a\xfe\xaa\x15\x1b\x59\x37\xd7\x91\xd4\x5c\x02\x34\xad\x80\xad\x01\x6f\x00\x34\xef\x09\x3b\xe0\x4c\x8b\xc9\x35\x46\x7c\xcb\xd9\x86\xda\x5d\x1c\xf7\xaf\x28\x28\xa5\x4c\x15\xc6\xc0\x25\x1c\xca\xbf\x48\x3a\x1d\xa1\x7b\x81\x65\x4e\xf2\x49\x53\x1c\xaa\x84\x88\x6f\x65\x30\x25\x78\x42\xe5\xee\x1e\xf8\x8e\x19\xf9\xaf\x34\xb9\x7a\x7b\xf6\xc2\x29\x75\x15\xb8\x07\x78\x2c\xf9", 253, { 0x84, 0x6b, 0xe9, 0x6b, 0xfc, 0xff, 0x73, 0x49, 0xce, 0xf5, 0x59, 0xf8, 0x85, 0x75, 0x4b, 0x6d } },
|
||||
{ "\x12\x75\x7c\xa3\xe7\x74\x65\x23\x81\x28\xf1\x5b\x1f\x2d\x8b\x6f\x44\xe0\xcd\x2d\xd8\xdb\x77\x16\x6c\x0b\x7b\x0d\x9b\x70\x34\x9b\x8c\x71\xb7\xdd\x93\xda\x42\x0b\xf7\x73\xd2\xa5\xce\x3e\xd1\x3c\x05\x4c\xeb\xda\x7c\x3c\x01\x0f\x4e\x51\x37\x99\x2e\x2f\x28\xaf\xed\x32\x39\xea\x18\x6b\x0b\xd0\xbd\x39\x0a\xff\x4e\x7f\x22\xf3\x9f\x87\x92\x74\x0a\x73\xd8\x9f\xb2\x5b\xcc\x8e\xe4\x08\xc9\xa7\x99\x4c\x06\x7e\x18\xfc\x02\x68\xb8\x8c\x1e\x9d\xc3\x45\x44\x08\x77\x25\xc5\xaf\x26\x53\x41\xba\x7d\x3d\xbf\x22\xe1\x50\xdd\xf7\xf5\x53\x21\x4d\x38\x61\x6d\xc4\xcc\x81\x91\xb3\x51\xe3\xfb\xf1\xf0\xba\x89\x3f\x74\xb0\x7f\x55\x92\x0a\x94\x88\x49\x5a\x27\x14\x64\xdb\x8f\x0c\x1d\x6c\x90\xdb\xdc\x2c\xe9\x76\x1d\xae\x09\x20\x6f\xd9\xe2\xd9\x98\x5f\xd7\x64\xd6\xd8\xcf\xf4\x40\x7a\x6b\x72\x4b\x77\x54\x6d\x69\xf4\xad\x9f\xcc\xa1\xa8\x18\x49\xf9\x34\x0a\x57\x18\xd4\x30\x36\x34\x8b\xdb\x2c\xb9\xf4\x9a\xea\x05\x6e\x85\x0e\xbd\x73\x26\xc2\xca\x0a\x05\x81\xf4\x53\xcf\xfa\x19\x40\x22\x0d\x09\x63\xf8\xf2\x01\xe1\xad\x79\xc3\x86\xae\x6b\x4e", 254, { 0x23, 0xe9, 0x88, 0x6a, 0xc2, 0x8c, 0x64, 0x59, 0xdb, 0xa2, 0xe7, 0x84, 0x10, 0x37, 0x53, 0xd0 } },
|
||||
{ "\xf3\xc0\x10\x3f\xf2\xea\xca\xc4\xea\x01\xdf\x39\x6d\xce\x54\x61\xef\xdd\xf4\x42\x92\xe5\x70\x9d\x1c\xcf\xa0\x08\x0a\x65\xe8\xaa\xbe\x98\xb6\x93\xd3\x6d\x27\xb5\x91\x86\xc9\x83\x7c\x49\x7b\x25\x07\xaf\x71\x55\x66\xab\x54\xd9\x81\x34\x86\x9d\x04\xf1\x83\x6c\x93\x80\x63\x4b\x1b\x64\x7b\x72\x44\x89\x24\xe8\x02\x74\x93\xba\x4b\x0b\xe7\xd7\xe3\xfe\x42\x8b\x53\xd1\x0e\x96\xf8\x88\x61\xe9\x37\xee\x7b\xfc\xce\x81\x6c\xce\x46\xfd\xd3\x7a\x84\x83\xc1\x73\x7f\x66\xbb\x5c\x0c\x93\xde\x86\xd6\x9a\x1d\x07\x69\x5d\xa6\x73\x6d\x54\x64\x3a\xef\x7a\x9d\x9e\xdb\xd7\xba\x4f\x86\xab\x27\xa4\x68\x34\x51\x78\xe7\x1c\xcc\x9f\x4e\x83\x97\x04\xdc\xa4\x77\x61\xf9\x26\x7f\x99\x84\x01\xb1\xb5\x47\x0b\xbf\x79\x8c\x1f\xea\xa2\xc9\xe8\x0c\xbf\x76\x4f\xb1\xa9\xff\x7f\x5f\xa1\xd5\x91\xf6\x04\xa0\xd9\x32\xad\x8f\xcc\x4e\xe7\xcf\x8c\xc3\x0d\x19\x12\x2f\xc1\x66\xf7\x50\xc5\xbe\xdf\x2f\x79\x2e\x83\x59\xf1\xd8\x59\x48\xb2\x24\xe1\xe1\x0a\x15\x8e\x17\x09\xb6\x50\xad\x1f\xb3\xba\x18\x54\x03\xd5\x82\x1e\xc3\x80\xeb\xe2\x1f\x82\x6a\x0a\x69\x2e\x92", 255, { 0xe8, 0x99, 0x39, 0xbb, 0x59, 0x6c, 0x74, 0x74, 0x67, 0x04, 0x26, 0x4c, 0xd3, 0xaf, 0x38, 0x31 } },
|
||||
{ "\xbf\x4b\xb1\xf0\x43\x19\xfc\xb0\xee\x40\x48\x5f\xc3\xdc\x4a\xca\xaf\x65\xf5\x06\x5d\x88\xe7\x89\xb8\x14\x71\x76\xfe\x0b\x46\xf6\x7e\xd9\xbf\xc1\xee\xa1\xc8\xbd\x6b\xb2\x6b\xbd\x0d\x18\xf7\x6a\x26\x4f\xcc\x3f\x18\x13\xc6\xae\xd0\x53\x44\x60\xe3\x43\xd4\x9a\x43\x91\x7c\xbb\x9d\xaf\xa7\xe1\x53\x4f\xab\xac\x11\xed\xf3\x1a\x0e\x85\xce\x92\xe1\x66\xd3\xfc\xfd\x1f\xee\x0d\xcb\x95\x0c\xa0\x63\x36\x5f\x40\xe6\x48\x4e\xc2\x7a\x5b\xfd\x0f\xe3\xdd\x74\x00\xbb\xcc\x6e\x62\x4e\x86\xc0\x18\x14\xbc\x64\x60\xcb\x85\x22\x2e\x31\x8f\xda\xb4\x5b\x70\x70\x03\xb5\x1a\x54\xcb\x97\x6d\xac\x3e\x7f\xe7\x21\x13\xf1\x77\x43\xa7\xe8\x6f\x9a\x3e\xf7\x97\x4a\x66\x01\x5d\x62\x7c\x91\x2a\xc1\x48\xd7\xd1\xa5\xc4\x40\x21\xd1\xfa\xb1\x9a\x5b\x0b\x5f\x3c\x0f\x4b\x4d\x7a\x83\x8a\x63\x4e\xb9\x6e\x28\x66\x6a\xfc\x1d\x7c\xf5\x35\xb5\xc3\xe4\xdd\xf4\x7d\x16\x57\xa2\xa9\x8f\xab\x2c\xda\xd9\xaa\x18\x23\x14\x29\x23\x2f\xa1\x69\xf9\x6d\x67\x97\x91\x68\xc0\x6e\x22\x34\x04\xfa\xc5\x04\xb0\x78\xa8\xd9\x32\x5a\xec\x55\x53\x66\x1d\xae\x41\xfe\x4b\xbe\x38\x7a", 256, { 0xf9, 0xd0, 0x4d, 0xbb, 0xc9, 0x3f, 0xc3, 0xa4, 0x73, 0xd0, 0xd2, 0x2a, 0xb4, 0x79, 0x0a, 0xcb } },
|
||||
|
4706
cmdline/state.c
Normal file
4706
cmdline/state.c
Normal file
File diff suppressed because it is too large
Load Diff
385
cmdline/state.h
Normal file
385
cmdline/state.h
Normal file
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __STATE_H
|
||||
#define __STATE_H
|
||||
|
||||
#include "elem.h"
|
||||
|
||||
struct snapraid_handle;
|
||||
struct snapraid_io;
|
||||
|
||||
/****************************************************************************/
|
||||
/* parity level */
|
||||
|
||||
/**
|
||||
* Max level of parity supported.
|
||||
*/
|
||||
#define LEV_MAX 6
|
||||
|
||||
/**
|
||||
* Return the parity name: Parity, 2-Parity, 3-Parity, 4-Parity, 5-Parity, 6-Parity.
|
||||
*/
|
||||
const char* lev_name(unsigned level);
|
||||
|
||||
/**
|
||||
* Return the parity name used in the config file: parity, 2-parity, 3-parity, 4-parity, 5-parity, 6-parity.
|
||||
*/
|
||||
const char* lev_config_name(unsigned level);
|
||||
|
||||
/****************************************************************************/
|
||||
/* state */
|
||||
|
||||
/**
|
||||
* Units for disk space.
|
||||
*/
|
||||
#define KILO (1000)
|
||||
#define MEGA (1000 * 1000)
|
||||
#define GIGA (1000 * 1000 * 1000)
|
||||
#define TERA (1000 * 1000 * 1000 * 1000LL)
|
||||
#define KIBI (1024)
|
||||
#define MEBI (1024 * 1024)
|
||||
#define GIBI (1024 * 1024 * 1024)
|
||||
#define TEBI (1024 * 1024 * 1024 * 1024LL)
|
||||
|
||||
/**
|
||||
* Global variable to identify if Ctrl+C is pressed.
|
||||
*/
|
||||
extern volatile int global_interrupt;
|
||||
|
||||
#define SORT_PHYSICAL 1 /**< Sort by physical order. */
|
||||
#define SORT_INODE 2 /**< Sort by inode. */
|
||||
#define SORT_ALPHA 3 /**< Sort by alphabetic order. */
|
||||
#define SORT_DIR 4 /**< Sort by directory order. */
|
||||
|
||||
/**
|
||||
* Options set only at startup.
|
||||
* For all these options a value of 0 means nothing set, and to use the default.
|
||||
*/
|
||||
struct snapraid_option {
|
||||
int gui; /**< Gui output. */
|
||||
int auditonly; /**< In check, checks only the hash and not the parity. */
|
||||
int badonly; /**< In fix, fixes only the blocks marked as bad. */
|
||||
int syncedonly; /**< In fix, fixes only files that are synced. */
|
||||
int prehash; /**< Enables the prehash mode for sync. */
|
||||
unsigned io_error_limit; /**< Max number of input/output errors before aborting. */
|
||||
int force_zero; /**< Forced dangerous operations of syncing files now with zero size. */
|
||||
int force_empty; /**< Forced dangerous operations of syncing disks now empty. */
|
||||
int force_uuid; /**< Forced dangerous operations of syncing disks with uuid changed. */
|
||||
int force_device; /**< Forced dangerous operations of using disks with save device id. */
|
||||
int force_nocopy; /**< Force dangerous operations of syncing files without using copy detection. */
|
||||
int force_full; /**< Force a full parity update. */
|
||||
int force_realloc; /**< Force a full reallocation and parity update. */
|
||||
int expect_unrecoverable; /**< Expect presence of unrecoverable error in checking or fixing. */
|
||||
int expect_recoverable; /**< Expect presence of recoverable error in checking. */
|
||||
int skip_device; /**< Skip devices matching checks. */
|
||||
int skip_sign; /**< Skip the sign check for content files. */
|
||||
int skip_fallocate; /**< Skip the use of fallocate(). */
|
||||
int skip_space_holder; /**< Skip the use of spaceholder file. */
|
||||
int file_mode; /**< File mode. Mask of ADVISE_* flags. */
|
||||
int skip_lock; /**< Skip the lock file protection. */
|
||||
int skip_self; /**< Skip the self-test. */
|
||||
int skip_content_check; /**< Relax some content file checks. */
|
||||
int skip_parity_access; /**< Skip the parity access for commands that don't need it. */
|
||||
int skip_disk_access; /**< Skip the data disk access for commands that don't need it. */
|
||||
int skip_content_access; /**< Skip the content access for commands that don't need it. */
|
||||
int kill_after_sync; /**< Kill the process after sync without saving the final state. */
|
||||
int force_murmur3; /**< Force Murmur3 choice. */
|
||||
int force_spooky2; /**< Force Spooky2 choice. */
|
||||
int force_order; /**< Force sorting order. One of the SORT_* defines. */
|
||||
unsigned force_scrub_at; /**< Force scrub for the specified number of blocks. */
|
||||
int force_scrub_even; /**< Force scrub of all the even blocks. */
|
||||
int force_content_write; /**< Force the update of the content file. */
|
||||
int skip_content_write; /**< Skip the update of the content file. */
|
||||
int force_scan_winfind; /**< Force the use of FindFirst/Next in Windows to list directories. */
|
||||
int force_progress; /**< Force the use of the progress status. */
|
||||
unsigned force_autosave_at; /**< Force autosave at the specified block. */
|
||||
int fake_device; /**< Fake device data. */
|
||||
int no_warnings; /**< Remove some warning messages. */
|
||||
int expected_missing; /**< If missing files are expected and should not be reported. */
|
||||
int fake_uuid; /**< Set fakes UUID for testing. */
|
||||
int match_first_uuid; /**< Force the matching of the first UUID. */
|
||||
int force_parity_update; /**< Force parity update even if data is not changed. */
|
||||
unsigned io_cache; /**< Number of IO buffers to use. 0 for default. */
|
||||
int auto_conf; /**< Allow to run without configuration file. */
|
||||
int force_stats; /**< Force stats print during process. */
|
||||
uint64_t parity_limit_size; /**< Test limit for parity files. */
|
||||
};
|
||||
|
||||
struct snapraid_state {
|
||||
struct snapraid_option opt; /**< Setup options. */
|
||||
int filter_hidden; /**< Filter out hidden files. */
|
||||
uint64_t autosave; /**< Autosave after the specified amount of data. 0 to disable. */
|
||||
int need_write; /**< If the state is changed. */
|
||||
int checked_read; /**< If the state was read and checked. */
|
||||
uint32_t block_size; /**< Block size in bytes. */
|
||||
unsigned raid_mode; /**< Raid mode to use. RAID_MODE_DEFAULT or RAID_MODE_ALTERNATE. */
|
||||
int file_mode; /**< File access mode. Combination of ADVISE_* flags. */
|
||||
struct snapraid_parity parity[LEV_MAX]; /**< Parity vector. */
|
||||
char share[PATH_MAX]; /**< Path of the share tree. If !=0 pool links are created in a different way. */
|
||||
char pool[PATH_MAX]; /**< Path of the pool tree. */
|
||||
uint64_t pool_device; /**< Device identifier of the pool. */
|
||||
unsigned char hashseed[HASH_MAX]; /**< Hash seed. Just after a uint64 to provide a minimal alignment. */
|
||||
unsigned char prevhashseed[HASH_MAX]; /**< Previous hash seed. In case of rehash. */
|
||||
char lockfile[PATH_MAX]; /**< Path of the lock file to use. */
|
||||
unsigned level; /**< Number of parity levels. 1 for PAR1, 2 for PAR2. */
|
||||
unsigned hash; /**< Hash kind used. */
|
||||
unsigned prevhash; /**< Previous hash kind used. In case of rehash. */
|
||||
unsigned besthash; /**< Best hash suggested. */
|
||||
const char* command; /**< Command running. */
|
||||
tommy_list contentlist; /**< List of content files. */
|
||||
tommy_list disklist; /**< List of all the disks. */
|
||||
tommy_list maplist; /**< List of all the disk mappings. */
|
||||
tommy_list filterlist; /**< List of inclusion/exclusion. */
|
||||
tommy_list importlist; /**< List of import file. */
|
||||
tommy_hashdyn importset; /**< Hashtable by hash of all the import blocks. */
|
||||
tommy_hashdyn previmportset; /**< Hashtable by prevhash of all the import blocks. Valid only if we are in a rehash state. */
|
||||
tommy_hashdyn searchset; /**< Hashtable by timestamp of all the search files. */
|
||||
tommy_arrayblkof infoarr; /**< Block information array. */
|
||||
|
||||
/**
|
||||
* Cumulative time used for computations.
|
||||
*/
|
||||
uint64_t tick_misc;
|
||||
uint64_t tick_sched;
|
||||
uint64_t tick_raid;
|
||||
uint64_t tick_hash;
|
||||
|
||||
/**
|
||||
* Cumulative time used for all io operations of disks.
|
||||
*/
|
||||
uint64_t tick_io;
|
||||
|
||||
/**
|
||||
* Last time used for time measure.
|
||||
*/
|
||||
uint64_t tick_last;
|
||||
|
||||
int clear_past_hash; /**< Clear all the hash from CHG and DELETED blocks when reading the state from an incomplete sync. */
|
||||
|
||||
time_t progress_whole_start; /**< Initial start of the whole process. */
|
||||
time_t progress_interruption; /**< Time of the start of the progress interruption. */
|
||||
time_t progress_wasted; /**< Time wasted in interruptions. */
|
||||
|
||||
time_t progress_time[PROGRESS_MAX]; /**< Last times of progress. */
|
||||
block_off_t progress_pos[PROGRESS_MAX]; /**< Last positions of progress. */
|
||||
data_off_t progress_size[PROGRESS_MAX]; /**< Last sizes of progress. */
|
||||
uint64_t progress_tick_misc[PROGRESS_MAX]; /**< Last cpu ticks of progress. */
|
||||
uint64_t progress_tick_sched[PROGRESS_MAX]; /**< Last scheduling ticks of progress. */
|
||||
uint64_t progress_tick_raid[PROGRESS_MAX]; /**< Last raid ticks of progress. */
|
||||
uint64_t progress_tick_hash[PROGRESS_MAX]; /**< Last hash ticks of progress. */
|
||||
uint64_t progress_tick_io[PROGRESS_MAX]; /**< Last io ticks of progress. */
|
||||
|
||||
int progress_ptr; /**< Pointer to the next position to fill. Rolling over. */
|
||||
int progress_tick; /**< Number of measures done. */
|
||||
|
||||
int no_conf; /**< Automatically add missing info. Used to load content without a configuration file. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the state.
|
||||
*/
|
||||
void state_init(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Deinitialize the state.
|
||||
*/
|
||||
void state_done(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Read the configuration file.
|
||||
*/
|
||||
void state_config(struct snapraid_state* state, const char* path, const char* command, struct snapraid_option* opt, tommy_list* filterlist_disk);
|
||||
|
||||
/**
|
||||
* Read the state.
|
||||
*/
|
||||
void state_read(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Write the new state.
|
||||
*/
|
||||
void state_write(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Diff all the disks.
|
||||
*/
|
||||
int state_diff(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Scan all the disks to update the state.
|
||||
*/
|
||||
void state_scan(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Set the nanosecond timestamp of all files that have a zero value.
|
||||
*/
|
||||
void state_touch(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Devices operations.
|
||||
*/
|
||||
void state_device(struct snapraid_state* state, int operation, tommy_list* filterlist_disk);
|
||||
|
||||
/**
|
||||
* Sync the parity data.
|
||||
*/
|
||||
int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount);
|
||||
|
||||
/**
|
||||
* Check (and fixes) all the files and parity data.
|
||||
* \param fix If we have to fix, after checking.
|
||||
*/
|
||||
int state_check(struct snapraid_state* state, int fix, block_off_t blockstart, block_off_t blockcount);
|
||||
|
||||
/**
|
||||
* Dry the files.
|
||||
*/
|
||||
void state_dry(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount);
|
||||
|
||||
/**
|
||||
* Rehash the files.
|
||||
*/
|
||||
void state_rehash(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Scrub levels.
|
||||
*/
|
||||
#define SCRUB_AUTO -1 /**< Automatic selection. */
|
||||
#define SCRUB_BAD -2 /**< Scrub only the bad blocks. */
|
||||
#define SCRUB_NEW -3 /**< Scub the new blocks. */
|
||||
#define SCRUB_FULL -4 /**< Scrub everything. */
|
||||
#define SCRUB_EVEN -5 /**< Even blocks. */
|
||||
|
||||
/**
|
||||
* Scrub the files.
|
||||
*/
|
||||
int state_scrub(struct snapraid_state* state, int plan, int olderthan);
|
||||
|
||||
/**
|
||||
* Print the status.
|
||||
*/
|
||||
int state_status(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Find duplicates.
|
||||
*/
|
||||
void state_dup(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* List content.
|
||||
*/
|
||||
void state_list(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Create pool tree.
|
||||
*/
|
||||
void state_pool(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Refresh the free space info.
|
||||
*
|
||||
* Note that it requires disks access.
|
||||
*/
|
||||
void state_refresh(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Skip files, symlinks and dirs.
|
||||
* Apply any skip access disk.
|
||||
*/
|
||||
void state_skip(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Filter files, symlinks and dirs.
|
||||
* Apply an additional filter to the list currently loaded.
|
||||
*/
|
||||
void state_filter(struct snapraid_state* state, tommy_list* filterlist_file, tommy_list* filterlist_disk, int filter_missing, int filter_error);
|
||||
|
||||
/**
|
||||
* Begin the progress visualization.
|
||||
*/
|
||||
int state_progress_begin(struct snapraid_state* state, block_off_t blockstart, block_off_t blockmax, block_off_t countmax);
|
||||
|
||||
/**
|
||||
* End the progress visualization.
|
||||
*/
|
||||
void state_progress_end(struct snapraid_state* state, block_off_t countpos, block_off_t countmax, data_off_t countsize);
|
||||
|
||||
/**
|
||||
* Write the progress.
|
||||
*/
|
||||
int state_progress(struct snapraid_state* state, struct snapraid_io* io, block_off_t blockpos, block_off_t countpos, block_off_t countmax, data_off_t countsize);
|
||||
|
||||
/**
|
||||
* Stop temporarily the progress.
|
||||
*/
|
||||
void state_progress_stop(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Restart the progress.
|
||||
*/
|
||||
void state_progress_restart(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Set the usage time as wasted one not counted.
|
||||
*/
|
||||
void state_usage_waste(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Set the usage time for CPU.
|
||||
*/
|
||||
void state_usage_misc(struct snapraid_state* state);
|
||||
void state_usage_sched(struct snapraid_state* state);
|
||||
void state_usage_raid(struct snapraid_state* state);
|
||||
void state_usage_hash(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Set the last file used
|
||||
*/
|
||||
void state_usage_file(struct snapraid_state* state, struct snapraid_disk* disk, struct snapraid_file* file);
|
||||
|
||||
/**
|
||||
* Set the usage time for a set of data disks.
|
||||
*/
|
||||
void state_usage_disk(struct snapraid_state* state, struct snapraid_handle* handle_map, unsigned* waiting_map, unsigned waiting_mac);
|
||||
|
||||
/**
|
||||
* Set the usage time for a set of parity disk.
|
||||
*/
|
||||
void state_usage_parity(struct snapraid_state* state, unsigned* waiting_map, unsigned waiting_mac);
|
||||
|
||||
/**
|
||||
* Print the stats of the usage time.
|
||||
*/
|
||||
void state_usage_print(struct snapraid_state* state);
|
||||
|
||||
/**
|
||||
* Check the file-system on all disks.
|
||||
* On error it aborts.
|
||||
*/
|
||||
void state_fscheck(struct snapraid_state* state, const char* ope);
|
||||
|
||||
/****************************************************************************/
|
||||
/* misc */
|
||||
|
||||
/**
|
||||
* Generate a dummy configuration file from a content file.
|
||||
*/
|
||||
void generate_configuration(const char* content);
|
||||
|
||||
#endif
|
||||
|
531
cmdline/status.c
Normal file
531
cmdline/status.c
Normal file
@ -0,0 +1,531 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "parity.h"
|
||||
#include "handle.h"
|
||||
#include "raid/raid.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* status */
|
||||
|
||||
unsigned day_ago(time_t ref, time_t now)
|
||||
{
|
||||
return (now - ref) / (24 * 3600);
|
||||
}
|
||||
|
||||
#define GRAPH_COLUMN 70
|
||||
#define GRAPH_ROW 15
|
||||
|
||||
static unsigned perc(uint64_t part, uint64_t total)
|
||||
{
|
||||
if (!total)
|
||||
return 0;
|
||||
|
||||
return (unsigned)(part * 100 / total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bit used to mark unscrubbed time info.
|
||||
*/
|
||||
#define TIME_NEW 1
|
||||
|
||||
int state_status(struct snapraid_state* state)
|
||||
{
|
||||
block_off_t blockmax;
|
||||
block_off_t i;
|
||||
time_t* timemap;
|
||||
time_t now;
|
||||
block_off_t bad;
|
||||
block_off_t bad_first;
|
||||
block_off_t bad_last;
|
||||
block_off_t rehash;
|
||||
block_off_t count;
|
||||
unsigned l;
|
||||
unsigned dayoldest, daymedian, daynewest;
|
||||
unsigned bar_scrubbed[GRAPH_COLUMN];
|
||||
unsigned bar_new[GRAPH_COLUMN];
|
||||
unsigned barpos;
|
||||
unsigned barmax;
|
||||
time_t oldest, newest, median;
|
||||
unsigned x, y;
|
||||
tommy_node* node_disk;
|
||||
unsigned file_count;
|
||||
unsigned file_fragmented;
|
||||
unsigned extra_fragment;
|
||||
unsigned file_zerosubsecond;
|
||||
uint64_t file_size;
|
||||
uint64_t file_block_count;
|
||||
uint64_t file_block_free;
|
||||
block_off_t parity_block_free;
|
||||
unsigned unsynced_blocks;
|
||||
unsigned unscrubbed_blocks;
|
||||
uint64_t all_wasted;
|
||||
int free_not_zero;
|
||||
|
||||
/* get the present time */
|
||||
now = time(0);
|
||||
|
||||
/* keep track if at least a free info is available */
|
||||
free_not_zero = 0;
|
||||
|
||||
blockmax = parity_allocated_size(state);
|
||||
|
||||
log_tag("summary:block_size:%u\n", state->block_size);
|
||||
log_tag("summary:parity_block_count:%u\n", blockmax);
|
||||
|
||||
/* get the minimum parity free space */
|
||||
parity_block_free = state->parity[0].free_blocks;
|
||||
for (l = 0; l < state->level; ++l) {
|
||||
log_tag("summary:parity_block_total:%s:%u\n", lev_config_name(l), state->parity[l].total_blocks);
|
||||
log_tag("summary:parity_block_free:%s:%u\n", lev_config_name(l), state->parity[l].free_blocks);
|
||||
if (state->parity[l].free_blocks < parity_block_free)
|
||||
parity_block_free = state->parity[l].free_blocks;
|
||||
if (state->parity[l].free_blocks != 0)
|
||||
free_not_zero = 1;
|
||||
}
|
||||
log_tag("summary:parity_block_free_min:%u\n", parity_block_free);
|
||||
|
||||
printf("SnapRAID status report:\n");
|
||||
printf("\n");
|
||||
printf(" Files Fragmented Excess Wasted Used Free Use Name\n");
|
||||
printf(" Files Fragments GB GB GB\n");
|
||||
|
||||
/* count fragments */
|
||||
file_count = 0;
|
||||
file_size = 0;
|
||||
file_block_count = 0;
|
||||
file_block_free = 0;
|
||||
file_fragmented = 0;
|
||||
extra_fragment = 0;
|
||||
file_zerosubsecond = 0;
|
||||
all_wasted = 0;
|
||||
for (node_disk = state->disklist; node_disk != 0; node_disk = node_disk->next) {
|
||||
struct snapraid_disk* disk = node_disk->data;
|
||||
tommy_node* node;
|
||||
block_off_t j;
|
||||
unsigned disk_file_count = 0;
|
||||
unsigned disk_file_fragmented = 0;
|
||||
unsigned disk_extra_fragment = 0;
|
||||
unsigned disk_file_zerosubsecond = 0;
|
||||
block_off_t disk_block_count = 0;
|
||||
uint64_t disk_file_size = 0;
|
||||
block_off_t disk_block_latest_used = 0;
|
||||
block_off_t disk_block_max_by_space;
|
||||
block_off_t disk_block_max_by_parity;
|
||||
block_off_t disk_block_max;
|
||||
int64_t wasted;
|
||||
|
||||
/* for each file in the disk */
|
||||
node = disk->filelist;
|
||||
while (node) {
|
||||
struct snapraid_file* file;
|
||||
|
||||
file = node->data;
|
||||
node = node->next; /* next node */
|
||||
|
||||
if (file->mtime_nsec == STAT_NSEC_INVALID
|
||||
|| file->mtime_nsec == 0
|
||||
) {
|
||||
++file_zerosubsecond;
|
||||
++disk_file_zerosubsecond;
|
||||
if (disk_file_zerosubsecond < 50)
|
||||
log_tag("zerosubsecond:%s:%s: \n", disk->name, file->sub);
|
||||
if (disk_file_zerosubsecond == 50)
|
||||
log_tag("zerosubsecond:%s:%s: (more follow)\n", disk->name, file->sub);
|
||||
}
|
||||
|
||||
/* check fragmentation */
|
||||
if (file->blockmax != 0) {
|
||||
block_off_t prev_pos;
|
||||
block_off_t last_pos;
|
||||
int fragmented;
|
||||
|
||||
fragmented = 0;
|
||||
prev_pos = fs_file2par_get(disk, file, 0);
|
||||
for (j = 1; j < file->blockmax; ++j) {
|
||||
block_off_t parity_pos = fs_file2par_get(disk, file, j);
|
||||
if (prev_pos + 1 != parity_pos) {
|
||||
fragmented = 1;
|
||||
++extra_fragment;
|
||||
++disk_extra_fragment;
|
||||
}
|
||||
prev_pos = parity_pos;
|
||||
}
|
||||
|
||||
/* keep track of latest block used */
|
||||
last_pos = fs_file2par_get(disk, file, file->blockmax - 1);
|
||||
if (last_pos > disk_block_latest_used) {
|
||||
disk_block_latest_used = last_pos;
|
||||
}
|
||||
|
||||
if (fragmented) {
|
||||
++file_fragmented;
|
||||
++disk_file_fragmented;
|
||||
}
|
||||
|
||||
disk_block_count += file->blockmax;
|
||||
}
|
||||
|
||||
/* count files */
|
||||
++file_count;
|
||||
++disk_file_count;
|
||||
file_size += file->size;
|
||||
file_block_count += file->blockmax;
|
||||
disk_file_size += file->size;
|
||||
}
|
||||
|
||||
if (disk->free_blocks != 0)
|
||||
free_not_zero = 1;
|
||||
|
||||
/* get the free block info */
|
||||
disk_block_max_by_space = disk_block_count + disk->free_blocks;
|
||||
disk_block_max_by_parity = blockmax + parity_block_free;
|
||||
|
||||
/* the maximum usable space in a disk is limited by the smallest */
|
||||
/* of the disk size and the parity size */
|
||||
/* the wasted space is the space that we have to leave */
|
||||
/* free on the data disk, when the parity is filled up */
|
||||
if (disk_block_max_by_space < disk_block_max_by_parity) {
|
||||
disk_block_max = disk_block_max_by_space;
|
||||
} else {
|
||||
disk_block_max = disk_block_max_by_parity;
|
||||
}
|
||||
|
||||
/* wasted space is the difference of the two maximum size */
|
||||
/* if negative, it's extra space available in parity */
|
||||
wasted = (int64_t)disk_block_max_by_space - (int64_t)disk_block_max_by_parity;
|
||||
wasted *= state->block_size;
|
||||
|
||||
if (wasted > 0)
|
||||
all_wasted += wasted;
|
||||
file_block_free += disk_block_max - disk_block_count;
|
||||
|
||||
printf("%8u", disk_file_count);
|
||||
printf("%8u", disk_file_fragmented);
|
||||
printf("%8u", disk_extra_fragment);
|
||||
if (wasted < -100LL * GIGA) {
|
||||
printf(" -");
|
||||
} else {
|
||||
printf("%8.1f", (double)wasted / GIGA);
|
||||
}
|
||||
printf("%8" PRIu64, disk_file_size / GIGA);
|
||||
|
||||
if (disk_block_max == 0 && disk_block_count == 0) {
|
||||
/* if the disk is empty and we don't have the free space info */
|
||||
printf(" -");
|
||||
printf(" - ");
|
||||
} else {
|
||||
printf("%8" PRIu64, (disk_block_max - disk_block_count) * (uint64_t)state->block_size / GIGA);
|
||||
printf(" %3u%%", perc(disk_block_count, disk_block_max));
|
||||
}
|
||||
printf(" %s\n", disk->name);
|
||||
|
||||
log_tag("summary:disk_file_count:%s:%u\n", disk->name, disk_file_count);
|
||||
log_tag("summary:disk_block_count:%s:%u\n", disk->name, disk_block_count);
|
||||
log_tag("summary:disk_fragmented_file_count:%s:%u\n", disk->name, disk_file_fragmented);
|
||||
log_tag("summary:disk_excess_fragment_count:%s:%u\n", disk->name, disk_extra_fragment);
|
||||
log_tag("summary:disk_zerosubsecond_file_count:%s:%u\n", disk->name, disk_file_zerosubsecond);
|
||||
log_tag("summary:disk_file_size:%s:%" PRIu64 "\n", disk->name, disk_file_size);
|
||||
log_tag("summary:disk_block_allocated:%s:%u\n", disk->name, disk_block_latest_used + 1);
|
||||
log_tag("summary:disk_block_total:%s:%u\n", disk->name, disk->total_blocks);
|
||||
log_tag("summary:disk_block_free:%s:%u\n", disk->name, disk->free_blocks);
|
||||
log_tag("summary:disk_block_max_by_space:%s:%u\n", disk->name, disk_block_max_by_space);
|
||||
log_tag("summary:disk_block_max_by_parity:%s:%u\n", disk->name, disk_block_max_by_parity);
|
||||
log_tag("summary:disk_block_max:%s:%u\n", disk->name, disk_block_max);
|
||||
log_tag("summary:disk_space_wasted:%s:%" PRId64 "\n", disk->name, wasted);
|
||||
}
|
||||
|
||||
/* totals */
|
||||
printf(" --------------------------------------------------------------------------\n");
|
||||
printf("%8u", file_count);
|
||||
printf("%8u", file_fragmented);
|
||||
printf("%8u", extra_fragment);
|
||||
printf("%8.1f", (double)all_wasted / GIGA);
|
||||
printf("%8" PRIu64, file_size / GIGA);
|
||||
printf("%8" PRIu64, file_block_free * state->block_size / GIGA);
|
||||
printf(" %3u%%", perc(file_block_count, file_block_count + file_block_free));
|
||||
printf("\n");
|
||||
|
||||
/* warn about invalid data free info */
|
||||
if (!free_not_zero)
|
||||
printf("\nWARNING! Free space info will be valid after the first sync.\n");
|
||||
|
||||
log_tag("summary:file_count:%u\n", file_count);
|
||||
log_tag("summary:file_block_count:%" PRIu64 "\n", file_block_count);
|
||||
log_tag("summary:fragmented_file_count:%u\n", file_fragmented);
|
||||
log_tag("summary:excess_fragment_count:%u\n", extra_fragment);
|
||||
log_tag("summary:zerosubsecond_file_count:%u\n", file_zerosubsecond);
|
||||
log_tag("summary:file_size:%" PRIu64 "\n", file_size);
|
||||
log_tag("summary:parity_size:%" PRIu64 "\n", blockmax * (uint64_t)state->block_size);
|
||||
log_tag("summary:parity_size_max:%" PRIu64 "\n", (blockmax + parity_block_free) * (uint64_t)state->block_size);
|
||||
log_tag("summary:hash:%s\n", hash_config_name(state->hash));
|
||||
log_tag("summary:prev_hash:%s\n", hash_config_name(state->prevhash));
|
||||
log_tag("summary:best_hash:%s\n", hash_config_name(state->besthash));
|
||||
log_flush();
|
||||
|
||||
/* copy the info a temp vector, and count bad/rehash/unsynced blocks */
|
||||
timemap = malloc_nofail(blockmax * sizeof(time_t));
|
||||
bad = 0;
|
||||
bad_first = 0;
|
||||
bad_last = 0;
|
||||
count = 0;
|
||||
rehash = 0;
|
||||
unsynced_blocks = 0;
|
||||
unscrubbed_blocks = 0;
|
||||
log_tag("block_count:%u\n", blockmax);
|
||||
for (i = 0; i < blockmax; ++i) {
|
||||
int one_invalid;
|
||||
int one_valid;
|
||||
|
||||
snapraid_info info = info_get(&state->infoarr, i);
|
||||
|
||||
/* for each disk */
|
||||
one_invalid = 0;
|
||||
one_valid = 0;
|
||||
for (node_disk = state->disklist; node_disk != 0; node_disk = node_disk->next) {
|
||||
struct snapraid_disk* disk = node_disk->data;
|
||||
struct snapraid_block* block = fs_par2block_find(disk, i);
|
||||
|
||||
if (block_has_file(block))
|
||||
one_valid = 1;
|
||||
if (block_has_invalid_parity(block))
|
||||
one_invalid = 1;
|
||||
}
|
||||
|
||||
/* if both valid and invalid, we need to update */
|
||||
if (one_invalid && one_valid) {
|
||||
++unsynced_blocks;
|
||||
}
|
||||
|
||||
/* skip unused blocks */
|
||||
if (info != 0) {
|
||||
time_t scrub_time;
|
||||
|
||||
if (info_get_bad(info)) {
|
||||
if (bad == 0)
|
||||
bad_first = i;
|
||||
bad_last = i;
|
||||
++bad;
|
||||
}
|
||||
|
||||
if (info_get_rehash(info))
|
||||
++rehash;
|
||||
|
||||
scrub_time = info_get_time(info);
|
||||
|
||||
if (info_get_justsynced(info)) {
|
||||
++unscrubbed_blocks;
|
||||
|
||||
/* mark the time as not scrubbed */
|
||||
scrub_time |= TIME_NEW;
|
||||
}
|
||||
|
||||
timemap[count++] = scrub_time;
|
||||
}
|
||||
|
||||
if (state->opt.gui) {
|
||||
if (info != 0)
|
||||
log_tag("block:%u:%" PRIu64 ":%s:%s:%s:%s\n", i, (uint64_t)info_get_time(info), one_valid ? "used" : "", one_invalid ? "unsynced" : "", info_get_bad(info) ? "bad" : "", info_get_rehash(info) ? "rehash" : "");
|
||||
else
|
||||
log_tag("block_noinfo:%u:%s:%s\n", i, one_valid ? "used" : "", one_invalid ? "unsynced" : "");
|
||||
}
|
||||
}
|
||||
|
||||
log_tag("summary:has_unsynced:%u\n", unsynced_blocks);
|
||||
log_tag("summary:has_unscrubbed:%u\n", unscrubbed_blocks);
|
||||
log_tag("summary:has_rehash:%u\n", rehash);
|
||||
log_tag("summary:has_bad:%u:%u:%u\n", bad, bad_first, bad_last);
|
||||
log_flush();
|
||||
|
||||
if (!count) {
|
||||
log_fatal("The array is empty.\n");
|
||||
free(timemap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sort the info to get the time info */
|
||||
qsort(timemap, count, sizeof(time_t), time_compare);
|
||||
|
||||
/* output the info map */
|
||||
i = 0;
|
||||
log_tag("info_count:%u\n", count);
|
||||
while (i < count) {
|
||||
unsigned j = i + 1;
|
||||
while (j < count && timemap[i] == timemap[j])
|
||||
++j;
|
||||
if ((timemap[i] & TIME_NEW) == 0) {
|
||||
log_tag("info_time:%" PRIu64 ":%u:scrubbed\n", (uint64_t)timemap[i], j - i);
|
||||
} else {
|
||||
log_tag("info_time:%" PRIu64 ":%u:new\n", (uint64_t)(timemap[i] & ~TIME_NEW), j - i);
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
|
||||
oldest = timemap[0];
|
||||
median = timemap[count / 2];
|
||||
newest = timemap[count - 1];
|
||||
dayoldest = day_ago(oldest, now);
|
||||
daymedian = day_ago(median, now);
|
||||
daynewest = day_ago(newest, now);
|
||||
|
||||
/* compute graph limits */
|
||||
barpos = 0;
|
||||
barmax = 0;
|
||||
for (i = 0; i < GRAPH_COLUMN; ++i) {
|
||||
time_t limit;
|
||||
unsigned step_scrubbed, step_new;
|
||||
|
||||
limit = oldest + (newest - oldest) * (i + 1) / GRAPH_COLUMN;
|
||||
|
||||
step_scrubbed = 0;
|
||||
step_new = 0;
|
||||
while (barpos < count && timemap[barpos] <= limit) {
|
||||
if ((timemap[barpos] & TIME_NEW) != 0)
|
||||
++step_new;
|
||||
else
|
||||
++step_scrubbed;
|
||||
++barpos;
|
||||
}
|
||||
|
||||
if (step_new + step_scrubbed > barmax)
|
||||
barmax = step_new + step_scrubbed;
|
||||
|
||||
bar_scrubbed[i] = step_scrubbed;
|
||||
bar_new[i] = step_new;
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
/* print the graph */
|
||||
for (y = 0; y < GRAPH_ROW; ++y) {
|
||||
if (y == 0)
|
||||
printf("%3u%%|", barmax * 100 / count);
|
||||
else if (y == GRAPH_ROW - 1)
|
||||
printf(" 0%%|");
|
||||
else if (y == GRAPH_ROW / 2)
|
||||
printf("%3u%%|", barmax * 50 / count);
|
||||
else
|
||||
printf(" |");
|
||||
for (x = 0; x < GRAPH_COLUMN; ++x) {
|
||||
unsigned pivot_upper = barmax * (GRAPH_ROW - y) / GRAPH_ROW;
|
||||
unsigned pivot_lower = barmax * (GRAPH_ROW - 1 - y) / GRAPH_ROW;
|
||||
unsigned both = bar_scrubbed[x] + bar_new[x];
|
||||
unsigned scrubbed = bar_scrubbed[x];
|
||||
|
||||
if (both > pivot_upper) {
|
||||
if (scrubbed > pivot_lower)
|
||||
printf("*");
|
||||
else
|
||||
printf("o");
|
||||
} else if (both > pivot_lower) {
|
||||
if (scrubbed == both)
|
||||
printf("*");
|
||||
else
|
||||
printf("o");
|
||||
} else {
|
||||
if (y == GRAPH_ROW - 1)
|
||||
printf("_");
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf(" %3u days ago of the last scrub/sync %3u\n", dayoldest, daynewest);
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("The oldest block was scrubbed %u days ago, the median %u, the newest %u.\n", dayoldest, daymedian, daynewest);
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (unsynced_blocks) {
|
||||
printf("WARNING! The array is NOT fully synced.\n");
|
||||
printf("You have a sync in progress at %u%%.\n", (blockmax - unsynced_blocks) * 100 / blockmax);
|
||||
} else {
|
||||
printf("No sync is in progress.\n");
|
||||
}
|
||||
|
||||
if (unscrubbed_blocks) {
|
||||
printf("The %u%% of the array is not scrubbed.\n", (unscrubbed_blocks * 100 + blockmax - 1) / blockmax);
|
||||
} else {
|
||||
printf("The full array was scrubbed at least one time.\n");
|
||||
}
|
||||
|
||||
if (file_zerosubsecond) {
|
||||
printf("You have %u files with zero sub-second timestamp.\n", file_zerosubsecond);
|
||||
printf("Run the 'touch' command to set it to a not zero value.\n");
|
||||
} else {
|
||||
printf("No file has a zero sub-second timestamp.\n");
|
||||
}
|
||||
|
||||
if (rehash) {
|
||||
printf("You have a rehash in progress at %u%%.\n", (count - rehash) * 100 / count);
|
||||
} else {
|
||||
if (state->besthash != state->hash) {
|
||||
printf("No rehash is in progress, but for optimal performance one is recommended.\n");
|
||||
} else {
|
||||
printf("No rehash is in progress or needed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (bad) {
|
||||
block_off_t bad_print;
|
||||
|
||||
printf("DANGER! In the array there are %u errors!\n\n", bad);
|
||||
|
||||
printf("They are from block %u to %u, specifically at blocks:", bad_first, bad_last);
|
||||
|
||||
/* print some of the errors */
|
||||
bad_print = 0;
|
||||
for (i = 0; i < blockmax; ++i) {
|
||||
snapraid_info info = info_get(&state->infoarr, i);
|
||||
|
||||
/* skip unused blocks */
|
||||
if (info == 0)
|
||||
continue;
|
||||
|
||||
if (info_get_bad(info)) {
|
||||
printf(" %u", i);
|
||||
++bad_print;
|
||||
}
|
||||
|
||||
if (bad_print > 100) {
|
||||
printf(" and %u more...", bad - bad_print);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
printf("To fix them use the command 'snapraid -e fix'.\n");
|
||||
printf("The errors will disappear from the 'status' at the next 'scrub' command.\n");
|
||||
} else {
|
||||
printf("No error detected.\n");
|
||||
}
|
||||
|
||||
/* free the temp vector */
|
||||
free(timemap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
757
cmdline/stream.c
Normal file
757
cmdline/stream.c
Normal file
@ -0,0 +1,757 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "util.h"
|
||||
#include "stream.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* stream */
|
||||
|
||||
unsigned STREAM_SIZE = 64 * 1024;
|
||||
|
||||
STREAM* sopen_read(const char* file)
|
||||
{
|
||||
#if HAVE_POSIX_FADVISE
|
||||
int ret;
|
||||
#endif
|
||||
STREAM* s = malloc_nofail(sizeof(STREAM));
|
||||
|
||||
s->handle_size = 1;
|
||||
s->handle = malloc_nofail(sizeof(struct stream_handle));
|
||||
|
||||
pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file);
|
||||
s->handle[0].f = open(file, O_RDONLY | O_BINARY | O_SEQUENTIAL);
|
||||
if (s->handle[0].f == -1) {
|
||||
free(s->handle);
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
/* advise sequential access */
|
||||
ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
if (ret == ENOSYS) {
|
||||
log_fatal("WARNING! fadvise() is not supported in this platform. Performance may not be optimal!\n");
|
||||
/* call is not supported, like in armhf, see posix_fadvise manpage */
|
||||
ret = 0;
|
||||
}
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
close(s->handle[0].f);
|
||||
free(s->handle);
|
||||
free(s);
|
||||
errno = ret; /* posix_fadvise return the error code */
|
||||
return 0;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
#endif
|
||||
|
||||
s->buffer = malloc_nofail_test(STREAM_SIZE);
|
||||
s->pos = s->buffer;
|
||||
s->end = s->buffer;
|
||||
s->state = STREAM_STATE_READ;
|
||||
s->state_index = 0;
|
||||
s->offset = 0;
|
||||
s->offset_uncached = 0;
|
||||
s->crc = 0;
|
||||
s->crc_uncached = 0;
|
||||
s->crc_stream = CRC_IV;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
STREAM* sopen_multi_write(unsigned count)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
STREAM* s = malloc_nofail(sizeof(STREAM));
|
||||
|
||||
s->handle_size = count;
|
||||
s->handle = malloc_nofail(count * sizeof(struct stream_handle));
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
s->handle[i].f = -1;
|
||||
|
||||
s->buffer = malloc_nofail_test(STREAM_SIZE);
|
||||
s->pos = s->buffer;
|
||||
s->end = s->buffer + STREAM_SIZE;
|
||||
s->state = STREAM_STATE_WRITE;
|
||||
s->state_index = 0;
|
||||
s->offset = 0;
|
||||
s->offset_uncached = 0;
|
||||
s->crc = 0;
|
||||
s->crc_uncached = 0;
|
||||
s->crc_stream = CRC_IV;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int sopen_multi_file(STREAM* s, unsigned i, const char* file)
|
||||
{
|
||||
#if HAVE_POSIX_FADVISE
|
||||
int ret;
|
||||
#endif
|
||||
int f;
|
||||
|
||||
pathcpy(s->handle[i].path, sizeof(s->handle[i].path), file);
|
||||
|
||||
f = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_SEQUENTIAL, 0600);
|
||||
if (f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
#if HAVE_POSIX_FADVISE
|
||||
/* advise sequential access */
|
||||
ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
|
||||
if (ret == ENOSYS) {
|
||||
/* call is not supported, like in armhf, see posix_fadvise manpage */
|
||||
ret = 0;
|
||||
}
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
close(f);
|
||||
errno = ret; /* posix_fadvise return the error code */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
#endif
|
||||
|
||||
s->handle[i].f = f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
STREAM* sopen_write(const char* file)
|
||||
{
|
||||
STREAM* s = sopen_multi_write(1);
|
||||
|
||||
if (sopen_multi_file(s, 0, file) != 0) {
|
||||
sclose(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int sclose(STREAM* s)
|
||||
{
|
||||
int fail = 0;
|
||||
unsigned i;
|
||||
|
||||
if (s->state == STREAM_STATE_WRITE) {
|
||||
if (sflush(s) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
fail = 1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < s->handle_size; ++i) {
|
||||
if (close(s->handle[i].f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
fail = 1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
free(s->handle);
|
||||
free(s->buffer);
|
||||
free(s);
|
||||
|
||||
if (fail) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int shandle(STREAM* s)
|
||||
{
|
||||
if (!s->handle_size) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return s->handle[0].f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill the read stream buffer.
|
||||
* \return 0 if at least on char is read, or EOF on error.
|
||||
*/
|
||||
static int sfill(STREAM* s)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
if (s->state != STREAM_STATE_READ) {
|
||||
/* LCOV_EXCL_START */
|
||||
return EOF;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = read(s->handle[0].f, s->buffer, STREAM_SIZE);
|
||||
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
s->state = STREAM_STATE_ERROR;
|
||||
return EOF;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (ret == 0) {
|
||||
s->state = STREAM_STATE_EOF;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* update the crc */
|
||||
s->crc_uncached = s->crc;
|
||||
s->crc = crc32c(s->crc, s->buffer, ret);
|
||||
|
||||
/* update the offset */
|
||||
s->offset_uncached = s->offset;
|
||||
s->offset += ret;
|
||||
|
||||
s->pos = s->buffer;
|
||||
s->end = s->buffer + ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sdeplete(STREAM* s, unsigned char* last)
|
||||
{
|
||||
/* last four bytes */
|
||||
last[0] = 0;
|
||||
last[1] = 0;
|
||||
last[2] = 0;
|
||||
last[3] = 0;
|
||||
|
||||
while (1) {
|
||||
/* increase the position up to 4 bytes before the end */
|
||||
if (s->pos + 4 <= s->end)
|
||||
s->pos = s->end - 4;
|
||||
|
||||
/* insert the last 4 bytes */
|
||||
while (s->pos < s->end) {
|
||||
last[0] = last[1];
|
||||
last[1] = last[2];
|
||||
last[2] = last[3];
|
||||
last[3] = *s->pos++;
|
||||
}
|
||||
|
||||
/* fill again the buffer until the end of the file */
|
||||
if (sfill(s) != 0) {
|
||||
/* on error fail */
|
||||
if (serror(s)) {
|
||||
/* LCOV_EXCL_START */
|
||||
return EOF;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* on EOF terminate */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sflush(STREAM* s)
|
||||
{
|
||||
ssize_t ret;
|
||||
ssize_t size;
|
||||
unsigned i;
|
||||
|
||||
if (s->state != STREAM_STATE_WRITE) {
|
||||
/* LCOV_EXCL_START */
|
||||
return EOF;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
size = s->pos - s->buffer;
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < s->handle_size; ++i) {
|
||||
ret = write(s->handle[i].f, s->buffer, size);
|
||||
|
||||
if (ret != size) {
|
||||
/* LCOV_EXCL_START */
|
||||
s->state = STREAM_STATE_ERROR;
|
||||
s->state_index = i;
|
||||
return EOF;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the crc *after* writing the data.
|
||||
*
|
||||
* This must be done after the file write,
|
||||
* to be able to detect memory errors on the buffer,
|
||||
* happening during the write.
|
||||
*/
|
||||
s->crc = crc32c(s->crc, s->buffer, size);
|
||||
s->crc_uncached = s->crc;
|
||||
|
||||
/* update the offset */
|
||||
s->offset += size;
|
||||
s->offset_uncached = s->offset;
|
||||
|
||||
s->pos = s->buffer;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t stell(STREAM* s)
|
||||
{
|
||||
return s->offset_uncached + (s->pos - s->buffer);
|
||||
}
|
||||
|
||||
uint32_t scrc(STREAM*s)
|
||||
{
|
||||
return crc32c(s->crc_uncached, s->buffer, s->pos - s->buffer);
|
||||
}
|
||||
|
||||
uint32_t scrc_stream(STREAM*s)
|
||||
{
|
||||
return s->crc_stream ^ CRC_IV;
|
||||
}
|
||||
|
||||
int sgetc_uncached(STREAM* s)
|
||||
{
|
||||
/* if at the end of the buffer, fill it */
|
||||
if (s->pos == s->end && sfill(s) != 0)
|
||||
return EOF;
|
||||
return *s->pos++;
|
||||
}
|
||||
|
||||
int sgettok(STREAM* f, char* str, int size)
|
||||
{
|
||||
char* i = str;
|
||||
char* send = str + size;
|
||||
int c;
|
||||
|
||||
while (1) {
|
||||
c = sgetc(f);
|
||||
if (c == EOF) {
|
||||
break;
|
||||
}
|
||||
if (c == ' ' || c == '\t') {
|
||||
sungetc(c, f);
|
||||
break;
|
||||
}
|
||||
if (c == '\n') {
|
||||
/* remove ending carrige return to support the Windows CR+LF format */
|
||||
if (i != str && i[-1] == '\r')
|
||||
--i;
|
||||
sungetc(c, f);
|
||||
break;
|
||||
}
|
||||
|
||||
*i++ = c;
|
||||
|
||||
if (i == send) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
*i = 0;
|
||||
|
||||
return i - str;
|
||||
}
|
||||
|
||||
int sread(STREAM* f, void* void_data, unsigned size)
|
||||
{
|
||||
unsigned char* data = void_data;
|
||||
|
||||
/* if there is enough space in memory */
|
||||
if (sptrlookup(f, size)) {
|
||||
/* optimized version with all the data in memory */
|
||||
unsigned char* pos = sptrget(f);
|
||||
|
||||
/* copy it */
|
||||
while (size--)
|
||||
*data++ = *pos++;
|
||||
|
||||
sptrset(f, pos);
|
||||
} else {
|
||||
/* standard version using sgetc() */
|
||||
while (size--) {
|
||||
int c = sgetc(f);
|
||||
if (c == EOF) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
*data++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sgetline(STREAM* f, char* str, int size)
|
||||
{
|
||||
char* i = str;
|
||||
char* send = str + size;
|
||||
int c;
|
||||
|
||||
/* if there is enough data in memory */
|
||||
if (sptrlookup(f, size)) {
|
||||
/* optimized version with all the data in memory */
|
||||
unsigned char* pos = sptrget(f);
|
||||
|
||||
while (1) {
|
||||
c = *pos++;
|
||||
if (c == '\n') {
|
||||
/* remove ending carrige return to support the Windows CR+LF format */
|
||||
if (i != str && i[-1] == '\r')
|
||||
--i;
|
||||
--pos;
|
||||
break;
|
||||
}
|
||||
|
||||
*i++ = c;
|
||||
|
||||
if (i == send) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
sptrset(f, pos);
|
||||
} else {
|
||||
while (1) {
|
||||
c = sgetc(f);
|
||||
if (c == EOF) {
|
||||
/* LCOV_EXCL_START */
|
||||
break;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
if (c == '\n') {
|
||||
/* remove ending carrige return to support the Windows CR+LF format */
|
||||
if (i != str && i[-1] == '\r')
|
||||
--i;
|
||||
sungetc(c, f);
|
||||
break;
|
||||
}
|
||||
|
||||
*i++ = c;
|
||||
|
||||
if (i == send) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*i = 0;
|
||||
|
||||
return i - str;
|
||||
}
|
||||
|
||||
int sgetlasttok(STREAM* f, char* str, int size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = sgetline(f, str, size);
|
||||
if (ret < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return ret;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
while (ret > 0 && (str[ret - 1] == ' ' || str[ret - 1] == '\t'))
|
||||
--ret;
|
||||
|
||||
str[ret] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sgetu32(STREAM* f, uint32_t* value)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = sgetc(f);
|
||||
if (c >= '0' && c <= '9') {
|
||||
uint32_t v;
|
||||
|
||||
v = c - '0';
|
||||
|
||||
c = sgetc(f);
|
||||
while (c >= '0' && c <= '9') {
|
||||
v *= 10;
|
||||
v += c - '0';
|
||||
c = sgetc(f);
|
||||
}
|
||||
|
||||
*value = v;
|
||||
|
||||
sungetc(c, f);
|
||||
return 0;
|
||||
} else {
|
||||
/* LCOV_EXCL_START */
|
||||
/* nothing read */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
int sgetb32(STREAM* f, uint32_t* value)
|
||||
{
|
||||
uint32_t v;
|
||||
unsigned char b;
|
||||
unsigned char s;
|
||||
int c;
|
||||
|
||||
v = 0;
|
||||
s = 0;
|
||||
loop:
|
||||
c = sgetc(f);
|
||||
if (c == EOF) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
b = (unsigned char)c;
|
||||
if ((b & 0x80) == 0) {
|
||||
v |= (uint32_t)b << s;
|
||||
s += 7;
|
||||
if (s >= 32) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
|
||||
v |= (uint32_t)(b & 0x7f) << s;
|
||||
|
||||
*value = v;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sgetb64(STREAM* f, uint64_t* value)
|
||||
{
|
||||
uint64_t v;
|
||||
unsigned char b;
|
||||
unsigned char s;
|
||||
int c;
|
||||
|
||||
v = 0;
|
||||
s = 0;
|
||||
loop:
|
||||
c = sgetc(f);
|
||||
if (c == EOF) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
b = (unsigned char)c;
|
||||
if ((b & 0x80) == 0) {
|
||||
v |= (uint64_t)b << s;
|
||||
s += 7;
|
||||
if (s >= 64) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
goto loop;
|
||||
}
|
||||
|
||||
v |= (uint64_t)(b & 0x7f) << s;
|
||||
|
||||
*value = v;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sgetble32(STREAM* f, uint32_t* value)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
if (sread(f, buf, 4) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
*value = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sgetbs(STREAM* f, char* str, int size)
|
||||
{
|
||||
uint32_t len;
|
||||
|
||||
if (sgetb32(f, &len) < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (len + 1 > (uint32_t)size) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
str[len] = 0;
|
||||
|
||||
return sread(f, str, (int)len);
|
||||
}
|
||||
|
||||
int swrite(const void* void_data, unsigned size, STREAM* f)
|
||||
{
|
||||
const unsigned char* data = void_data;
|
||||
|
||||
/* if there is enough space in memory */
|
||||
if (sptrlookup(f, size)) {
|
||||
/* optimized version with all the data in memory */
|
||||
unsigned char* pos = sptrget(f);
|
||||
|
||||
/**
|
||||
* Update the crc *before* writing the data in the buffer
|
||||
*
|
||||
* This must be done before the memory write,
|
||||
* to be able to detect memory errors on the buffer,
|
||||
* happening before we write it on the file.
|
||||
*/
|
||||
f->crc_stream = crc32c_plain(f->crc_stream, data, size);
|
||||
|
||||
/* copy it */
|
||||
while (size--)
|
||||
*pos++ = *data++;
|
||||
|
||||
sptrset(f, pos);
|
||||
} else {
|
||||
/* standard version using sputc() */
|
||||
while (size--) {
|
||||
if (sputc(*data++, f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sputb32(uint32_t value, STREAM* s)
|
||||
{
|
||||
unsigned char b;
|
||||
unsigned char buf[16];
|
||||
unsigned i;
|
||||
|
||||
i = 0;
|
||||
loop:
|
||||
b = value & 0x7f;
|
||||
value >>= 7;
|
||||
|
||||
if (value) {
|
||||
buf[i++] = b;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
buf[i++] = b | 0x80;
|
||||
|
||||
return swrite(buf, i, s);
|
||||
}
|
||||
|
||||
int sputb64(uint64_t value, STREAM* s)
|
||||
{
|
||||
unsigned char b;
|
||||
unsigned char buf[16];
|
||||
unsigned i;
|
||||
|
||||
i = 0;
|
||||
loop:
|
||||
b = value & 0x7f;
|
||||
value >>= 7;
|
||||
|
||||
if (value) {
|
||||
buf[i++] = b;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
buf[i++] = b | 0x80;
|
||||
|
||||
return swrite(buf, i, s);
|
||||
}
|
||||
|
||||
int sputble32(uint32_t value, STREAM* s)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
|
||||
buf[0] = value & 0xFF;
|
||||
buf[1] = (value >> 8) & 0xFF;
|
||||
buf[2] = (value >> 16) & 0xFF;
|
||||
buf[3] = (value >> 24) & 0xFF;
|
||||
|
||||
return swrite(buf, 4, s);
|
||||
}
|
||||
|
||||
int sputbs(const char* str, STREAM* f)
|
||||
{
|
||||
size_t len = strlen(str);
|
||||
|
||||
if (sputb32(len, f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return swrite(str, len, f);
|
||||
}
|
||||
|
||||
#if HAVE_FSYNC
|
||||
int ssync(STREAM* s)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < s->handle_size; ++i) {
|
||||
if (fsync(s->handle[i].f) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
s->state = STREAM_STATE_ERROR;
|
||||
s->state_index = i;
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
416
cmdline/stream.h
Normal file
416
cmdline/stream.h
Normal file
@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __STREAM_H
|
||||
#define __STREAM_H
|
||||
|
||||
#include "util.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* stream */
|
||||
|
||||
/**
|
||||
* Size of the buffer of the stream.
|
||||
*
|
||||
* It's not a constant for testing purpose.
|
||||
*/
|
||||
unsigned STREAM_SIZE;
|
||||
|
||||
#define STREAM_STATE_READ 0 /**< The stream is in a normal state of read. */
|
||||
#define STREAM_STATE_WRITE 1 /**< The stream is in a normal state of write. */
|
||||
#define STREAM_STATE_ERROR -1 /**< An error was encountered. */
|
||||
#define STREAM_STATE_EOF 2 /**< The end of file was encountered. */
|
||||
|
||||
struct stream_handle {
|
||||
int f; /**< Handle of the file. */
|
||||
char path[PATH_MAX]; /**< Path of the file. */
|
||||
};
|
||||
|
||||
struct stream {
|
||||
unsigned char* buffer; /**< Buffer of the stream. */
|
||||
unsigned char* pos; /**< Current position in the buffer. */
|
||||
unsigned char* end; /**< End position of the buffer. */
|
||||
int state; /**< State of the stream. One of STREAM_STATE. */
|
||||
int state_index; /**< Index of the handle causing a state change. */
|
||||
unsigned handle_size; /**< Number of handles. */
|
||||
struct stream_handle* handle; /**< Set of handles. */
|
||||
off_t offset; /**< Offset into the file. */
|
||||
off_t offset_uncached; /**< Offset into the file excluding the cached data. */
|
||||
|
||||
/**
|
||||
* CRC of the data read or written in the file.
|
||||
*
|
||||
* If reading, it's the CRC of all data read from the file,
|
||||
* including the one in the buffer.
|
||||
* If writing it's all the data wrote to the file,
|
||||
* excluding the one still in buffer yet to be written.
|
||||
*/
|
||||
uint32_t crc;
|
||||
|
||||
/**
|
||||
* CRC of the file excluding the cached data in the buffer.
|
||||
*
|
||||
* If reading, it's the CRC of the data read from the file,
|
||||
* excluding the one in the buffer.
|
||||
* If writing it's all the data wrote to the file,
|
||||
* excluding the one still in buffer yet to be written.
|
||||
*/
|
||||
uint32_t crc_uncached;
|
||||
|
||||
/**
|
||||
* CRC of the data written to the stream.
|
||||
*
|
||||
* This is an extra check of the data that is written to
|
||||
* file to ensure that it's consistent even in case
|
||||
* of memory errors.
|
||||
*
|
||||
* This extra check takes about 2 seconds for each GB of
|
||||
* content file with the Intel CRC instruction,
|
||||
* and about 4 seconds without it.
|
||||
* But usually this doesn't slow down the write process,
|
||||
* as the disk is the bottle-neck.
|
||||
*
|
||||
* Note that this CRC doesn't have the IV processing.
|
||||
*
|
||||
* Not used in reading.
|
||||
* In writing, it's all the data wrote calling sput() functions.
|
||||
*/
|
||||
uint32_t crc_stream;
|
||||
};
|
||||
|
||||
/**
|
||||
* Opaque STREAM type. Like ::FILE.
|
||||
*/
|
||||
typedef struct stream STREAM;
|
||||
|
||||
/**
|
||||
* Open a stream for reading. Like fopen("r").
|
||||
*/
|
||||
STREAM* sopen_read(const char* file);
|
||||
|
||||
/**
|
||||
* Open a stream for writing. Like fopen("w").
|
||||
*/
|
||||
STREAM* sopen_write(const char* file);
|
||||
|
||||
/**
|
||||
* Open a set of streams for writing. Like fopen("w").
|
||||
*/
|
||||
STREAM* sopen_multi_write(unsigned count);
|
||||
|
||||
/**
|
||||
* Specify the file to open.
|
||||
*/
|
||||
int sopen_multi_file(STREAM* s, unsigned i, const char* file);
|
||||
|
||||
/**
|
||||
* Close a stream. Like fclose().
|
||||
*/
|
||||
int sclose(STREAM* s);
|
||||
|
||||
/**
|
||||
* Return the handle of the file.
|
||||
* In case of multi file, the first one is returned.
|
||||
*/
|
||||
int shandle(STREAM* s);
|
||||
|
||||
/**
|
||||
* Read the stream until the end, and return the latest 4 chars.
|
||||
* The CRC of the file is also computed, and you can get it using scrc().
|
||||
* \return 0 on success, or EOF on error.
|
||||
*/
|
||||
int sdeplete(STREAM* s, unsigned char* last);
|
||||
|
||||
/**
|
||||
* Flush the write stream buffer.
|
||||
* \return 0 on success, or EOF on error.
|
||||
*/
|
||||
int sflush(STREAM* s);
|
||||
|
||||
/**
|
||||
* Get the file pointer.
|
||||
*/
|
||||
int64_t stell(STREAM* s);
|
||||
|
||||
/**
|
||||
* Get the CRC of the processed data.
|
||||
*/
|
||||
uint32_t scrc(STREAM* s);
|
||||
|
||||
/**
|
||||
* Get the CRC of the processed data in put.
|
||||
*/
|
||||
uint32_t scrc_stream(STREAM* s);
|
||||
|
||||
/**
|
||||
* Check if the buffer has enough data loaded.
|
||||
*/
|
||||
static inline int sptrlookup(STREAM* s, int size)
|
||||
{
|
||||
return s->pos + size <= s->end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current stream ptr.
|
||||
*/
|
||||
static inline unsigned char* sptrget(STREAM* s)
|
||||
{
|
||||
return s->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current stream ptr.
|
||||
*/
|
||||
static inline void sptrset(STREAM* s, unsigned char* ptr)
|
||||
{
|
||||
s->pos = ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the error status. Like ferror().
|
||||
*/
|
||||
static inline int serror(STREAM* s)
|
||||
{
|
||||
return s->state == STREAM_STATE_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the eof status. Like feof().
|
||||
*/
|
||||
static inline int seof(STREAM* s)
|
||||
{
|
||||
return s->state == STREAM_STATE_EOF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the handle that caused the error.
|
||||
*/
|
||||
static inline int serrorindex(STREAM* s)
|
||||
{
|
||||
return s->state_index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path of the handle that caused the error.
|
||||
*/
|
||||
static inline const char* serrorfile(STREAM* s)
|
||||
{
|
||||
return s->handle[s->state_index].path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the stream. Like fsync().
|
||||
*/
|
||||
int ssync(STREAM* s);
|
||||
|
||||
/****************************************************************************/
|
||||
/* get */
|
||||
|
||||
/**
|
||||
* \internal Used by sgetc().
|
||||
* \note Don't call this directly, but use sgetc().
|
||||
*/
|
||||
int sgetc_uncached(STREAM* s);
|
||||
|
||||
/**
|
||||
* Read a char. Like fgetc().
|
||||
*/
|
||||
static inline int sgetc(STREAM* s)
|
||||
{
|
||||
if (tommy_unlikely(s->pos == s->end))
|
||||
return sgetc_uncached(s);
|
||||
return *s->pos++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unread a char.
|
||||
* Like ungetc() but you have to unget the same char read.
|
||||
*/
|
||||
static inline void sungetc(int c, STREAM* s)
|
||||
{
|
||||
if (c != EOF)
|
||||
--s->pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a fixed amount of chars.
|
||||
* Return 0 on success, or -1 on error.
|
||||
*/
|
||||
int sread(STREAM* f, void* void_data, unsigned size);
|
||||
|
||||
/**
|
||||
* Get a char from a stream, ignoring one '\r'.
|
||||
*/
|
||||
static inline int sgeteol(STREAM* f)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = sgetc(f);
|
||||
if (c == '\r')
|
||||
c = sgetc(f);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all the spaces and tabs.
|
||||
* Return the number of spaces and tabs read.
|
||||
*/
|
||||
static inline int sgetspace(STREAM* f)
|
||||
{
|
||||
int count = 0;
|
||||
int c;
|
||||
|
||||
c = sgetc(f);
|
||||
while (c == ' ' || c == '\t') {
|
||||
++count;
|
||||
c = sgetc(f);
|
||||
}
|
||||
|
||||
sungetc(c, f);
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read until the first space or tab.
|
||||
* Stop at the first ' ', '\t', '\n' or EOF.
|
||||
* Return <0 if the buffer is too small, or the number of chars read.
|
||||
*/
|
||||
int sgettok(STREAM* f, char* str, int size);
|
||||
|
||||
/**
|
||||
* Read until the end of line.
|
||||
* Stop at the first '\n' or EOF. Note that '\n' is left in the stream.
|
||||
* Return <0 if the buffer is too small, or the number of chars read.
|
||||
*/
|
||||
int sgetline(STREAM* f, char* str, int size);
|
||||
|
||||
/**
|
||||
* Like sgetline() but remove ' ' and '\t' at the end.
|
||||
*/
|
||||
int sgetlasttok(STREAM* f, char* str, int size);
|
||||
|
||||
/**
|
||||
* Read a 32 bit number.
|
||||
* Stop at the first not digit char or EOF.
|
||||
* Return <0 if there isn't enough to read.
|
||||
*/
|
||||
int sgetu32(STREAM* f, uint32_t* value);
|
||||
|
||||
/****************************************************************************/
|
||||
/* binary get */
|
||||
|
||||
/**
|
||||
* Read a binary 32 bit number in packet format.
|
||||
* Return <0 if there isn't enough to read.
|
||||
*/
|
||||
int sgetb32(STREAM* f, uint32_t* value);
|
||||
|
||||
/**
|
||||
* Read a binary 64 bit number in packet format.
|
||||
* Return <0 if there isn't enough to read.
|
||||
*/
|
||||
int sgetb64(STREAM* f, uint64_t* value);
|
||||
|
||||
/**
|
||||
* Read a binary 32 bit number in little endian format.
|
||||
* Return <0 if there isn't enough to read.
|
||||
*/
|
||||
int sgetble32(STREAM* f, uint32_t* value);
|
||||
|
||||
/**
|
||||
* Read a binary string.
|
||||
* Return -1 on error or if the buffer is too small, or the number of chars read.
|
||||
*/
|
||||
int sgetbs(STREAM* f, char* str, int size);
|
||||
|
||||
/****************************************************************************/
|
||||
/* put */
|
||||
|
||||
/**
|
||||
* Write a char. Like fputc().
|
||||
* Return 0 on success or -1 on error.
|
||||
*/
|
||||
static inline int sputc(int c, STREAM* s)
|
||||
{
|
||||
if (s->pos == s->end) {
|
||||
if (sflush(s) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the crc *before* writing the data in the buffer
|
||||
*
|
||||
* This must be done before the memory write,
|
||||
* to be able to detect memory errors on the buffer,
|
||||
* happening before we write it on the file.
|
||||
*/
|
||||
s->crc_stream = crc32c_plain_char(s->crc_stream, c);
|
||||
|
||||
*s->pos++ = c;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a end of line.
|
||||
* Return 0 on success or -1 on error.
|
||||
*/
|
||||
static inline int sputeol(STREAM* s)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (sputc('\r', s) != 0)
|
||||
return -1;
|
||||
#endif
|
||||
return sputc('\n', s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a sized string.
|
||||
* Return 0 on success or -1 on error.
|
||||
*/
|
||||
int swrite(const void* data, unsigned size, STREAM* f);
|
||||
|
||||
/****************************************************************************/
|
||||
/* binary put */
|
||||
|
||||
/**
|
||||
* Write a binary 32 bit number in packed format.
|
||||
* Return 0 on success or -1 on error.
|
||||
*/
|
||||
int sputb32(uint32_t value, STREAM* s);
|
||||
|
||||
/**
|
||||
* Write a binary 64 bit number in packed format.
|
||||
* Return 0 on success or -1 on error.
|
||||
*/
|
||||
int sputb64(uint64_t value, STREAM* s);
|
||||
|
||||
/**
|
||||
* Write a binary 32 bit number in little endian format.
|
||||
* Return 0 on success or -1 on error.
|
||||
*/
|
||||
int sputble32(uint32_t value, STREAM* s);
|
||||
|
||||
/**
|
||||
* Write a binary string.
|
||||
* Return 0 on success or -1 on error.
|
||||
*/
|
||||
int sputbs(const char* str, STREAM* s);
|
||||
|
||||
#endif
|
||||
|
1716
cmdline/support.c
Normal file
1716
cmdline/support.c
Normal file
File diff suppressed because it is too large
Load Diff
437
cmdline/support.h
Normal file
437
cmdline/support.h
Normal file
@ -0,0 +1,437 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __SUPPORT_H
|
||||
#define __SUPPORT_H
|
||||
|
||||
/****************************************************************************/
|
||||
/* lock */
|
||||
|
||||
/**
|
||||
* Initialize and destroy the locks.
|
||||
*/
|
||||
void lock_init(void);
|
||||
void lock_done(void);
|
||||
|
||||
/**
|
||||
* Lock used for printf.
|
||||
*
|
||||
* In Windows printf() is not atomic, and multiple threads
|
||||
* will have output interleaved.
|
||||
*
|
||||
* Note that even defining __USE_MINGW_ANSI_STDIO the problem persists.
|
||||
*
|
||||
* See for example:
|
||||
*
|
||||
* Weird output when I use pthread and printf.
|
||||
* http://stackoverflow.com/questions/13190254/weird-output-when-i-use-pthread-and-printf
|
||||
*
|
||||
* This is also required in other OS because we split output in stdlog in
|
||||
* two fprintf calls.
|
||||
*/
|
||||
void lock_msg(void);
|
||||
void unlock_msg(void);
|
||||
|
||||
/**
|
||||
* Lock used for memory counter.
|
||||
*/
|
||||
void lock_memory(void);
|
||||
void unlock_memory(void);
|
||||
|
||||
/****************************************************************************/
|
||||
/* log */
|
||||
|
||||
/**
|
||||
* Fatal error messages.
|
||||
*
|
||||
* Messages printed before an early termination.
|
||||
*
|
||||
* These messages go in the log file and in stderr unconditionally.
|
||||
*/
|
||||
void log_fatal(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Unexpected error messages.
|
||||
*
|
||||
* Messages reporting error conditions that don't prevent the program to run.
|
||||
*
|
||||
* Some of them could be also serious errors, like "silent errors".
|
||||
* In such case, the summary result is always printed as error,
|
||||
* and we are sure to notify the user in some way.
|
||||
*
|
||||
* These messages go in the log file if specified, otherwise they go in stderr.
|
||||
*/
|
||||
void log_error(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Expected error messages, without fallback to stderr.
|
||||
*
|
||||
* These errors are "someway" expected, and then they never go to screen.
|
||||
* For example, when undeleting missing files, the messages for missing files
|
||||
* are not shown.
|
||||
*
|
||||
* These messages go in the log file if specified, otherwise they are lost.
|
||||
*/
|
||||
void log_expected(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Tag messages.
|
||||
*
|
||||
* Messages are in tag format, like "tag:entry:...".
|
||||
*
|
||||
* These messages never go on the screen, but only in the log file if specified.
|
||||
*
|
||||
* Note that this function, allows not \n terminated strings.
|
||||
*
|
||||
* These messages are buffered. Use msg_flush() to flush them.
|
||||
*/
|
||||
void log_tag(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Flush the log.
|
||||
*/
|
||||
void log_flush(void);
|
||||
|
||||
/**
|
||||
* Pointer to log function.
|
||||
*/
|
||||
typedef void fptr(const char* format, ...);
|
||||
|
||||
/****************************************************************************/
|
||||
/* message */
|
||||
|
||||
/**
|
||||
* Message levels.
|
||||
*
|
||||
* The levels control the amount of information printed on the screen.
|
||||
* Note that log_fatal(), log_error(), log_expected() and log_tag() are not affected by this option.
|
||||
*
|
||||
* From the most quiet to the most verbose.
|
||||
*/
|
||||
#define MSG_STATUS -3
|
||||
#define MSG_INFO -2
|
||||
#define MSG_PROGRESS -1
|
||||
#define MSG_BAR 0
|
||||
#define MSG_VERBOSE 1
|
||||
|
||||
/**
|
||||
* Selected message level.
|
||||
*/
|
||||
extern int msg_level;
|
||||
|
||||
/**
|
||||
* State messages.
|
||||
*
|
||||
* Messages that tell what the program is doing or did, but limited to few lines.
|
||||
* They are status information, and summary results.
|
||||
*/
|
||||
void msg_status(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Info messages.
|
||||
*
|
||||
* Messages that tell what was done.
|
||||
* Potentially a lot of messages are possible. They can still be on the screen,
|
||||
* as losing them we don't lose information.
|
||||
*
|
||||
* These messages never go in the log file, because there is always a corresponding log_tag().
|
||||
*/
|
||||
void msg_info(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Progress messages.
|
||||
*
|
||||
* Message that tell the progress of program.
|
||||
*
|
||||
* These messages also go in the log file.
|
||||
*/
|
||||
void msg_progress(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Progress bar messages.
|
||||
*
|
||||
* Message that show the percentage of the progress.
|
||||
*
|
||||
* These messages never go in the log file.
|
||||
*
|
||||
* These messages are buffered. Use msg_flush() to flush them.
|
||||
*/
|
||||
void msg_bar(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Verbose messages.
|
||||
*
|
||||
* Message that tell what is already expected.
|
||||
*
|
||||
* These messages also go in the log file.
|
||||
*/
|
||||
void msg_verbose(const char* format, ...) __attribute__((format(attribute_printf, 1, 2)));
|
||||
|
||||
/**
|
||||
* Flush the output.
|
||||
*/
|
||||
void msg_flush(void);
|
||||
|
||||
/****************************************************************************/
|
||||
/* print */
|
||||
|
||||
/**
|
||||
* Print a repeated char.
|
||||
*/
|
||||
void printc(char c, size_t pad);
|
||||
|
||||
/**
|
||||
* Print a string with right space padding.
|
||||
*/
|
||||
void printr(const char* str, size_t pad);
|
||||
|
||||
/**
|
||||
* Print a string with left space padding.
|
||||
*/
|
||||
void printl(const char* str, size_t pad);
|
||||
|
||||
/**
|
||||
* Print a probability with space padding.
|
||||
*/
|
||||
void printp(double v, size_t pad);
|
||||
|
||||
/****************************************************************************/
|
||||
/* string */
|
||||
|
||||
#define ESC_MAX (PATH_MAX*2 + 1)
|
||||
|
||||
/**
|
||||
* Escape a string for the log.
|
||||
*
|
||||
* \param buffer Preallocated buffer of ESC_MAX size.
|
||||
*
|
||||
* Chars ':', '\n', '\r' and '\' are escaped to '\d', '\\n', '\\r' and '\\'.
|
||||
*/
|
||||
const char* esc_tag(const char* str, char* buffer);
|
||||
|
||||
/**
|
||||
* Escape a string for the shell.
|
||||
*
|
||||
* \param buffer Preallocated buffer of ESC_MAX size.
|
||||
*/
|
||||
const char* esc_shell_multi(const char** str_map, unsigned str_max, char* buffer);
|
||||
static inline const char* esc_shell(const char* str, char* buffer)
|
||||
{
|
||||
return esc_shell_multi(&str, 1, buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Polish a string.
|
||||
*
|
||||
* Not printable chars are replaced by spaces.
|
||||
*
|
||||
* Note that the passed string is modified.
|
||||
*/
|
||||
char* strpolish(char* s);
|
||||
|
||||
/**
|
||||
* Split a string in multiple tokens separated by delimiters.
|
||||
*
|
||||
* Multiple delimiters are grouped together.
|
||||
*/
|
||||
unsigned strsplit(char** split_map, unsigned split_max, char* line, const char* delimiters);
|
||||
|
||||
/****************************************************************************/
|
||||
/* path */
|
||||
|
||||
/**
|
||||
* Copy a path limiting the size.
|
||||
* Abort if too long.
|
||||
*/
|
||||
void pathcpy(char* dst, size_t size, const char* src);
|
||||
|
||||
/**
|
||||
* Concatenate a path limiting the size.
|
||||
* Abort if too long.
|
||||
*/
|
||||
void pathcat(char* dst, size_t size, const char* src);
|
||||
|
||||
/**
|
||||
* Concatenate a path limiting the size.
|
||||
* Abort if too long.
|
||||
*/
|
||||
void pathcatc(char* dst, size_t size, char c);
|
||||
|
||||
/**
|
||||
* Import a path limiting the size.
|
||||
* In Windows all the backslash are converted to the C standard of forward slash.
|
||||
* Abort if too long.
|
||||
*/
|
||||
void pathimport(char* dst, size_t size, const char* src);
|
||||
|
||||
/**
|
||||
* Export a path limiting the size.
|
||||
* In Windows all the C slashes are converted to the Windows backslash.
|
||||
* Abort if too long.
|
||||
*/
|
||||
void pathexport(char* dst, size_t size, const char* src);
|
||||
|
||||
/**
|
||||
* Print a path.
|
||||
* Abort if too long.
|
||||
*/
|
||||
void pathprint(char* dst, size_t size, const char* format, ...) __attribute__((format(attribute_printf, 3, 4)));
|
||||
|
||||
/**
|
||||
* Ensure the presence of a terminating slash, if it isn't empty.
|
||||
* Abort if too long.
|
||||
*/
|
||||
void pathslash(char* dst, size_t size);
|
||||
|
||||
/**
|
||||
* Cut everything after the latest slash.
|
||||
*/
|
||||
void pathcut(char* dst);
|
||||
|
||||
/**
|
||||
* Compare two paths.
|
||||
* In Windows it's case insensitive and assumes \ equal at /.
|
||||
*/
|
||||
int pathcmp(const char* a, const char* b);
|
||||
|
||||
/****************************************************************************/
|
||||
/* file-system */
|
||||
|
||||
/**
|
||||
* Create all the ancestor directories if missing.
|
||||
* The file name, after the last /, is ignored.
|
||||
*/
|
||||
int mkancestor(const char* file);
|
||||
|
||||
/**
|
||||
* Change the modification time of an open file.
|
||||
*/
|
||||
int fmtime(int f, int64_t mtime_sec, int mtime_nsec);
|
||||
|
||||
/**
|
||||
* Change the modification time of a file or link.
|
||||
* Note that links are NOT deferenced.
|
||||
*/
|
||||
int lmtime(const char* path, int64_t mtime_sec, int mtime_nsec);
|
||||
|
||||
/****************************************************************************/
|
||||
/* advise */
|
||||
|
||||
/**
|
||||
* Advise modes.
|
||||
*/
|
||||
#define ADVISE_DEFAULT 0 /**< Default mode. */
|
||||
#define ADVISE_NONE 1 /**< Bare read/write mode. */
|
||||
#define ADVISE_SEQUENTIAL 2 /**< Sequential mode. */
|
||||
#define ADVISE_FLUSH 3 /**< Flush mode. */
|
||||
#define ADVISE_FLUSH_WINDOW 4 /**< Flush mode with a window of 8MB. */
|
||||
#define ADVISE_DISCARD 5 /**< Discard the cache after every operation. */
|
||||
#define ADVISE_DISCARD_WINDOW 6 /**< Discard the cache with a window of 8MB. */
|
||||
#define ADVISE_DIRECT 7 /**< Direct mode. */
|
||||
|
||||
#define ADVISE_WINDOW_SIZE (8 * 1024 * 1024) /**< Window size. */
|
||||
|
||||
struct advise_struct {
|
||||
int mode;
|
||||
data_off_t dirty_begin;
|
||||
data_off_t dirty_end;
|
||||
};
|
||||
|
||||
void advise_init(struct advise_struct* advise, int mode);
|
||||
int advise_flags(struct advise_struct* advise);
|
||||
int advise_open(struct advise_struct* advise, int f);
|
||||
int advise_write(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
|
||||
int advise_read(struct advise_struct* advise, int f, data_off_t offset, data_off_t size);
|
||||
|
||||
/****************************************************************************/
|
||||
/* memory */
|
||||
|
||||
/**
|
||||
* Return the size of the allocated memory.
|
||||
*/
|
||||
size_t malloc_counter_get(void);
|
||||
|
||||
/**
|
||||
* Safe malloc.
|
||||
* If no memory is available, it aborts.
|
||||
*/
|
||||
void* malloc_nofail(size_t size);
|
||||
|
||||
/**
|
||||
* Safe cmalloc.
|
||||
* If no memory is available, it aborts.
|
||||
*/
|
||||
void* calloc_nofail(size_t count, size_t size);
|
||||
|
||||
/**
|
||||
* Safe strdup.
|
||||
* If no memory is available, it aborts.
|
||||
*/
|
||||
char* strdup_nofail(const char* str);
|
||||
|
||||
/**
|
||||
* Helper for printing an error about a failed allocation.
|
||||
*/
|
||||
void malloc_fail(size_t size);
|
||||
|
||||
/****************************************************************************/
|
||||
/* smartctl */
|
||||
|
||||
/**
|
||||
* Read smartctl attributes from a stream.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* smart, char* serial, char* vendor, char* model);
|
||||
|
||||
/**
|
||||
* Flush smartctl output from a stream.
|
||||
*/
|
||||
int smartctl_flush(FILE* f, const char* file, const char* name);
|
||||
|
||||
/****************************************************************************/
|
||||
/* thread */
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
/**
|
||||
* Control when to signal the condition variables.
|
||||
*
|
||||
* Default is inside the mutex.
|
||||
*
|
||||
* Ensure to change that before starting any thread.
|
||||
*/
|
||||
int thread_cond_signal_outside;
|
||||
|
||||
/**
|
||||
* Thread wrappers to handle error conditions.
|
||||
*/
|
||||
void thread_mutex_init(pthread_mutex_t* mutex, pthread_mutexattr_t* attr);
|
||||
void thread_mutex_destroy(pthread_mutex_t* mutex);
|
||||
void thread_mutex_lock(pthread_mutex_t* mutex);
|
||||
void thread_mutex_unlock(pthread_mutex_t* mutex);
|
||||
void thread_cond_init(pthread_cond_t* cond, pthread_condattr_t* attr);
|
||||
void thread_cond_destroy(pthread_cond_t* cond);
|
||||
void thread_cond_signal(pthread_cond_t* cond);
|
||||
void thread_cond_broadcast(pthread_cond_t* cond);
|
||||
void thread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);
|
||||
void thread_cond_signal_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex);
|
||||
void thread_cond_broadcast_and_unlock(pthread_cond_t* cond, pthread_mutex_t* mutex);
|
||||
void thread_create(pthread_t* thread, pthread_attr_t* attr, void *(* func)(void *), void *arg);
|
||||
void thread_join(pthread_t thread, void** retval);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
1610
cmdline/sync.c
Normal file
1610
cmdline/sync.c
Normal file
File diff suppressed because it is too large
Load Diff
146
cmdline/touch.c
Normal file
146
cmdline/touch.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "elem.h"
|
||||
#include "state.h"
|
||||
#include "handle.h"
|
||||
|
||||
void state_touch(struct snapraid_state* state)
|
||||
{
|
||||
tommy_node* i;
|
||||
char esc_buffer[ESC_MAX];
|
||||
|
||||
msg_progress("Setting sub-second timestamps...\n");
|
||||
|
||||
/* for all disks */
|
||||
for (i = state->disklist; i != 0; i = i->next) {
|
||||
struct snapraid_disk* disk = i->data;
|
||||
tommy_node* j;
|
||||
|
||||
/* for all files */
|
||||
for (j = disk->filelist; j != 0; j = j->next) {
|
||||
struct snapraid_file* file = j->data;
|
||||
|
||||
/* if the file has a zero nanosecond timestamp */
|
||||
/* note that symbolic links are not in the file list */
|
||||
/* and then are not processed */
|
||||
if (file->mtime_nsec == 0) {
|
||||
char path[PATH_MAX];
|
||||
struct stat st;
|
||||
int f;
|
||||
int ret;
|
||||
int nsec;
|
||||
int flags;
|
||||
|
||||
pathprint(path, sizeof(path), "%s%s", disk->dir, file->sub);
|
||||
|
||||
/* set a new nanosecond timestamp different than 0 */
|
||||
do {
|
||||
uint32_t nano;
|
||||
|
||||
/* get a random nanosecond value */
|
||||
if (randomize(&nano, sizeof(nano)) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Failed to get random values.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
nsec = nano % 1000000000;
|
||||
} while (nsec == 0);
|
||||
|
||||
/* O_BINARY: open as binary file (Windows only) */
|
||||
/* O_NOFOLLOW: do not follow links to ensure to open the real file */
|
||||
flags = O_BINARY | O_NOFOLLOW;
|
||||
#ifdef _WIN32
|
||||
/* in Windows we must have write access at the file */
|
||||
flags |= O_RDWR;
|
||||
#else
|
||||
/* in all others platforms, read access is enough */
|
||||
flags |= O_RDONLY;
|
||||
#endif
|
||||
|
||||
/* open it */
|
||||
f = open(path, flags);
|
||||
if (f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening file '%s'. %s.\n", path, strerror(errno));
|
||||
continue;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* get the present timestamp, that may be different than the one */
|
||||
/* in the content file */
|
||||
ret = fstat(f, &st);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
close(f);
|
||||
log_fatal("Error accessing file '%s'. %s.\n", path, strerror(errno));
|
||||
continue;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* set the tweaked modification time, with new nano seconds */
|
||||
ret = fmtime(f, st.st_mtime, nsec);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
close(f);
|
||||
log_fatal("Error timing file '%s'. %s.\n", path, strerror(errno));
|
||||
continue;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* uses fstat again to get the present timestamp */
|
||||
/* this is needed because the value read */
|
||||
/* may be different than the written one */
|
||||
ret = fstat(f, &st);
|
||||
if (ret == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
close(f);
|
||||
log_fatal("Error accessing file '%s'. %s.\n", path, strerror(errno));
|
||||
continue;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* close it */
|
||||
ret = close(f);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing file '%s'. %s.\n", path, strerror(errno));
|
||||
continue;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* set the same nanosecond value in the content file */
|
||||
/* note that if the seconds value is already matching */
|
||||
/* the file won't be synced because the content file will */
|
||||
/* contain the new updated timestamp */
|
||||
file->mtime_nsec = STAT_NSEC(&st);
|
||||
|
||||
/* state changed, we need to update it */
|
||||
state->need_write = 1;
|
||||
|
||||
log_tag("touch:%s:%s: %" PRIu64 ".%d\n", disk->name, esc_tag(file->sub, esc_buffer), (uint64_t)st.st_mtime, STAT_NSEC(&st));
|
||||
msg_info("touch %s\n", fmt_term(disk, file->sub, esc_buffer));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1563
cmdline/unix.c
Normal file
1563
cmdline/unix.c
Normal file
File diff suppressed because it is too large
Load Diff
67
cmdline/unix.h
Normal file
67
cmdline/unix.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __UNIX_H
|
||||
#define __UNIX_H
|
||||
|
||||
#ifdef __linux__
|
||||
#define HAVE_LINUX_DEVICE 1 /**< In Linux enables special device support. */
|
||||
#define HAVE_DIRECT_IO 1 /**< Support O_DIRECT in open(). */
|
||||
#endif
|
||||
|
||||
#define O_BINARY 0 /**< Not used in Unix. */
|
||||
#define O_SEQUENTIAL 0 /**< In Unix posix_fadvise() shall be used. */
|
||||
|
||||
/**
|
||||
* If nanoseconds are not supported, we report the special STAT_NSEC_INVALID value,
|
||||
* to mark that it's undefined.
|
||||
*/
|
||||
#define STAT_NSEC_INVALID -1
|
||||
|
||||
/* Check if we have nanoseconds support */
|
||||
#if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
#define STAT_NSEC(st) ((int)(st)->st_mtim.tv_nsec) /* Linux */
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||
#define STAT_NSEC(st) ((int)(st)->st_mtimensec) /* NetBSD */
|
||||
#elif HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
#define STAT_NSEC(st) ((int)(st)->st_mtimespec.tv_nsec) /* FreeBSD, Mac OS X */
|
||||
#else
|
||||
#define STAT_NSEC(st) STAT_NSEC_INVALID
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Open a file with the O_NOATIME flag to avoid to update the access time.
|
||||
*/
|
||||
int open_noatime(const char* file, int flags);
|
||||
|
||||
/**
|
||||
* Check if the specified file is hidden.
|
||||
*/
|
||||
int dirent_hidden(struct dirent* dd);
|
||||
|
||||
/**
|
||||
* Return a description of the file type.
|
||||
*/
|
||||
const char* stat_desc(struct stat* st);
|
||||
|
||||
/**
|
||||
* Return the aligment requirement for direct IO.
|
||||
*/
|
||||
size_t direct_size(void);
|
||||
|
||||
#endif
|
||||
|
641
cmdline/util.c
Normal file
641
cmdline/util.c
Normal file
@ -0,0 +1,641 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "portable.h"
|
||||
|
||||
#include "support.h"
|
||||
#include "util.h"
|
||||
#include "raid/cpu.h"
|
||||
#include "raid/memory.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* memory */
|
||||
|
||||
void* malloc_nofail_align(size_t size, void** freeptr)
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
ptr = raid_malloc(size, freeptr);
|
||||
|
||||
if (!ptr) {
|
||||
/* LCOV_EXCL_START */
|
||||
malloc_fail(size);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* malloc_nofail_direct(size_t size, void** freeptr)
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
ptr = raid_malloc_align(size, direct_size(), freeptr);
|
||||
|
||||
if (!ptr) {
|
||||
/* LCOV_EXCL_START */
|
||||
malloc_fail(size);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void** malloc_nofail_vector_align(int nd, int n, size_t size, void** freeptr)
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
ptr = raid_malloc_vector(nd, n, size, freeptr);
|
||||
|
||||
if (!ptr) {
|
||||
/* LCOV_EXCL_START */
|
||||
malloc_fail(n * size);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void** malloc_nofail_vector_direct(int nd, int n, size_t size, void** freeptr)
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
ptr = raid_malloc_vector_align(nd, n, size, direct_size(), 0, freeptr);
|
||||
|
||||
if (!ptr) {
|
||||
/* LCOV_EXCL_START */
|
||||
malloc_fail(n * size);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* malloc_nofail_test(size_t size)
|
||||
{
|
||||
void* ptr;
|
||||
|
||||
ptr = malloc_nofail(size);
|
||||
|
||||
mtest_vector(1, size, &ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast memory test.
|
||||
*
|
||||
* It's similar at raid_mtest_vector() but faster because
|
||||
* we have a lot of buffers to verify.
|
||||
*/
|
||||
static int fast_mtest_vector(int n, size_t size, void** vv)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* test with all the bits */
|
||||
for (i = 0; i < 8; ++i) {
|
||||
unsigned char value = 1 << i;
|
||||
|
||||
/* fill first */
|
||||
memset(vv[0], value, size);
|
||||
|
||||
/* copy to the next */
|
||||
for (j = 1; j < n; ++j)
|
||||
memcpy(vv[j], vv[j - 1], size);
|
||||
|
||||
/* compare with the previous */
|
||||
for (j = 1; j <= n; ++j)
|
||||
if (memcmp(vv[j % n], vv[j - 1], size) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mtest_vector(int n, size_t size, void** vv)
|
||||
{
|
||||
if (fast_mtest_vector(n, size, vv) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("DANGER! Your RAM memory is broken! DO NOT PROCEED UNTIL FIXED!\n");
|
||||
log_fatal("Try running a memory test like http://www.memtest86.com/\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* crc */
|
||||
|
||||
uint32_t CRC32C_0[256] = {
|
||||
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
|
||||
0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
|
||||
0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
|
||||
0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24,
|
||||
0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b,
|
||||
0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
|
||||
0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54,
|
||||
0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b,
|
||||
0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,
|
||||
0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35,
|
||||
0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5,
|
||||
0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
|
||||
0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45,
|
||||
0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a,
|
||||
0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,
|
||||
0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595,
|
||||
0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48,
|
||||
0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
|
||||
0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687,
|
||||
0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198,
|
||||
0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,
|
||||
0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38,
|
||||
0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8,
|
||||
0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
|
||||
0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096,
|
||||
0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789,
|
||||
0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,
|
||||
0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46,
|
||||
0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9,
|
||||
0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
|
||||
0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36,
|
||||
0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829,
|
||||
0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,
|
||||
0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93,
|
||||
0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043,
|
||||
0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
|
||||
0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3,
|
||||
0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc,
|
||||
0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,
|
||||
0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033,
|
||||
0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652,
|
||||
0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
|
||||
0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d,
|
||||
0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982,
|
||||
0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,
|
||||
0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622,
|
||||
0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2,
|
||||
0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
|
||||
0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530,
|
||||
0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f,
|
||||
0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,
|
||||
0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0,
|
||||
0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f,
|
||||
0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
|
||||
0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90,
|
||||
0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f,
|
||||
0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,
|
||||
0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1,
|
||||
0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321,
|
||||
0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
|
||||
0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81,
|
||||
0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,
|
||||
0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
|
||||
0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351
|
||||
};
|
||||
|
||||
uint32_t CRC32C_1[256] = {
|
||||
0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899,
|
||||
0x4e8a61dc, 0x5d28f9ab, 0x69cf5132, 0x7a6dc945,
|
||||
0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21,
|
||||
0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd,
|
||||
0x3fc5f181, 0x2c6769f6, 0x1880c16f, 0x0b225918,
|
||||
0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4,
|
||||
0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0,
|
||||
0xec5b53e5, 0xfff9cb92, 0xcb1e630b, 0xd8bcfb7c,
|
||||
0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b,
|
||||
0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47,
|
||||
0xe29f20ba, 0xf13db8cd, 0xc5da1054, 0xd6788823,
|
||||
0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff,
|
||||
0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a,
|
||||
0x0ec4735f, 0x1d66eb28, 0x298143b1, 0x3a23dbc6,
|
||||
0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2,
|
||||
0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e,
|
||||
0xff17c604, 0xecb55e73, 0xd852f6ea, 0xcbf06e9d,
|
||||
0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41,
|
||||
0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25,
|
||||
0x2c896460, 0x3f2bfc17, 0x0bcc548e, 0x186eccf9,
|
||||
0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c,
|
||||
0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0,
|
||||
0x5dc6f43d, 0x4e646c4a, 0x7a83c4d3, 0x69215ca4,
|
||||
0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78,
|
||||
0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f,
|
||||
0xce1644da, 0xddb4dcad, 0xe9537434, 0xfaf1ec43,
|
||||
0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27,
|
||||
0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb,
|
||||
0xbf59d487, 0xacfb4cf0, 0x981ce469, 0x8bbe7c1e,
|
||||
0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2,
|
||||
0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6,
|
||||
0x6cc776e3, 0x7f65ee94, 0x4b82460d, 0x5820de7a,
|
||||
0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260,
|
||||
0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc,
|
||||
0x66d73941, 0x7575a136, 0x419209af, 0x523091d8,
|
||||
0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004,
|
||||
0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1,
|
||||
0x8a8c6aa4, 0x992ef2d3, 0xadc95a4a, 0xbe6bc23d,
|
||||
0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059,
|
||||
0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185,
|
||||
0x844819fb, 0x97ea818c, 0xa30d2915, 0xb0afb162,
|
||||
0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be,
|
||||
0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da,
|
||||
0x57d6bb9f, 0x447423e8, 0x70938b71, 0x63311306,
|
||||
0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3,
|
||||
0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f,
|
||||
0x26992bc2, 0x353bb3b5, 0x01dc1b2c, 0x127e835b,
|
||||
0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287,
|
||||
0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464,
|
||||
0x4a5e5d21, 0x59fcc556, 0x6d1b6dcf, 0x7eb9f5b8,
|
||||
0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc,
|
||||
0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600,
|
||||
0x3b11cd7c, 0x28b3550b, 0x1c54fd92, 0x0ff665e5,
|
||||
0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439,
|
||||
0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d,
|
||||
0xe88f6f18, 0xfb2df76f, 0xcfca5ff6, 0xdc68c781,
|
||||
0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766,
|
||||
0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba,
|
||||
0xe64b1c47, 0xf5e98430, 0xc10e2ca9, 0xd2acb4de,
|
||||
0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502,
|
||||
0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7,
|
||||
0x0a104fa2, 0x19b2d7d5, 0x2d557f4c, 0x3ef7e73b,
|
||||
0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f,
|
||||
0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483
|
||||
};
|
||||
|
||||
uint32_t CRC32C_2[256] = {
|
||||
0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073,
|
||||
0x9edea41a, 0x3b9f3664, 0xd1b1f617, 0x74f06469,
|
||||
0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6,
|
||||
0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac,
|
||||
0x70a27d8a, 0xd5e3eff4, 0x3fcd2f87, 0x9a8cbdf9,
|
||||
0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3,
|
||||
0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c,
|
||||
0xd62de755, 0x736c752b, 0x9942b558, 0x3c032726,
|
||||
0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67,
|
||||
0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d,
|
||||
0xd915c5d1, 0x7c5457af, 0x967a97dc, 0x333b05a2,
|
||||
0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8,
|
||||
0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed,
|
||||
0x0f382284, 0xaa79b0fa, 0x40577089, 0xe516e2f7,
|
||||
0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828,
|
||||
0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32,
|
||||
0xc76580d9, 0x622412a7, 0x880ad2d4, 0x2d4b40aa,
|
||||
0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0,
|
||||
0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f,
|
||||
0x61ea1a06, 0xc4ab8878, 0x2e85480b, 0x8bc4da75,
|
||||
0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20,
|
||||
0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a,
|
||||
0x8f96c396, 0x2ad751e8, 0xc0f9919b, 0x65b803e5,
|
||||
0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff,
|
||||
0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe,
|
||||
0xb8ffdfd7, 0x1dbe4da9, 0xf7908dda, 0x52d11fa4,
|
||||
0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b,
|
||||
0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161,
|
||||
0x56830647, 0xf3c29439, 0x19ec544a, 0xbcadc634,
|
||||
0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e,
|
||||
0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1,
|
||||
0xf00c9c98, 0x554d0ee6, 0xbf63ce95, 0x1a225ceb,
|
||||
0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730,
|
||||
0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a,
|
||||
0xb3764986, 0x1637dbf8, 0xfc191b8b, 0x595889f5,
|
||||
0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def,
|
||||
0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba,
|
||||
0x655baed3, 0xc01a3cad, 0x2a34fcde, 0x8f756ea0,
|
||||
0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f,
|
||||
0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065,
|
||||
0x6a638c57, 0xcf221e29, 0x250cde5a, 0x804d4c24,
|
||||
0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e,
|
||||
0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1,
|
||||
0xccec1688, 0x69ad84f6, 0x83834485, 0x26c2d6fb,
|
||||
0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae,
|
||||
0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4,
|
||||
0x2290cf18, 0x87d15d66, 0x6dff9d15, 0xc8be0f6b,
|
||||
0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71,
|
||||
0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9,
|
||||
0xd29c5380, 0x77ddc1fe, 0x9df3018d, 0x38b293f3,
|
||||
0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c,
|
||||
0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36,
|
||||
0x3ce08a10, 0x99a1186e, 0x738fd81d, 0xd6ce4a63,
|
||||
0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79,
|
||||
0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6,
|
||||
0x9a6f10cf, 0x3f2e82b1, 0xd50042c2, 0x7041d0bc,
|
||||
0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd,
|
||||
0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7,
|
||||
0x9557324b, 0x3016a035, 0xda386046, 0x7f79f238,
|
||||
0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622,
|
||||
0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177,
|
||||
0x437ad51e, 0xe63b4760, 0x0c158713, 0xa954156d,
|
||||
0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2,
|
||||
0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8
|
||||
};
|
||||
|
||||
uint32_t CRC32C_3[256] = {
|
||||
0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939,
|
||||
0x7b2231f3, 0xa6679b4b, 0xc4451272, 0x1900b8ca,
|
||||
0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf,
|
||||
0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c,
|
||||
0xe964b13d, 0x34211b85, 0x560392bc, 0x8b463804,
|
||||
0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7,
|
||||
0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2,
|
||||
0x6402e328, 0xb9474990, 0xdb65c0a9, 0x06206a11,
|
||||
0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2,
|
||||
0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41,
|
||||
0x2161776d, 0xfc24ddd5, 0x9e0654ec, 0x4343fe54,
|
||||
0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7,
|
||||
0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f,
|
||||
0x45639445, 0x98263efd, 0xfa04b7c4, 0x27411d7c,
|
||||
0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69,
|
||||
0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a,
|
||||
0xaba65fe7, 0x76e3f55f, 0x14c17c66, 0xc984d6de,
|
||||
0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d,
|
||||
0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538,
|
||||
0x26c00df2, 0xfb85a74a, 0x99a72e73, 0x44e284cb,
|
||||
0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3,
|
||||
0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610,
|
||||
0xb4868d3c, 0x69c32784, 0x0be1aebd, 0xd6a40405,
|
||||
0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6,
|
||||
0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255,
|
||||
0x07a17a9f, 0xdae4d027, 0xb8c6591e, 0x6583f3a6,
|
||||
0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3,
|
||||
0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040,
|
||||
0x95e7fa51, 0x48a250e9, 0x2a80d9d0, 0xf7c57368,
|
||||
0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b,
|
||||
0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e,
|
||||
0x1881a844, 0xc5c402fc, 0xa7e68bc5, 0x7aa3217d,
|
||||
0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006,
|
||||
0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5,
|
||||
0xa4e4aad9, 0x79a10061, 0x1b838958, 0xc6c623e0,
|
||||
0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213,
|
||||
0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b,
|
||||
0xc0e649f1, 0x1da3e349, 0x7f816a70, 0xa2c4c0c8,
|
||||
0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd,
|
||||
0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e,
|
||||
0x8585ddb4, 0x58c0770c, 0x3ae2fe35, 0xe7a7548d,
|
||||
0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e,
|
||||
0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b,
|
||||
0x08e38fa1, 0xd5a62519, 0xb784ac20, 0x6ac10698,
|
||||
0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0,
|
||||
0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443,
|
||||
0x9aa50f6f, 0x47e0a5d7, 0x25c22cee, 0xf8878656,
|
||||
0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5,
|
||||
0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1,
|
||||
0x8224a72b, 0x5f610d93, 0x3d4384aa, 0xe0062e12,
|
||||
0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07,
|
||||
0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4,
|
||||
0x106227e5, 0xcd278d5d, 0xaf050464, 0x7240aedc,
|
||||
0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f,
|
||||
0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a,
|
||||
0x9d0475f0, 0x4041df48, 0x22635671, 0xff26fcc9,
|
||||
0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a,
|
||||
0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99,
|
||||
0xd867e1b5, 0x05224b0d, 0x6700c234, 0xba45688c,
|
||||
0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f,
|
||||
0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57,
|
||||
0xbc65029d, 0x6120a825, 0x0302211c, 0xde478ba4,
|
||||
0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1,
|
||||
0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842
|
||||
};
|
||||
|
||||
#if HAVE_SSE42
|
||||
int crc_x86;
|
||||
#endif
|
||||
|
||||
uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size)
|
||||
{
|
||||
crc ^= CRC_IV;
|
||||
|
||||
crc = crc32c_gen_plain(crc, ptr, size);
|
||||
|
||||
crc ^= CRC_IV;
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
#if HAVE_SSE42
|
||||
uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size)
|
||||
{
|
||||
crc ^= CRC_IV;
|
||||
|
||||
crc = crc32c_x86_plain(crc, ptr, size);
|
||||
|
||||
crc ^= CRC_IV;
|
||||
|
||||
return crc;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size);
|
||||
|
||||
void crc32c_init(void)
|
||||
{
|
||||
crc32c = crc32c_gen;
|
||||
#if HAVE_SSE42
|
||||
if (raid_cpu_has_crc32()) {
|
||||
crc_x86 = 1;
|
||||
crc32c = crc32c_x86;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* byte operations */
|
||||
|
||||
/*
|
||||
* Rotate left.
|
||||
* In x86/x64 they are optimized with a single assembler instruction.
|
||||
*/
|
||||
static inline uint32_t util_rotl32(uint32_t x, int8_t r)
|
||||
{
|
||||
return (x << r) | (x >> (32 - r));
|
||||
}
|
||||
|
||||
static inline uint64_t util_rotl64(uint64_t x, int8_t r)
|
||||
{
|
||||
return (x << r) | (x >> (64 - r));
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap endianess.
|
||||
* They are needed only if BigEndian.
|
||||
*/
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#define util_swap32(x) __builtin_bswap32(x)
|
||||
#define util_swap64(x) __builtin_bswap64(x)
|
||||
|
||||
#elif HAVE_BYTESWAP_H
|
||||
|
||||
#include <byteswap.h>
|
||||
|
||||
#define util_swap32(x) bswap_32(x)
|
||||
#define util_swap64(x) bswap_64(x)
|
||||
|
||||
#else
|
||||
static inline uint32_t util_swap32(uint32_t v)
|
||||
{
|
||||
return (util_rotl32(v, 8) & 0x00ff00ff)
|
||||
| (util_rotl32(v, 24) & 0xff00ff00);
|
||||
}
|
||||
|
||||
static inline uint64_t util_swap64(uint64_t v)
|
||||
{
|
||||
return (util_rotl64(v, 8) & 0x000000ff000000ffULL)
|
||||
| (util_rotl64(v, 24) & 0x0000ff000000ff00ULL)
|
||||
| (util_rotl64(v, 40) & 0x00ff000000ff0000ULL)
|
||||
| (util_rotl64(v, 56) & 0xff000000ff000000ULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint32_t util_read32(const void* ptr)
|
||||
{
|
||||
uint32_t v;
|
||||
memcpy(&v, ptr, sizeof(v));
|
||||
#if WORDS_BIGENDIAN
|
||||
v = util_swap32(v);
|
||||
#endif
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline uint64_t util_read64(const void* ptr)
|
||||
{
|
||||
uint64_t v;
|
||||
memcpy(&v, ptr, sizeof(v));
|
||||
#if WORDS_BIGENDIAN
|
||||
v = util_swap64(v);
|
||||
#endif
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void util_write32(void* ptr, uint32_t v)
|
||||
{
|
||||
#if WORDS_BIGENDIAN
|
||||
v = util_swap32(v);
|
||||
#endif
|
||||
memcpy(ptr, &v, sizeof(v));
|
||||
}
|
||||
|
||||
static inline void util_write64(void* ptr, uint64_t v)
|
||||
{
|
||||
#if WORDS_BIGENDIAN
|
||||
v = util_swap64(v);
|
||||
#endif
|
||||
memcpy(ptr, &v, sizeof(v));
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* hash */
|
||||
|
||||
#include "murmur3.c"
|
||||
#include "spooky2.c"
|
||||
|
||||
void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size)
|
||||
{
|
||||
switch (kind) {
|
||||
case HASH_MURMUR3 :
|
||||
MurmurHash3_x86_128(src, size, seed, digest);
|
||||
break;
|
||||
case HASH_SPOOKY2 :
|
||||
SpookyHash128(src, size, seed, digest);
|
||||
break;
|
||||
default :
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Internal inconsistency in hash function %u\n", kind);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
const char* hash_config_name(unsigned kind)
|
||||
{
|
||||
switch (kind) {
|
||||
case HASH_UNDEFINED : return "undefined";
|
||||
case HASH_MURMUR3 : return "murmur3";
|
||||
case HASH_SPOOKY2 : return "spooky2";
|
||||
default :
|
||||
/* LCOV_EXCL_START */
|
||||
return "unknown";
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
unsigned count;
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < size; ++i) {
|
||||
unsigned j;
|
||||
unsigned char diff = data1[i] ^ data2[i];
|
||||
for (j = 0; j < 8; ++j) {
|
||||
if ((diff & 1) != 0)
|
||||
++count;
|
||||
diff >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* lock */
|
||||
|
||||
#if HAVE_LOCKFILE
|
||||
int lock_lock(const char* file)
|
||||
{
|
||||
int f;
|
||||
|
||||
f = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||
if (f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* exclusive lock, not blocking */
|
||||
if (flock(f, LOCK_EX | LOCK_NB) == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
close(f);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_LOCKFILE
|
||||
int lock_unlock(int f)
|
||||
{
|
||||
/*
|
||||
* Intentionally don't remove the lock file.
|
||||
* Removing it just introduces race course with other process
|
||||
* that could have already opened it.
|
||||
*/
|
||||
if (close(f) == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
224
cmdline/util.h
Normal file
224
cmdline/util.h
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __UTIL_H
|
||||
#define __UTIL_H
|
||||
|
||||
/****************************************************************************/
|
||||
/* memory */
|
||||
|
||||
/**
|
||||
* Safe aligned malloc.
|
||||
* If no memory is available, it aborts.
|
||||
*/
|
||||
void* malloc_nofail_align(size_t size, void** freeptr);
|
||||
|
||||
/**
|
||||
* Safe aligned malloc. Usable for direct io.
|
||||
*/
|
||||
void* malloc_nofail_direct(size_t size, void** freeptr);
|
||||
|
||||
/**
|
||||
* Safe aligned vector allocation.
|
||||
* If no memory is available, it aborts.
|
||||
*/
|
||||
void** malloc_nofail_vector_align(int nd, int n, size_t size, void** freeptr);
|
||||
|
||||
/**
|
||||
* Safe page vector allocation. Usable for direct io.
|
||||
* If no memory is available, it aborts.
|
||||
*/
|
||||
void** malloc_nofail_vector_direct(int nd, int n, size_t size, void** freeptr);
|
||||
|
||||
/**
|
||||
* Safe allocation with memory test.
|
||||
*/
|
||||
void* malloc_nofail_test(size_t size);
|
||||
|
||||
/**
|
||||
* Test the memory vector for RAM problems.
|
||||
* If a problem is found, it crashes.
|
||||
*/
|
||||
void mtest_vector(int n, size_t size, void** vv);
|
||||
|
||||
/****************************************************************************/
|
||||
/* crc */
|
||||
|
||||
/**
|
||||
* CRC initial value.
|
||||
* Using a not zero value allows to detect a leading run of zeros.
|
||||
*/
|
||||
#define CRC_IV 0xffffffffU
|
||||
|
||||
/**
|
||||
* CRC-32 (Castagnoli) table.
|
||||
*/
|
||||
extern uint32_t CRC32C_0[256];
|
||||
extern uint32_t CRC32C_1[256];
|
||||
extern uint32_t CRC32C_2[256];
|
||||
extern uint32_t CRC32C_3[256];
|
||||
|
||||
/**
|
||||
* If the CPU support the CRC instructions.
|
||||
*/
|
||||
#if HAVE_SSE42
|
||||
extern int crc_x86;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Compute CRC-32 (Castagnoli) for a single byte without the IV.
|
||||
*/
|
||||
static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
|
||||
{
|
||||
#if HAVE_SSE42
|
||||
if (tommy_likely(crc_x86)) {
|
||||
asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
|
||||
return crc;
|
||||
}
|
||||
#endif
|
||||
return CRC32C_0[(crc ^ c) & 0xff] ^ (crc >> 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the CRC-32 (Castagnoli) without the IV.
|
||||
*/
|
||||
static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
|
||||
{
|
||||
while (size >= 4) {
|
||||
crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
|
||||
crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
|
||||
ptr += 4;
|
||||
size -= 4;
|
||||
}
|
||||
|
||||
while (size) {
|
||||
crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8);
|
||||
++ptr;
|
||||
--size;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the CRC-32 (Castagnoli) without the IV.
|
||||
*/
|
||||
#if HAVE_SSE42
|
||||
static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
uint64_t crc64 = crc;
|
||||
while (size >= 8) {
|
||||
asm ("crc32q %1, %0\n" : "+r" (crc64) : "m" (*(const uint64_t*)ptr));
|
||||
ptr += 8;
|
||||
size -= 8;
|
||||
}
|
||||
crc = crc64;
|
||||
#else
|
||||
while (size >= 4) {
|
||||
asm ("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr));
|
||||
ptr += 4;
|
||||
size -= 4;
|
||||
}
|
||||
#endif
|
||||
while (size) {
|
||||
asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
|
||||
++ptr;
|
||||
--size;
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Compute CRC-32 (Castagnoli) without the IV.
|
||||
*/
|
||||
static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
|
||||
{
|
||||
#if HAVE_SSE42
|
||||
if (tommy_likely(crc_x86)) {
|
||||
return crc32c_x86_plain(crc, ptr, size);
|
||||
}
|
||||
#endif
|
||||
return crc32c_gen_plain(crc, ptr, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the CRC-32 (Castagnoli)
|
||||
*/
|
||||
uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size);
|
||||
|
||||
/**
|
||||
* Internal entry points for testing.
|
||||
*/
|
||||
uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size);
|
||||
uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size);
|
||||
|
||||
/**
|
||||
* Initialize the CRC-32 (Castagnoli) support.
|
||||
*/
|
||||
void crc32c_init(void);
|
||||
|
||||
/****************************************************************************/
|
||||
/* hash */
|
||||
|
||||
/**
|
||||
* Size of the hash.
|
||||
*/
|
||||
#define HASH_MAX 16
|
||||
|
||||
/**
|
||||
* Hash kinds.
|
||||
*/
|
||||
#define HASH_UNDEFINED 0
|
||||
#define HASH_MURMUR3 1
|
||||
#define HASH_SPOOKY2 2
|
||||
|
||||
/**
|
||||
* Compute the HASH of a memory block.
|
||||
* Seed is a 128 bit vector.
|
||||
*/
|
||||
void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size);
|
||||
|
||||
/**
|
||||
* Return the hash name.
|
||||
*/
|
||||
const char* hash_config_name(unsigned kind);
|
||||
|
||||
/**
|
||||
* Count the number of different bits in the two buffers.
|
||||
*/
|
||||
unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size);
|
||||
|
||||
/****************************************************************************/
|
||||
/* lock */
|
||||
|
||||
/**
|
||||
* Create and locks the lock file.
|
||||
* Return -1 on error, otherwise it's the file handle to pass to lock_unlock().
|
||||
*/
|
||||
int lock_lock(const char* file);
|
||||
|
||||
/**
|
||||
* Unlock the lock file.
|
||||
* Return -1 on error.
|
||||
*/
|
||||
int lock_unlock(int f);
|
||||
|
||||
#endif
|
||||
|
347
compile
Executable file
347
compile
Executable file
@ -0,0 +1,347 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2012-10-14.11; # UTC
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
1421
config.guess
vendored
Executable file
1421
config.guess
vendored
Executable file
File diff suppressed because it is too large
Load Diff
422
config.h.in
Normal file
422
config.h.in
Normal file
@ -0,0 +1,422 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* Define to 1 if you have the `access' function. */
|
||||
#undef HAVE_ACCESS
|
||||
|
||||
/* Define to 1 if inline assembly should be used. */
|
||||
#undef HAVE_ASSEMBLY
|
||||
|
||||
/* Define to 1 if avx2 is supported by the assembler. */
|
||||
#undef HAVE_AVX2
|
||||
|
||||
/* Define to 1 if you have the `backtrace' function. */
|
||||
#undef HAVE_BACKTRACE
|
||||
|
||||
/* Define to 1 if you have the `backtrace_symbols' function. */
|
||||
#undef HAVE_BACKTRACE_SYMBOLS
|
||||
|
||||
/* Define to 1 if you have the <blkid/blkid.h> header file. */
|
||||
#undef HAVE_BLKID_BLKID_H
|
||||
|
||||
/* Define to 1 if you have the `blkid_devno_to_devname' function. */
|
||||
#undef HAVE_BLKID_DEVNO_TO_DEVNAME
|
||||
|
||||
/* Define to 1 if you have the `blkid_get_tag_value' function. */
|
||||
#undef HAVE_BLKID_GET_TAG_VALUE
|
||||
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
#undef HAVE_BYTESWAP_H
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#undef HAVE_CLOCK_GETTIME
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define to 1 if you have the <execinfo.h> header file. */
|
||||
#undef HAVE_EXECINFO_H
|
||||
|
||||
/* Define to 1 if you have the `fallocate' function. */
|
||||
#undef HAVE_FALLOCATE
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `ferror_unlocked' function. */
|
||||
#undef HAVE_FERROR_UNLOCKED
|
||||
|
||||
/* Define to 1 if you have the `flock' function. */
|
||||
#undef HAVE_FLOCK
|
||||
|
||||
/* Define to 1 if you have the `fnmatch' function. */
|
||||
#undef HAVE_FNMATCH
|
||||
|
||||
/* Define to 1 if you have the <fnmatch.h> header file. */
|
||||
#undef HAVE_FNMATCH_H
|
||||
|
||||
/* Define to 1 if you have the `fstatat' function. */
|
||||
#undef HAVE_FSTATAT
|
||||
|
||||
/* Define to 1 if you have the `fsync' function. */
|
||||
#undef HAVE_FSYNC
|
||||
|
||||
/* Define to 1 if you have the `ftruncate' function. */
|
||||
#undef HAVE_FTRUNCATE
|
||||
|
||||
/* Define to 1 if you have the `futimens' function. */
|
||||
#undef HAVE_FUTIMENS
|
||||
|
||||
/* Define to 1 if you have the `futimes' function. */
|
||||
#undef HAVE_FUTIMES
|
||||
|
||||
/* Define to 1 if you have the `futimesat' function. */
|
||||
#undef HAVE_FUTIMESAT
|
||||
|
||||
/* Define to 1 if you have the `getc_unlocked' function. */
|
||||
#undef HAVE_GETC_UNLOCKED
|
||||
|
||||
/* Define to 1 if you have the `getopt' function. */
|
||||
#undef HAVE_GETOPT
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#undef HAVE_GETOPT_H
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#undef HAVE_GETOPT_LONG
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <io.h> header file. */
|
||||
#undef HAVE_IO_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <linux/fiemap.h> header file. */
|
||||
#undef HAVE_LINUX_FIEMAP_H
|
||||
|
||||
/* Define to 1 if you have the <linux/fs.h> header file. */
|
||||
#undef HAVE_LINUX_FS_H
|
||||
|
||||
/* Define to 1 if you have the `localtime_r' function. */
|
||||
#undef HAVE_LOCALTIME_R
|
||||
|
||||
/* Define to 1 if you have the `lutimes' function. */
|
||||
#undef HAVE_LUTIMES
|
||||
|
||||
/* Define to 1 if you have the `mach_absolute_time' function. */
|
||||
#undef HAVE_MACH_ABSOLUTE_TIME
|
||||
|
||||
/* Define to 1 if you have the <mach/mach_time.h> header file. */
|
||||
#undef HAVE_MACH_MACH_TIME_H
|
||||
|
||||
/* Define to 1 if you have the <math.h> header file. */
|
||||
#undef HAVE_MATH_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `memset' function. */
|
||||
#undef HAVE_MEMSET
|
||||
|
||||
/* Define to 1 if you have the `mkdir' function. */
|
||||
#undef HAVE_MKDIR
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the `posix_fadvise' function. */
|
||||
#undef HAVE_POSIX_FADVISE
|
||||
|
||||
/* Define to 1 if you have the `pthread_create' function. */
|
||||
#undef HAVE_PTHREAD_CREATE
|
||||
|
||||
/* Define to 1 if you have the <pthread.h> header file. */
|
||||
#undef HAVE_PTHREAD_H
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define to 1 if sse2 is supported by the assembler. */
|
||||
#undef HAVE_SSE2
|
||||
|
||||
/* Define to 1 if sse4.2 is supported by the assembler. */
|
||||
#undef HAVE_SSE42
|
||||
|
||||
/* Define to 1 if ssse3 is supported by the assembler. */
|
||||
#undef HAVE_SSSE3
|
||||
|
||||
/* Define to 1 if you have the `statfs' function. */
|
||||
#undef HAVE_STATFS
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#undef HAVE_STDDEF_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strrchr' function. */
|
||||
#undef HAVE_STRRCHR
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#undef HAVE_STRTOUL
|
||||
|
||||
/* Define to 1 if `d_ino' is a member of `struct dirent'. */
|
||||
#undef HAVE_STRUCT_DIRENT_D_INO
|
||||
|
||||
/* Define to 1 if `d_type' is a member of `struct dirent'. */
|
||||
#undef HAVE_STRUCT_DIRENT_D_TYPE
|
||||
|
||||
/* Define to 1 if `f_fstypename' is a member of `struct statfs'. */
|
||||
#undef HAVE_STRUCT_STATFS_F_FSTYPENAME
|
||||
|
||||
/* Define to 1 if `f_type' is a member of `struct statfs'. */
|
||||
#undef HAVE_STRUCT_STATFS_F_TYPE
|
||||
|
||||
/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||
|
||||
/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
|
||||
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
|
||||
/* Define to 1 if `st_nlink' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_NLINK
|
||||
|
||||
/* Define to 1 if you have the `sync_file_range' function. */
|
||||
#undef HAVE_SYNC_FILE_RANGE
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mount.h> header file. */
|
||||
#undef HAVE_SYS_MOUNT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/statfs.h> header file. */
|
||||
#undef HAVE_SYS_STATFS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/vfs.h> header file. */
|
||||
#undef HAVE_SYS_VFS_H
|
||||
|
||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `utimensat' function. */
|
||||
#undef HAVE_UTIMENSAT
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
|
||||
*/
|
||||
#undef MAJOR_IN_MKDEV
|
||||
|
||||
/* Define to 1 if `major', `minor', and `makedev' are declared in
|
||||
<sysmacros.h>. */
|
||||
#undef MAJOR_IN_SYSMACROS
|
||||
|
||||
/* Define to 1 if assertions should be disabled. */
|
||||
#undef NDEBUG
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#undef TIME_WITH_SYS_TIME
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# undef WORDS_BIGENDIAN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#undef _UINT32_T
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#undef _UINT64_T
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
#undef _UINT8_T
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 8 bits if such
|
||||
a type exists and the standard includes do not define it. */
|
||||
#undef int8_t
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define to the equivalent of the C99 'restrict' keyword, or to
|
||||
nothing if this is not supported. Do not define if restrict is
|
||||
supported directly. */
|
||||
#undef restrict
|
||||
/* Work around a bug in Sun C++: it does not support _Restrict or
|
||||
__restrict__, even though the corresponding Sun C compiler ends up with
|
||||
"#define restrict _Restrict" or "#define restrict __restrict__" in the
|
||||
previous line. Perhaps some future version of Sun C++ will work with
|
||||
restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
|
||||
#if defined __SUNPRO_CC && !defined __RESTRICT
|
||||
# define _Restrict
|
||||
# define __restrict__
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
#undef ssize_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint32_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 64 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint64_t
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 8 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
#undef uint8_t
|
||||
|
||||
/* Define to empty if the keyword `volatile' does not work. Warning: valid
|
||||
code using `volatile' can become incorrect without. Disable with care. */
|
||||
#undef volatile
|
1807
config.sub
vendored
Executable file
1807
config.sub
vendored
Executable file
File diff suppressed because it is too large
Load Diff
372
configure.ac
Normal file
372
configure.ac
Normal file
@ -0,0 +1,372 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ([2.65])
|
||||
dnl Get version number from git
|
||||
m4_define([git_revision], m4_esyscmd_s([./autover.sh]))
|
||||
AC_INIT([snapraid], [git_revision], [], [], [http://www.snapraid.it])
|
||||
AM_INIT_AUTOMAKE([foreign no-dependencies subdir-objects])
|
||||
AC_CONFIG_SRCDIR([cmdline/snapraid.c])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind],[])
|
||||
AC_CHECK_PROG([WINE],[wine],[wine],[])
|
||||
AC_CHECK_PROG([SDE],[sde],[sde],[])
|
||||
AC_CHECK_PROG([ADVD2],[advd2],[advd2],[])
|
||||
AM_CONDITIONAL(HAVE_ADVD2, [test x"$ADVD2" != x])
|
||||
|
||||
dnl Compiler option to improve stacktrace
|
||||
AC_CHECK_CC_OPT([-fno-omit-frame-pointer], CFLAGS="$CFLAGS -fno-omit-frame-pointer", [])
|
||||
AC_CHECK_CC_OPT([-fno-inline-functions-called-once], CFLAGS="$CFLAGS -fno-inline-functions-called-once", [])
|
||||
AC_CHECK_CC_OPT([-fno-inline-small-functions], CFLAGS="$CFLAGS -fno-inline-small-functions", [])
|
||||
AC_CHECK_CC_OPT([-rdynamic], CFLAGS="$CFLAGS -rdynamic", [])
|
||||
|
||||
dnl Checks for system.
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_ASSERT
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_HEADER_MAJOR
|
||||
AC_CHECK_HEADERS([fcntl.h stddef.h stdint.h stdlib.h string.h limits.h])
|
||||
AC_CHECK_HEADERS([unistd.h getopt.h fnmatch.h io.h inttypes.h byteswap.h])
|
||||
AC_CHECK_HEADERS([pthread.h math.h])
|
||||
AC_CHECK_HEADERS([sys/file.h sys/ioctl.h sys/vfs.h sys/statfs.h sys/param.h sys/mount.h])
|
||||
AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h mach/mach_time.h execinfo.h])
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_C_RESTRICT
|
||||
AC_C_VOLATILE
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_SSIZE_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_UINT8_T
|
||||
AC_TYPE_INT8_T
|
||||
AC_STRUCT_DIRENT_D_INO
|
||||
AC_STRUCT_DIRENT_D_TYPE
|
||||
AC_CHECK_MEMBERS([struct stat.st_nlink, struct stat.st_mtim.tv_nsec, struct stat.st_mtimensec, struct stat.st_mtimespec.tv_nsec], [], [], [[
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
]])
|
||||
AC_CHECK_MEMBERS([struct statfs.f_type], [], [], [[
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#if HAVE_SYS_MOUNT_H
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
#if HAVE_SYS_VFS_H
|
||||
#include <sys/vfs.h>
|
||||
#endif
|
||||
#if HAVE_SYS_STATFS_H
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
]])
|
||||
AC_CHECK_MEMBERS([struct statfs.f_fstypename], [], [], [[
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#if HAVE_SYS_MOUNT_H
|
||||
#include <sys/mount.h>
|
||||
#endif
|
||||
#if HAVE_SYS_VFS_H
|
||||
#include <sys/vfs.h>
|
||||
#endif
|
||||
#if HAVE_SYS_STATFS_H
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
]])
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS([memset strchr strerror strrchr mkdir gettimeofday strtoul])
|
||||
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf sigaction])
|
||||
AC_CHECK_FUNCS([ftruncate fallocate access])
|
||||
AC_CHECK_FUNCS([fsync posix_fadvise sync_file_range])
|
||||
AC_CHECK_FUNCS([getc_unlocked ferror_unlocked fnmatch])
|
||||
AC_CHECK_FUNCS([futimes futimens futimesat localtime_r lutimes utimensat])
|
||||
AC_CHECK_FUNCS([fstatat flock statfs])
|
||||
AC_CHECK_FUNCS([mach_absolute_time])
|
||||
AC_CHECK_FUNCS([backtrace backtrace_symbols])
|
||||
AC_SEARCH_LIBS([clock_gettime], [rt])
|
||||
AC_CHECK_FUNCS([clock_gettime])
|
||||
AC_CHECK_CC_OPT([-pthread], CFLAGS="$CFLAGS -pthread", CFLAGS="$CFLAGS -D_REENTRANT")
|
||||
AC_CHECK_FUNCS([pthread_create])
|
||||
AC_SEARCH_LIBS([exp], [m])
|
||||
|
||||
dnl Checks for libblkid
|
||||
AC_ARG_WITH([blkid],
|
||||
AS_HELP_STRING([--without-blkid], [Ignore presence of blkid and disable it]))
|
||||
AS_IF([test "x$with_blkid" != "xno"],
|
||||
[AC_SEARCH_LIBS([blkid_probe_all], [blkid], [have_blkid=yes], [have_blkid=no])],
|
||||
[have_blkid=no])
|
||||
AS_IF([test "x$have_blkid" = "xyes"],
|
||||
[
|
||||
AC_CHECK_HEADERS([blkid/blkid.h])
|
||||
AC_CHECK_FUNCS([blkid_devno_to_devname blkid_get_tag_value])
|
||||
],
|
||||
[AS_IF([test "x$with_blkid" = "xyes"],
|
||||
[AC_MSG_ERROR([blkid requested but not found])
|
||||
])
|
||||
])
|
||||
|
||||
dnl Checks for architecture
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
dnl Checks for compiler
|
||||
AC_CHECK_CC_OPT([-Wall], CFLAGS="$CFLAGS -Wall", [])
|
||||
AC_CHECK_CC_OPT([-Wextra], CFLAGS="$CFLAGS -Wextra", [])
|
||||
AC_CHECK_CC_OPT([-Wuninitialized], CFLAGS="$CFLAGS -Wuninitialized", [])
|
||||
AC_CHECK_CC_OPT([-Wshadow], CFLAGS="$CFLAGS -Wshadow", [])
|
||||
|
||||
dnl Checks for asm
|
||||
AC_ARG_ENABLE([asm],
|
||||
AS_HELP_STRING([--disable-asm], [Disable inline assembly]))
|
||||
AS_IF([test "x$enable_asm" != "xno"],
|
||||
[AC_DEFINE([HAVE_ASSEMBLY], [1], [Define to 1 if inline assembly should be used.])]
|
||||
|
||||
dnl AS_IF(HAVE_ASSEMBLY) NOT closed here
|
||||
|
||||
dnl Checks for AS supporting the SSE2 instructions.
|
||||
AC_MSG_CHECKING([for sse2])
|
||||
asmsse2=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
void f(void)
|
||||
{
|
||||
asm volatile("pxor %xmm0,%xmm1");
|
||||
}
|
||||
#else
|
||||
#error not x86
|
||||
#endif
|
||||
]])],
|
||||
[AC_DEFINE([HAVE_SSE2], [1], [Define to 1 if sse2 is supported by the assembler.]) asmsse2=yes])
|
||||
AC_MSG_RESULT([$asmsse2])
|
||||
|
||||
dnl Checks for AS supporting the SSSE3 instructions.
|
||||
AC_MSG_CHECKING([for ssse3])
|
||||
asmssse3=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
void f(void)
|
||||
{
|
||||
asm volatile("pshufb %xmm0,%xmm1");
|
||||
}
|
||||
#else
|
||||
#error not x86
|
||||
#endif
|
||||
]])],
|
||||
[AC_DEFINE([HAVE_SSSE3], [1], [Define to 1 if ssse3 is supported by the assembler.]) asmssse3=yes])
|
||||
AC_MSG_RESULT([$asmssse3])
|
||||
|
||||
dnl Checks for AS supporting the SSE4.2 instructions.
|
||||
AC_MSG_CHECKING([for sse42])
|
||||
asmsse42=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
unsigned f(unsigned crc, unsigned char b)
|
||||
{
|
||||
asm volatile("crc32b %1, %0" : "+r" (crc) : "rm" (b));
|
||||
return crc;
|
||||
}
|
||||
#else
|
||||
#error not x86
|
||||
#endif
|
||||
]])],
|
||||
[AC_DEFINE([HAVE_SSE42], [1], [Define to 1 if sse4.2 is supported by the assembler.]) asmsse42=yes])
|
||||
AC_MSG_RESULT([$asmsse42])
|
||||
|
||||
dnl Checks for AS supporting the AVX2 instructions.
|
||||
AC_MSG_CHECKING([for avx2])
|
||||
asmavx2=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
void f(void* ptr)
|
||||
{
|
||||
asm volatile("vbroadcasti128 %0, %%ymm0" : : "m" (ptr));
|
||||
}
|
||||
#else
|
||||
#error not x86
|
||||
#endif
|
||||
]])],
|
||||
[AC_DEFINE([HAVE_AVX2], [1], [Define to 1 if avx2 is supported by the assembler.]) asmavx2=yes])
|
||||
AC_MSG_RESULT([$asmavx2])
|
||||
|
||||
dnl AS_IF(HAVE_ASSEMBLY) closed here
|
||||
)
|
||||
|
||||
dnl Checks for test environment
|
||||
AS_CASE([$host],
|
||||
[*-*-mingw*],
|
||||
[
|
||||
TESTENV="$WINE"
|
||||
FAILENV="$TESTENV"
|
||||
],
|
||||
[POSIX=1]
|
||||
)
|
||||
AM_CONDITIONAL(HAVE_POSIX, [test x"$POSIX" != x])
|
||||
|
||||
AC_ARG_ENABLE([profiler],
|
||||
[AS_HELP_STRING([--enable-profiler],[enable the use of gprof for code coverage])],
|
||||
[
|
||||
CFLAGS="-O2 -pg -g -pthread"
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([coverage],
|
||||
[AS_HELP_STRING([--enable-coverage],[enable the use of gcov for code coverage])],
|
||||
[
|
||||
CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage -pthread"
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([valgrind],
|
||||
[AS_HELP_STRING([--enable-valgrind],[enable the use of valgrind in testing])],
|
||||
[
|
||||
TESTENV="$VALGRIND --leak-check=full --error-exitcode=1"
|
||||
FAILENV="$VALGRIND --error-exitcode=1"
|
||||
CFLAGS="$CFLAGS -DCHECKER"
|
||||
MEMORY_CHECKER=1
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([sgcheck],
|
||||
[AS_HELP_STRING([--enable-sgcheck],[enable the use of sgcheck in testing])],
|
||||
[
|
||||
TESTENV="$VALGRIND --tool=exp-sgcheck --suppressions=valgrind.supp --error-exitcode=1"
|
||||
FAILENV="$TESTENV"
|
||||
CFLAGS="$CFLAGS -DCHECKER"
|
||||
MEMORY_CHECKER=1
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([helgrind],
|
||||
[AS_HELP_STRING([--enable-helgrind],[enable the use of helgrind in testing])],
|
||||
[
|
||||
TESTENV="$VALGRIND --tool=helgrind --fair-sched=try --error-exitcode=1"
|
||||
FAILENV="$TESTENV"
|
||||
CFLAGS="$CFLAGS -DCHECKER"
|
||||
THREAD_CHECKER=1
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([drd],
|
||||
[AS_HELP_STRING([--enable-drd],[enable the use of drd in testing])],
|
||||
[
|
||||
TESTENV="$VALGRIND --tool=drd --fair-sched=try --error-exitcode=1"
|
||||
FAILENV="$TESTENV"
|
||||
CFLAGS="$CFLAGS -DCHECKER"
|
||||
THREAD_CHECKER=1
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([asan],
|
||||
[AS_HELP_STRING([--enable-asan],[enable the use of AddressSanitizer in testing])],
|
||||
[
|
||||
CFLAGS="$CFLAGS -DCHECKER -fsanitize=address"
|
||||
MEMORY_CHECKER=1
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([msan],
|
||||
[AS_HELP_STRING([--enable-msan],[enable the use of MemorySanitizer in testing])],
|
||||
[
|
||||
CFLAGS="$CFLAGS -DCHECKER -fsanitize=memory"
|
||||
MEMORY_CHECKER=1
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([ubsan],
|
||||
[AS_HELP_STRING([--enable-ubsan],[enable the use of UndefinedBehaviourSanitizer in testing])],
|
||||
[
|
||||
CFLAGS="$CFLAGS -DCHECKER -fsanitize=undefined"
|
||||
MEMORY_CHECKER=1
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([tsan],
|
||||
[AS_HELP_STRING([--enable-tsan],[enable the use of ThreadSanitizer in testing])],
|
||||
[
|
||||
CFLAGS="$CFLAGS -DCHECKER -fsanitize=thread"
|
||||
dnl Use MEMORY_CHECKER instead of THREAD_CHECKER to run the full and long test
|
||||
MEMORY_CHECKER=1
|
||||
],
|
||||
[])
|
||||
|
||||
AM_CONDITIONAL(HAVE_MEMORY_CHECKER, [test x"$MEMORY_CHECKER" != x])
|
||||
AM_CONDITIONAL(HAVE_THREAD_CHECKER, [test x"$THREAD_CHECKER" != x])
|
||||
|
||||
AC_ARG_ENABLE([sde],
|
||||
[AS_HELP_STRING([--enable-sde],[enable the use of SDE emulator in testing])],
|
||||
dnl p4p -> Pentium4 Prescott with SSE2
|
||||
dnl mrm -> Merom with SSSE3
|
||||
dnl nhm -> Nehalem with SSE4.2
|
||||
dnl hsw -> Haswell with AVX2
|
||||
dnl knl -> Knights Landing with AVX512
|
||||
[
|
||||
TESTENV_SSE2="$SDE -p4p --"
|
||||
TESTENV_SSSE3="$SDE -mrm --"
|
||||
TESTENV_SSE42="$SDE -nhm --"
|
||||
TESTENV_AVX2="$SDE -hsw --"
|
||||
EMULATOR=1
|
||||
# Target CPU compatible with P4 Prescott
|
||||
CFLAGS="$CFLAGS -march=athlon64"
|
||||
],
|
||||
[])
|
||||
AM_CONDITIONAL(HAVE_EMULATOR, [test x"$EMULATOR" != x])
|
||||
|
||||
AC_ARG_ENABLE([debug],
|
||||
[AS_HELP_STRING([--enable-debug],[enable debugging])],
|
||||
[
|
||||
CFLAGS="-Og -g -pthread -Wall -Wextra"
|
||||
AC_CHECK_CC_OPT([-rdynamic], CFLAGS="$CFLAGS -rdynamic", [])
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([warning-as-error],
|
||||
[AS_HELP_STRING([--enable-warning-as-error],[stop build on warnings])],
|
||||
[
|
||||
AC_CHECK_CC_OPT([-Werror], CFLAGS="$CFLAGS -Werror", [])
|
||||
dnl This avoid the Darwin error: clang: error: argument unused during compilation: '-pthread'
|
||||
dnl See: https://llvm.org/bugs/show_bug.cgi?id=7798
|
||||
AC_CHECK_CC_OPT([-Wno-error=unused-command-line-argument], CFLAGS="$CFLAGS -Wno-error=unused-command-line-argument", [])
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_ENABLE([warning],
|
||||
[AS_HELP_STRING([--enable-warning],[enable extra warning])],
|
||||
[
|
||||
AC_CHECK_CC_OPT([-Wpointer-arith], CFLAGS="$CFLAGS -Wpointer-arith", [])
|
||||
AC_CHECK_CC_OPT([-Wcast-qual], CFLAGS="$CFLAGS -Wcast-qual", [])
|
||||
AC_CHECK_CC_OPT([-Wunused], CFLAGS="$CFLAGS -Wunused", [])
|
||||
AC_CHECK_CC_OPT([-Wunreachable-code], CFLAGS="$CFLAGS -Wunreachable-code", [])
|
||||
AC_CHECK_CC_OPT([-Wpadded], CFLAGS="$CFLAGS -Wpadded", [])
|
||||
AC_CHECK_CC_OPT([-Weverything], CFLAGS="$CFLAGS -Weverything", [])
|
||||
],
|
||||
[])
|
||||
|
||||
AC_ARG_VAR([TESTENV], [Test environment])
|
||||
AC_ARG_VAR([FAILENV], [Test environment for failing tests])
|
||||
AC_ARG_VAR([TESTENV_SSE2], [Test environment for SSE2])
|
||||
AC_ARG_VAR([TESTENV_SSSE3], [Test environment for SSSE3])
|
||||
AC_ARG_VAR([TESTENV_SSE42], [Test environment for SSE42])
|
||||
AC_ARG_VAR([TESTENV_AVX2], [Test environment for AVX2])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
3
configure.windows-x64
Executable file
3
configure.windows-x64
Executable file
@ -0,0 +1,3 @@
|
||||
./configure --host=x86_64-w64-mingw32.static --build=`./config.guess` $@
|
||||
|
||||
|
3
configure.windows-x86
Executable file
3
configure.windows-x86
Executable file
@ -0,0 +1,3 @@
|
||||
./configure --host=i686-w64-mingw32.static --build=`./config.guess` $@
|
||||
|
||||
|
501
install-sh
Executable file
501
install-sh
Executable file
@ -0,0 +1,501 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2013-12-25.23; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
# following copyright and license.
|
||||
#
|
||||
# Copyright (C) 1994 X Consortium
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to
|
||||
# deal in the Software without restriction, including without limitation the
|
||||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
# sell copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the X Consortium shall not
|
||||
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||
# ings in this Software without prior written authorization from the X Consor-
|
||||
# tium.
|
||||
#
|
||||
#
|
||||
# FSF changes to this file are in the public domain.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# 'make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
|
||||
tab=' '
|
||||
nl='
|
||||
'
|
||||
IFS=" $tab$nl"
|
||||
|
||||
# Set DOITPROG to "echo" to test this script.
|
||||
|
||||
doit=${DOITPROG-}
|
||||
doit_exec=${doit:-exec}
|
||||
|
||||
# Put in absolute file names if you don't have them in your path;
|
||||
# or use environment vars.
|
||||
|
||||
chgrpprog=${CHGRPPROG-chgrp}
|
||||
chmodprog=${CHMODPROG-chmod}
|
||||
chownprog=${CHOWNPROG-chown}
|
||||
cmpprog=${CMPPROG-cmp}
|
||||
cpprog=${CPPROG-cp}
|
||||
mkdirprog=${MKDIRPROG-mkdir}
|
||||
mvprog=${MVPROG-mv}
|
||||
rmprog=${RMPROG-rm}
|
||||
stripprog=${STRIPPROG-strip}
|
||||
|
||||
posix_mkdir=
|
||||
|
||||
# Desired mode of installed file.
|
||||
mode=0755
|
||||
|
||||
chgrpcmd=
|
||||
chmodcmd=$chmodprog
|
||||
chowncmd=
|
||||
mvcmd=$mvprog
|
||||
rmcmd="$rmprog -f"
|
||||
stripcmd=
|
||||
|
||||
src=
|
||||
dst=
|
||||
dir_arg=
|
||||
dst_arg=
|
||||
|
||||
copy_on_change=false
|
||||
is_target_a_directory=possibly
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||
or: $0 [OPTION]... -d DIRECTORIES...
|
||||
|
||||
In the 1st form, copy SRCFILE to DSTFILE.
|
||||
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||
In the 4th, create DIRECTORIES.
|
||||
|
||||
Options:
|
||||
--help display this help and exit.
|
||||
--version display version info and exit.
|
||||
|
||||
-c (ignored)
|
||||
-C install only if different (preserve the last data modification time)
|
||||
-d create directories instead of installing files.
|
||||
-g GROUP $chgrpprog installed files to GROUP.
|
||||
-m MODE $chmodprog installed files to MODE.
|
||||
-o USER $chownprog installed files to USER.
|
||||
-s $stripprog installed files.
|
||||
-t DIRECTORY install into DIRECTORY.
|
||||
-T report an error if DSTFILE is a directory.
|
||||
|
||||
Environment variables override the default commands:
|
||||
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
|
||||
RMPROG STRIPPROG
|
||||
"
|
||||
|
||||
while test $# -ne 0; do
|
||||
case $1 in
|
||||
-c) ;;
|
||||
|
||||
-C) copy_on_change=true;;
|
||||
|
||||
-d) dir_arg=true;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift;;
|
||||
|
||||
--help) echo "$usage"; exit $?;;
|
||||
|
||||
-m) mode=$2
|
||||
case $mode in
|
||||
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
|
||||
echo "$0: invalid mode: $mode" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift;;
|
||||
|
||||
-s) stripcmd=$stripprog;;
|
||||
|
||||
-t)
|
||||
is_target_a_directory=always
|
||||
dst_arg=$2
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
shift;;
|
||||
|
||||
-T) is_target_a_directory=never;;
|
||||
|
||||
--version) echo "$0 $scriptversion"; exit $?;;
|
||||
|
||||
--) shift
|
||||
break;;
|
||||
|
||||
-*) echo "$0: invalid option: $1" >&2
|
||||
exit 1;;
|
||||
|
||||
*) break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# We allow the use of options -d and -T together, by making -d
|
||||
# take the precedence; this is for compatibility with GNU install.
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
if test -n "$dst_arg"; then
|
||||
echo "$0: target directory not allowed when installing a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
|
||||
# When -d is used, all remaining arguments are directories to create.
|
||||
# When -t is used, the destination is already specified.
|
||||
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||
for arg
|
||||
do
|
||||
if test -n "$dst_arg"; then
|
||||
# $@ is not empty: it contains at least $arg.
|
||||
set fnord "$@" "$dst_arg"
|
||||
shift # fnord
|
||||
fi
|
||||
shift # arg
|
||||
dst_arg=$arg
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $dst_arg in
|
||||
-* | [=\(\)!]) dst_arg=./$dst_arg;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
if test $# -eq 0; then
|
||||
if test -z "$dir_arg"; then
|
||||
echo "$0: no input file specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
# It's OK to call 'install-sh -d' without argument.
|
||||
# This can happen when creating conditional directories.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
if test $# -gt 1 || test "$is_target_a_directory" = always; then
|
||||
if test ! -d "$dst_arg"; then
|
||||
echo "$0: $dst_arg: Is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$dir_arg"; then
|
||||
do_exit='(exit $ret); exit $ret'
|
||||
trap "ret=129; $do_exit" 1
|
||||
trap "ret=130; $do_exit" 2
|
||||
trap "ret=141; $do_exit" 13
|
||||
trap "ret=143; $do_exit" 15
|
||||
|
||||
# Set umask so as not to create temps with too-generous modes.
|
||||
# However, 'strip' requires both read and write access to temps.
|
||||
case $mode in
|
||||
# Optimize common cases.
|
||||
*644) cp_umask=133;;
|
||||
*755) cp_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw='% 200'
|
||||
fi
|
||||
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
|
||||
*)
|
||||
if test -z "$stripcmd"; then
|
||||
u_plus_rw=
|
||||
else
|
||||
u_plus_rw=,u+rw
|
||||
fi
|
||||
cp_umask=$mode$u_plus_rw;;
|
||||
esac
|
||||
fi
|
||||
|
||||
for src
|
||||
do
|
||||
# Protect names problematic for 'test' and other utilities.
|
||||
case $src in
|
||||
-* | [=\(\)!]) src=./$src;;
|
||||
esac
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
dst=$src
|
||||
dstdir=$dst
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
if test ! -f "$src" && test ! -d "$src"; then
|
||||
echo "$0: $src does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$dst_arg"; then
|
||||
echo "$0: no destination specified." >&2
|
||||
exit 1
|
||||
fi
|
||||
dst=$dst_arg
|
||||
|
||||
# If destination is a directory, append the input filename; won't work
|
||||
# if double slashes aren't ignored.
|
||||
if test -d "$dst"; then
|
||||
if test "$is_target_a_directory" = never; then
|
||||
echo "$0: $dst_arg: Is a directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
dstdir=$dst
|
||||
dst=$dstdir/`basename "$src"`
|
||||
dstdir_status=0
|
||||
else
|
||||
dstdir=`dirname "$dst"`
|
||||
test -d "$dstdir"
|
||||
dstdir_status=$?
|
||||
fi
|
||||
fi
|
||||
|
||||
obsolete_mkdir_used=false
|
||||
|
||||
if test $dstdir_status != 0; then
|
||||
case $posix_mkdir in
|
||||
'')
|
||||
# Create intermediate dirs using mode 755 as modified by the umask.
|
||||
# This is like FreeBSD 'install' as of 1997-10-28.
|
||||
umask=`umask`
|
||||
case $stripcmd.$umask in
|
||||
# Optimize common cases.
|
||||
*[2367][2367]) mkdir_umask=$umask;;
|
||||
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
|
||||
|
||||
*[0-7])
|
||||
mkdir_umask=`expr $umask + 22 \
|
||||
- $umask % 100 % 40 + $umask % 20 \
|
||||
- $umask % 10 % 4 + $umask % 2
|
||||
`;;
|
||||
*) mkdir_umask=$umask,go-w;;
|
||||
esac
|
||||
|
||||
# With -d, create the new directory with the user-specified mode.
|
||||
# Otherwise, rely on $mkdir_umask.
|
||||
if test -n "$dir_arg"; then
|
||||
mkdir_mode=-m$mode
|
||||
else
|
||||
mkdir_mode=
|
||||
fi
|
||||
|
||||
posix_mkdir=false
|
||||
case $umask in
|
||||
*[123567][0-7][0-7])
|
||||
# POSIX mkdir -p sets u+wx bits regardless of umask, which
|
||||
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
|
||||
;;
|
||||
*)
|
||||
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
|
||||
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
|
||||
|
||||
if (umask $mkdir_umask &&
|
||||
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
|
||||
then
|
||||
if test -z "$dir_arg" || {
|
||||
# Check for POSIX incompatibilities with -m.
|
||||
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
|
||||
# other-writable bit of parent directory when it shouldn't.
|
||||
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
|
||||
ls_ld_tmpdir=`ls -ld "$tmpdir"`
|
||||
case $ls_ld_tmpdir in
|
||||
d????-?r-*) different_mode=700;;
|
||||
d????-?--*) different_mode=755;;
|
||||
*) false;;
|
||||
esac &&
|
||||
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
|
||||
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
|
||||
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
|
||||
}
|
||||
}
|
||||
then posix_mkdir=:
|
||||
fi
|
||||
rmdir "$tmpdir/d" "$tmpdir"
|
||||
else
|
||||
# Remove any dirs left behind by ancient mkdir implementations.
|
||||
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
|
||||
fi
|
||||
trap '' 0;;
|
||||
esac;;
|
||||
esac
|
||||
|
||||
if
|
||||
$posix_mkdir && (
|
||||
umask $mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
|
||||
)
|
||||
then :
|
||||
else
|
||||
|
||||
# The umask is ridiculous, or mkdir does not conform to POSIX,
|
||||
# or it failed possibly due to a race condition. Create the
|
||||
# directory the slow way, step by step, checking for races as we go.
|
||||
|
||||
case $dstdir in
|
||||
/*) prefix='/';;
|
||||
[-=\(\)!]*) prefix='./';;
|
||||
*) prefix='';;
|
||||
esac
|
||||
|
||||
oIFS=$IFS
|
||||
IFS=/
|
||||
set -f
|
||||
set fnord $dstdir
|
||||
shift
|
||||
set +f
|
||||
IFS=$oIFS
|
||||
|
||||
prefixes=
|
||||
|
||||
for d
|
||||
do
|
||||
test X"$d" = X && continue
|
||||
|
||||
prefix=$prefix$d
|
||||
if test -d "$prefix"; then
|
||||
prefixes=
|
||||
else
|
||||
if $posix_mkdir; then
|
||||
(umask=$mkdir_umask &&
|
||||
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
|
||||
# Don't fail if two instances are running concurrently.
|
||||
test -d "$prefix" || exit 1
|
||||
else
|
||||
case $prefix in
|
||||
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
|
||||
*) qprefix=$prefix;;
|
||||
esac
|
||||
prefixes="$prefixes '$qprefix'"
|
||||
fi
|
||||
fi
|
||||
prefix=$prefix/
|
||||
done
|
||||
|
||||
if test -n "$prefixes"; then
|
||||
# Don't fail if two instances are running concurrently.
|
||||
(umask $mkdir_umask &&
|
||||
eval "\$doit_exec \$mkdirprog $prefixes") ||
|
||||
test -d "$dstdir" || exit 1
|
||||
obsolete_mkdir_used=true
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "$dir_arg"; then
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
|
||||
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
|
||||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
|
||||
else
|
||||
|
||||
# Make a couple of temp file names in the proper directory.
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
rmtmp=$dstdir/_rm.$$_
|
||||
|
||||
# Trap to clean up those temp files at exit.
|
||||
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||
|
||||
# Copy the file name to the temp name.
|
||||
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits.
|
||||
#
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||
#
|
||||
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
|
||||
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
|
||||
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
|
||||
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
|
||||
|
||||
# If -C, don't bother to copy if it wouldn't change the file.
|
||||
if $copy_on_change &&
|
||||
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
|
||||
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
|
||||
set -f &&
|
||||
set X $old && old=:$2:$4:$5:$6 &&
|
||||
set X $new && new=:$2:$4:$5:$6 &&
|
||||
set +f &&
|
||||
test "$old" = "$new" &&
|
||||
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
|
||||
then
|
||||
rm -f "$dsttmp"
|
||||
else
|
||||
# Rename the file to the real destination.
|
||||
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
|
||||
|
||||
# The rename failed, perhaps because mv can't rename something else
|
||||
# to itself, or perhaps because mv is so ancient that it does not
|
||||
# support -f.
|
||||
{
|
||||
# Now remove or move aside any old file at destination location.
|
||||
# We try this two ways since rm can't unlink itself on some
|
||||
# systems and the destination file might be busy for other
|
||||
# reasons. In this case, the final cleanup might fail but the new
|
||||
# file should still install successfully.
|
||||
{
|
||||
test ! -f "$dst" ||
|
||||
$doit $rmcmd -f "$dst" 2>/dev/null ||
|
||||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
|
||||
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
|
||||
} ||
|
||||
{ echo "$0: cannot unlink or rename $dst" >&2
|
||||
(exit 1); exit 1
|
||||
}
|
||||
} &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
$doit $mvcmd "$dsttmp" "$dst"
|
||||
}
|
||||
fi || exit 1
|
||||
|
||||
trap '' 0
|
||||
fi
|
||||
done
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
215
missing
Executable file
215
missing
Executable file
@ -0,0 +1,215 @@
|
||||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2013-10-28.13; # UTC
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
if test $# -eq 0; then
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
|
||||
--is-lightweight)
|
||||
# Used by our autoconf macros to check whether the available missing
|
||||
# script is modern enough.
|
||||
exit 0
|
||||
;;
|
||||
|
||||
--run)
|
||||
# Back-compat with the calling convention used by older automake.
|
||||
shift
|
||||
;;
|
||||
|
||||
-h|--h|--he|--hel|--help)
|
||||
echo "\
|
||||
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||
|
||||
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
|
||||
to PROGRAM being missing or too old.
|
||||
|
||||
Options:
|
||||
-h, --help display this help and exit
|
||||
-v, --version output version information and exit
|
||||
|
||||
Supported PROGRAM values:
|
||||
aclocal autoconf autoheader autom4te automake makeinfo
|
||||
bison yacc flex lex help2man
|
||||
|
||||
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
|
||||
'g' are ignored when checking the name.
|
||||
|
||||
Send bug reports to <bug-automake@gnu.org>."
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||
echo "missing $scriptversion (GNU Automake)"
|
||||
exit $?
|
||||
;;
|
||||
|
||||
-*)
|
||||
echo 1>&2 "$0: unknown '$1' option"
|
||||
echo 1>&2 "Try '$0 --help' for more information"
|
||||
exit 1
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Run the given program, remember its exit status.
|
||||
"$@"; st=$?
|
||||
|
||||
# If it succeeded, we are done.
|
||||
test $st -eq 0 && exit 0
|
||||
|
||||
# Also exit now if we it failed (or wasn't found), and '--version' was
|
||||
# passed; such an option is passed most likely to detect whether the
|
||||
# program is present and works.
|
||||
case $2 in --version|--help) exit $st;; esac
|
||||
|
||||
# Exit code 63 means version mismatch. This often happens when the user
|
||||
# tries to use an ancient version of a tool on a file that requires a
|
||||
# minimum version.
|
||||
if test $st -eq 63; then
|
||||
msg="probably too old"
|
||||
elif test $st -eq 127; then
|
||||
# Program was missing.
|
||||
msg="missing on your system"
|
||||
else
|
||||
# Program was found and executed, but failed. Give up.
|
||||
exit $st
|
||||
fi
|
||||
|
||||
perl_URL=http://www.perl.org/
|
||||
flex_URL=http://flex.sourceforge.net/
|
||||
gnu_software_URL=http://www.gnu.org/software
|
||||
|
||||
program_details ()
|
||||
{
|
||||
case $1 in
|
||||
aclocal|automake)
|
||||
echo "The '$1' program is part of the GNU Automake package:"
|
||||
echo "<$gnu_software_URL/automake>"
|
||||
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/autoconf>"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
autoconf|autom4te|autoheader)
|
||||
echo "The '$1' program is part of the GNU Autoconf package:"
|
||||
echo "<$gnu_software_URL/autoconf/>"
|
||||
echo "It also requires GNU m4 and Perl in order to run:"
|
||||
echo "<$gnu_software_URL/m4/>"
|
||||
echo "<$perl_URL>"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice ()
|
||||
{
|
||||
# Normalize program name to check for.
|
||||
normalized_program=`echo "$1" | sed '
|
||||
s/^gnu-//; t
|
||||
s/^gnu//; t
|
||||
s/^g//; t'`
|
||||
|
||||
printf '%s\n' "'$1' is $msg."
|
||||
|
||||
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
|
||||
case $normalized_program in
|
||||
autoconf*)
|
||||
echo "You should only need it if you modified 'configure.ac',"
|
||||
echo "or m4 files included by it."
|
||||
program_details 'autoconf'
|
||||
;;
|
||||
autoheader*)
|
||||
echo "You should only need it if you modified 'acconfig.h' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'autoheader'
|
||||
;;
|
||||
automake*)
|
||||
echo "You should only need it if you modified 'Makefile.am' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'automake'
|
||||
;;
|
||||
aclocal*)
|
||||
echo "You should only need it if you modified 'acinclude.m4' or"
|
||||
echo "$configure_deps."
|
||||
program_details 'aclocal'
|
||||
;;
|
||||
autom4te*)
|
||||
echo "You might have modified some maintainer files that require"
|
||||
echo "the 'autom4te' program to be rebuilt."
|
||||
program_details 'autom4te'
|
||||
;;
|
||||
bison*|yacc*)
|
||||
echo "You should only need it if you modified a '.y' file."
|
||||
echo "You may want to install the GNU Bison package:"
|
||||
echo "<$gnu_software_URL/bison/>"
|
||||
;;
|
||||
lex*|flex*)
|
||||
echo "You should only need it if you modified a '.l' file."
|
||||
echo "You may want to install the Fast Lexical Analyzer package:"
|
||||
echo "<$flex_URL>"
|
||||
;;
|
||||
help2man*)
|
||||
echo "You should only need it if you modified a dependency" \
|
||||
"of a man page."
|
||||
echo "You may want to install the GNU Help2man package:"
|
||||
echo "<$gnu_software_URL/help2man/>"
|
||||
;;
|
||||
makeinfo*)
|
||||
echo "You should only need it if you modified a '.texi' file, or"
|
||||
echo "any other file indirectly affecting the aspect of the manual."
|
||||
echo "You might want to install the Texinfo package:"
|
||||
echo "<$gnu_software_URL/texinfo/>"
|
||||
echo "The spurious makeinfo call might also be the consequence of"
|
||||
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
|
||||
echo "want to install GNU make:"
|
||||
echo "<$gnu_software_URL/make/>"
|
||||
;;
|
||||
*)
|
||||
echo "You might have modified some files without having the proper"
|
||||
echo "tools for further handling them. Check the 'README' file, it"
|
||||
echo "often tells you about the needed prerequisites for installing"
|
||||
echo "this package. You may also peek at any GNU archive site, in"
|
||||
echo "case some other package contains this missing '$1' program."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
give_advice "$1" | sed -e '1s/^/WARNING: /' \
|
||||
-e '2,$s/^/ /' >&2
|
||||
|
||||
# Propagate the correct exit status (expected to be 127 for a program
|
||||
# not found, 63 for a program that failed due to version mismatch).
|
||||
exit $st
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
339
raid/COPYING
Normal file
339
raid/COPYING
Normal file
@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
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 Program or any portion
|
||||
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
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 Program, 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 Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) 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; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, 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 executable. However, as a
|
||||
special exception, the source code 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.
|
||||
|
||||
If distribution of executable or 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 counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program 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.
|
||||
|
||||
5. 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 Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program 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 to
|
||||
this License.
|
||||
|
||||
7. 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 Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program 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 Program.
|
||||
|
||||
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.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program 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.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies 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 Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, 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
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. 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 PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
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.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
185
raid/check.c
Normal file
185
raid/check.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "combo.h"
|
||||
#include "gf.h"
|
||||
|
||||
/**
|
||||
* Validate the provided failed blocks.
|
||||
*
|
||||
* This function checks if the specified failed blocks satisfy the redundancy
|
||||
* information using the data from the known valid parity blocks.
|
||||
*
|
||||
* It's similar at raid_check(), just with a different format for arguments.
|
||||
*
|
||||
* The number of failed blocks @nr must be strictly less than the number of
|
||||
* parities @nv, because you need one more parity to validate the recovering.
|
||||
*
|
||||
* No data or parity blocks are modified.
|
||||
*
|
||||
* @nr Number of failed data blocks.
|
||||
* @id[] Vector of @nr indexes of the failed data blocks.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* @nv Number of valid parity blocks.
|
||||
* @ip[] Vector of @nv indexes of the valid parity blocks.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* @nd Number of data blocks.
|
||||
* @size Size of the blocks pointed by @v. It must be a multipler of 64.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @ip[@nv - 1] + 1) elements. The starting elements are the
|
||||
* blocks for data, following with the parity blocks.
|
||||
* Each block has @size bytes.
|
||||
* @return 0 if the check is satisfied. -1 otherwise.
|
||||
*/
|
||||
static int raid_validate(int nr, int *id, int nv, int *ip, int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
const uint8_t *T[RAID_PARITY_MAX][RAID_PARITY_MAX];
|
||||
uint8_t G[RAID_PARITY_MAX * RAID_PARITY_MAX];
|
||||
uint8_t V[RAID_PARITY_MAX * RAID_PARITY_MAX];
|
||||
size_t i;
|
||||
int j, k, l;
|
||||
|
||||
BUG_ON(nr >= nv);
|
||||
|
||||
/* setup the coefficients matrix */
|
||||
for (j = 0; j < nr; ++j)
|
||||
for (k = 0; k < nr; ++k)
|
||||
G[j * nr + k] = A(ip[j], id[k]);
|
||||
|
||||
/* invert it to solve the system of linear equations */
|
||||
raid_invert(G, V, nr);
|
||||
|
||||
/* get multiplication tables */
|
||||
for (j = 0; j < nr; ++j)
|
||||
for (k = 0; k < nr; ++k)
|
||||
T[j][k] = table(V[j * nr + k]);
|
||||
|
||||
/* check all positions */
|
||||
for (i = 0; i < size; ++i) {
|
||||
uint8_t p[RAID_PARITY_MAX];
|
||||
|
||||
/* get parity */
|
||||
for (j = 0; j < nv; ++j)
|
||||
p[j] = v[nd + ip[j]][i];
|
||||
|
||||
/* compute delta parity, skipping broken disks */
|
||||
for (j = 0, k = 0; j < nd; ++j) {
|
||||
uint8_t b;
|
||||
|
||||
/* skip broken disks */
|
||||
if (k < nr && id[k] == j) {
|
||||
++k;
|
||||
continue;
|
||||
}
|
||||
|
||||
b = v[j][i];
|
||||
for (l = 0; l < nv; ++l)
|
||||
p[l] ^= gfmul[b][gfgen[ip[l]][j]];
|
||||
}
|
||||
|
||||
/* reconstruct data */
|
||||
for (j = 0; j < nr; ++j) {
|
||||
uint8_t b = 0;
|
||||
int idj = id[j];
|
||||
|
||||
/* recompute the data */
|
||||
for (k = 0; k < nr; ++k)
|
||||
b ^= T[j][k][p[k]];
|
||||
|
||||
/* add the parity contribution of the reconstructed data */
|
||||
for (l = nr; l < nv; ++l)
|
||||
p[l] ^= gfmul[b][gfgen[ip[l]][idj]];
|
||||
}
|
||||
|
||||
/* check that the final parity is 0 */
|
||||
for (l = nr; l < nv; ++l)
|
||||
if (p[l] != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v)
|
||||
{
|
||||
/* valid parity index */
|
||||
int ip[RAID_PARITY_MAX];
|
||||
int vp;
|
||||
int rd;
|
||||
int i, j;
|
||||
|
||||
/* enforce limit on size */
|
||||
BUG_ON(size % 64 != 0);
|
||||
|
||||
/* enforce limit on number of failures */
|
||||
BUG_ON(nr >= np); /* >= because we check with extra parity */
|
||||
BUG_ON(np > RAID_PARITY_MAX);
|
||||
|
||||
/* enforce order in index vector */
|
||||
BUG_ON(nr >= 2 && ir[0] >= ir[1]);
|
||||
BUG_ON(nr >= 3 && ir[1] >= ir[2]);
|
||||
BUG_ON(nr >= 4 && ir[2] >= ir[3]);
|
||||
BUG_ON(nr >= 5 && ir[3] >= ir[4]);
|
||||
BUG_ON(nr >= 6 && ir[4] >= ir[5]);
|
||||
|
||||
/* enforce limit on index vector */
|
||||
BUG_ON(nr > 0 && ir[nr-1] >= nd + np);
|
||||
|
||||
/* count failed data disk */
|
||||
rd = 0;
|
||||
while (rd < nr && ir[rd] < nd)
|
||||
++rd;
|
||||
|
||||
/* put valid parities into ip[] */
|
||||
vp = 0;
|
||||
for (i = rd, j = 0; j < np; ++j) {
|
||||
/* if parity is failed */
|
||||
if (i < nr && ir[i] == nd + j) {
|
||||
/* skip broken parity */
|
||||
++i;
|
||||
} else {
|
||||
/* store valid parity */
|
||||
ip[vp] = j;
|
||||
++vp;
|
||||
}
|
||||
}
|
||||
|
||||
return raid_validate(rd, ir, vp, ip, nd, size, v);
|
||||
}
|
||||
|
||||
int raid_scan(int *ir, int nd, int np, size_t size, void **v)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* check the special case of no failure */
|
||||
if (np != 0 && raid_check(0, 0, nd, np, size, v) == 0)
|
||||
return 0;
|
||||
|
||||
/* for each number of possible failures */
|
||||
for (r = 1; r < np; ++r) {
|
||||
/* try all combinations of r failures on n disks */
|
||||
combination_first(r, nd + np, ir);
|
||||
do {
|
||||
/* verify if the combination is a valid one */
|
||||
if (raid_check(r, ir, nd, np, size, v) == 0)
|
||||
return r;
|
||||
} while (combination_next(r, nd + np, ir));
|
||||
}
|
||||
|
||||
/* no solution found */
|
||||
return -1;
|
||||
}
|
||||
|
155
raid/combo.h
Normal file
155
raid/combo.h
Normal file
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __RAID_COMBO_H
|
||||
#define __RAID_COMBO_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* Get the first permutation with repetition of r of n elements.
|
||||
*
|
||||
* Typical use is with permutation_next() in the form :
|
||||
*
|
||||
* int i[R];
|
||||
* permutation_first(R, N, i);
|
||||
* do {
|
||||
* code using i[0], i[1], ..., i[R-1]
|
||||
* } while (permutation_next(R, N, i));
|
||||
*
|
||||
* It's equivalent at the code :
|
||||
*
|
||||
* for(i[0]=0;i[0]<N;++i[0])
|
||||
* for(i[1]=0;i[1]<N;++i[1])
|
||||
* ...
|
||||
* for(i[R-2]=0;i[R-2]<N;++i[R-2])
|
||||
* for(i[R-1]=0;i[R-1]<N;++i[R-1])
|
||||
* code using i[0], i[1], ..., i[R-1]
|
||||
*/
|
||||
static __always_inline void permutation_first(int r, int n, int *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)n; /* unused, but kept for clarity */
|
||||
assert(0 < r && r <= n);
|
||||
|
||||
for (i = 0; i < r; ++i)
|
||||
c[i] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next permutation with repetition of r of n elements.
|
||||
* Return ==0 when finished.
|
||||
*/
|
||||
static __always_inline int permutation_next(int r, int n, int *c)
|
||||
{
|
||||
int i = r - 1; /* present position */
|
||||
|
||||
recurse:
|
||||
/* next element at position i */
|
||||
++c[i];
|
||||
|
||||
/* if the position has reached the max */
|
||||
if (c[i] >= n) {
|
||||
|
||||
/* if we are at the first level, we have finished */
|
||||
if (i == 0)
|
||||
return 0;
|
||||
|
||||
/* increase the previous position */
|
||||
--i;
|
||||
goto recurse;
|
||||
}
|
||||
|
||||
++i;
|
||||
|
||||
/* initialize all the next positions, if any */
|
||||
while (i < r) {
|
||||
c[i] = 0;
|
||||
++i;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first combination without repetition of r of n elements.
|
||||
*
|
||||
* Typical use is with combination_next() in the form :
|
||||
*
|
||||
* int i[R];
|
||||
* combination_first(R, N, i);
|
||||
* do {
|
||||
* code using i[0], i[1], ..., i[R-1]
|
||||
* } while (combination_next(R, N, i));
|
||||
*
|
||||
* It's equivalent at the code :
|
||||
*
|
||||
* for(i[0]=0;i[0]<N-(R-1);++i[0])
|
||||
* for(i[1]=i[0]+1;i[1]<N-(R-2);++i[1])
|
||||
* ...
|
||||
* for(i[R-2]=i[R-3]+1;i[R-2]<N-1;++i[R-2])
|
||||
* for(i[R-1]=i[R-2]+1;i[R-1]<N;++i[R-1])
|
||||
* code using i[0], i[1], ..., i[R-1]
|
||||
*/
|
||||
static __always_inline void combination_first(int r, int n, int *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)n; /* unused, but kept for clarity */
|
||||
assert(0 < r && r <= n);
|
||||
|
||||
for (i = 0; i < r; ++i)
|
||||
c[i] = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next combination without repetition of r of n elements.
|
||||
* Return ==0 when finished.
|
||||
*/
|
||||
static __always_inline int combination_next(int r, int n, int *c)
|
||||
{
|
||||
int i = r - 1; /* present position */
|
||||
int h = n; /* high limit for this position */
|
||||
|
||||
recurse:
|
||||
/* next element at position i */
|
||||
++c[i];
|
||||
|
||||
/* if the position has reached the max */
|
||||
if (c[i] >= h) {
|
||||
|
||||
/* if we are at the first level, we have finished */
|
||||
if (i == 0)
|
||||
return 0;
|
||||
|
||||
/* increase the previous position */
|
||||
--i;
|
||||
--h;
|
||||
goto recurse;
|
||||
}
|
||||
|
||||
++i;
|
||||
|
||||
/* initialize all the next positions, if any */
|
||||
while (i < r) {
|
||||
/* each position start at the next value of the previous one */
|
||||
c[i] = c[i - 1] + 1;
|
||||
++i;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
331
raid/cpu.h
Normal file
331
raid/cpu.h
Normal file
@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __RAID_CPU_H
|
||||
#define __RAID_CPU_H
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
|
||||
static inline void raid_cpuid(uint32_t func_eax, uint32_t sub_ecx, uint32_t *reg)
|
||||
{
|
||||
asm volatile (
|
||||
#if defined(__i386__) && defined(__PIC__)
|
||||
/* allow compilation in PIC mode saving ebx */
|
||||
"xchgl %%ebx, %1\n"
|
||||
"cpuid\n"
|
||||
"xchgl %%ebx, %1\n"
|
||||
: "=a" (reg[0]), "=r" (reg[1]), "=c" (reg[2]), "=d" (reg[3])
|
||||
: "0" (func_eax), "2" (sub_ecx)
|
||||
#else
|
||||
"cpuid\n"
|
||||
: "=a" (reg[0]), "=b" (reg[1]), "=c" (reg[2]), "=d" (reg[3])
|
||||
: "0" (func_eax), "2" (sub_ecx)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
static inline void raid_xgetbv(uint32_t* reg)
|
||||
{
|
||||
/* get the value of the Extended Control Register ecx=0 */
|
||||
asm volatile (
|
||||
/* uses a direct encoding of the XGETBV instruction as only recent */
|
||||
/* assemblers support it. */
|
||||
/* the next line is equivalent at: "xgetbv\n" */
|
||||
".byte 0x0f, 0x01, 0xd0\n"
|
||||
: "=a" (reg[0]), "=d" (reg[3])
|
||||
: "c" (0)
|
||||
);
|
||||
}
|
||||
|
||||
#define CPU_VENDOR_MAX 13
|
||||
|
||||
static inline void raid_cpu_info(char *vendor, unsigned *family, unsigned *model)
|
||||
{
|
||||
uint32_t reg[4];
|
||||
unsigned f, ef, m, em;
|
||||
|
||||
raid_cpuid(0, 0, reg);
|
||||
|
||||
((uint32_t*)vendor)[0] = reg[1];
|
||||
((uint32_t*)vendor)[1] = reg[3];
|
||||
((uint32_t*)vendor)[2] = reg[2];
|
||||
vendor[12] = 0;
|
||||
|
||||
raid_cpuid(1, 0, reg);
|
||||
|
||||
f = (reg[0] >> 8) & 0xF;
|
||||
ef = (reg[0] >> 20) & 0xFF;
|
||||
m = (reg[0] >> 4) & 0xF;
|
||||
em = (reg[0] >> 16) & 0xF;
|
||||
|
||||
if (strcmp(vendor, "AuthenticAMD") == 0) {
|
||||
if (f < 15) {
|
||||
*family = f;
|
||||
*model = m;
|
||||
} else {
|
||||
*family = f + ef;
|
||||
*model = m + (em << 4);
|
||||
}
|
||||
} else {
|
||||
*family = f + ef;
|
||||
*model = m + (em << 4);
|
||||
}
|
||||
}
|
||||
|
||||
static inline int raid_cpu_match_sse(uint32_t cpuid_1_ecx, uint32_t cpuid_1_edx)
|
||||
{
|
||||
uint32_t reg[4];
|
||||
|
||||
raid_cpuid(1, 0, reg);
|
||||
if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
|
||||
return 0;
|
||||
if ((reg[3] & cpuid_1_edx) != cpuid_1_edx)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int raid_cpu_match_avx(uint32_t cpuid_1_ecx, uint32_t cpuid_7_ebx, uint32_t xcr0)
|
||||
{
|
||||
uint32_t reg[4];
|
||||
|
||||
raid_cpuid(1, 0, reg);
|
||||
if ((reg[2] & cpuid_1_ecx) != cpuid_1_ecx)
|
||||
return 0;
|
||||
|
||||
raid_xgetbv(reg);
|
||||
if ((reg[0] & xcr0) != xcr0)
|
||||
return 0;
|
||||
|
||||
raid_cpuid(7, 0, reg);
|
||||
if ((reg[1] & cpuid_7_ebx) != cpuid_7_ebx)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int raid_cpu_has_sse2(void)
|
||||
{
|
||||
/*
|
||||
* Intel® 64 and IA-32 Architectures Software Developer's Manual
|
||||
* 325462-048US September 2013
|
||||
*
|
||||
* 11.6.2 Checking for SSE/SSE2 Support
|
||||
* Before an application attempts to use the SSE and/or SSE2 extensions, it should check
|
||||
* that they are present on the processor:
|
||||
* 1. Check that the processor supports the CPUID instruction. Bit 21 of the EFLAGS
|
||||
* register can be used to check processor's support the CPUID instruction.
|
||||
* 2. Check that the processor supports the SSE and/or SSE2 extensions (true if
|
||||
* CPUID.01H:EDX.SSE[bit 25] = 1 and/or CPUID.01H:EDX.SSE2[bit 26] = 1).
|
||||
*/
|
||||
return raid_cpu_match_sse(
|
||||
0,
|
||||
1 << 26); /* SSE2 */
|
||||
}
|
||||
|
||||
static inline int raid_cpu_has_ssse3(void)
|
||||
{
|
||||
/*
|
||||
* Intel® 64 and IA-32 Architectures Software Developer's Manual
|
||||
* 325462-048US September 2013
|
||||
*
|
||||
* 12.7.2 Checking for SSSE3 Support
|
||||
* Before an application attempts to use the SSSE3 extensions, the application should
|
||||
* follow the steps illustrated in Section 11.6.2, "Checking for SSE/SSE2 Support."
|
||||
* Next, use the additional step provided below:
|
||||
* Check that the processor supports SSSE3 (if CPUID.01H:ECX.SSSE3[bit 9] = 1).
|
||||
*/
|
||||
return raid_cpu_match_sse(
|
||||
1 << 9, /* SSSE3 */
|
||||
1 << 26); /* SSE2 */
|
||||
}
|
||||
|
||||
static inline int raid_cpu_has_crc32(void)
|
||||
{
|
||||
/*
|
||||
* Intel® 64 and IA-32 Architectures Software Developer's Manual
|
||||
* 325462-048US September 2013
|
||||
*
|
||||
* 12.12.3 Checking for SSE4.2 Support
|
||||
* ...
|
||||
* Before an application attempts to use the CRC32 instruction, it must check
|
||||
* that the processor supports SSE4.2 (if CPUID.01H:ECX.SSE4_2[bit 20] = 1).
|
||||
*/
|
||||
return raid_cpu_match_sse(
|
||||
1 << 20, /* CRC32 */
|
||||
0);
|
||||
}
|
||||
|
||||
static inline int raid_cpu_has_avx2(void)
|
||||
{
|
||||
/*
|
||||
* Intel Architecture Instruction Set Extensions Programming Reference
|
||||
* 319433-022 October 2014
|
||||
*
|
||||
* 14.3 Detection of AVX instructions
|
||||
* 1) Detect CPUID.1:ECX.OSXSAVE[bit 27] = 1 (XGETBV enabled for application use1)
|
||||
* 2) Issue XGETBV and verify that XCR0[2:1] = `11b' (XMM state and YMM state are enabled by OS).
|
||||
* 3) detect CPUID.1:ECX.AVX[bit 28] = 1 (AVX instructions supported).
|
||||
* (Step 3 can be done in any order relative to 1 and 2)
|
||||
*
|
||||
* 14.7.1 Detection of AVX2
|
||||
* Hardware support for AVX2 is indicated by CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]=1.
|
||||
* Application Software must identify that hardware supports AVX, after that it must
|
||||
* also detect support for AVX2 by checking CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5].
|
||||
*/
|
||||
return raid_cpu_match_avx(
|
||||
(1 << 27) | (1 << 28), /* OSXSAVE and AVX */
|
||||
1 << 5, /* AVX2 */
|
||||
3 << 1); /* OS saves XMM and YMM registers */
|
||||
}
|
||||
|
||||
static inline int raid_cpu_has_avx512bw(void)
|
||||
{
|
||||
/*
|
||||
* Intel Architecture Instruction Set Extensions Programming Reference
|
||||
* 319433-022 October 2014
|
||||
*
|
||||
* 2.2 Detection of 512-bit Instruction Groups of Intel AVX-512 Family
|
||||
* 1) Detect CPUID.1:ECX.OSXSAVE[bit 27] = 1 (XGETBV enabled for application use)
|
||||
* 2) Execute XGETBV and verify that XCR0[7:5] = `111b' (OPMASK state, upper 256-bit of
|
||||
* ZMM0-ZMM15 and ZMM16-ZMM31 state are enabled by OS) and that XCR0[2:1] = `11b'
|
||||
* (XMM state and YMM state are enabled by OS).
|
||||
* 3) Verify both CPUID.0x7.0:EBX.AVX512F[bit 16] = 1, CPUID.0x7.0:EBX.AVX512BW[bit 30] = 1.
|
||||
*/
|
||||
|
||||
/* note that intentionally we don't check for AVX and AVX2 */
|
||||
/* because the documentation doesn't require that */
|
||||
return raid_cpu_match_avx(
|
||||
1 << 27, /* XSAVE/XGETBV */
|
||||
(1 << 16) | (1 << 30), /* AVX512F and AVX512BW */
|
||||
(3 << 1) | (7 << 5)); /* OS saves XMM, YMM and ZMM registers */
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if it's an Intel Atom CPU.
|
||||
*/
|
||||
static inline int raid_cpu_is_atom(unsigned family, unsigned model)
|
||||
{
|
||||
if (family != 6)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* x86 Architecture CPUID
|
||||
* http://www.sandpile.org/x86/cpuid.htm
|
||||
*
|
||||
* Intel Atom
|
||||
* 1C (28) Atom (45 nm) with 512 KB on-die L2
|
||||
* 26 (38) Atom (45 nm) with 512 KB on-die L2
|
||||
* 36 (54) Atom (32 nm) with 512 KB on-die L2
|
||||
* 27 (39) Atom (32 nm) with 512 KB on-die L2
|
||||
* 35 (53) Atom (?? nm) with ??? KB on-die L2
|
||||
* 4A (74) Atom 2C (22 nm) 1 MB L2 + PowerVR (TGR)
|
||||
* 5A (90) Atom 4C (22 nm) 2 MB L2 + PowerVR (ANN)
|
||||
* 37 (55) Atom 4C (22 nm) 2 MB L2 + Intel Gen7 (BYT)
|
||||
* 4C (76) Atom 4C (14 nm) 2 MB L2 + Intel Gen8 (BSW)
|
||||
* 5D (93) Atom 4C (28 nm TSMC) 1 MB L2 + Mali (SoFIA)
|
||||
* 4D (77) Atom 8C (22 nm) 4 MB L2 (AVN)
|
||||
* ?? Atom ?C (14 nm) ? MB L2 (DVN)
|
||||
*/
|
||||
return model == 28 || model == 38 || model == 54
|
||||
|| model == 39 || model == 53 || model == 74
|
||||
|| model == 90 || model == 55 || model == 76
|
||||
|| model == 93 || model == 77;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the processor has a slow MULT implementation.
|
||||
* If yes, it's better to use a hash not based on multiplication.
|
||||
*/
|
||||
static inline int raid_cpu_has_slowmult(void)
|
||||
{
|
||||
char vendor[CPU_VENDOR_MAX];
|
||||
unsigned family;
|
||||
unsigned model;
|
||||
|
||||
/*
|
||||
* In some cases Murmur3 based on MUL instruction,
|
||||
* is a LOT slower than Spooky2 based on SHIFTs.
|
||||
*/
|
||||
raid_cpu_info(vendor, &family, &model);
|
||||
|
||||
if (strcmp(vendor, "GenuineIntel") == 0) {
|
||||
/*
|
||||
* Intel Atom (Model 28)
|
||||
* murmur3:378 MB/s, spooky2:3413 MB/s (x86)
|
||||
*
|
||||
* Intel Atom (Model 77)
|
||||
* murmur3:1311 MB/s, spooky2:4056 MB/s (x64)
|
||||
*/
|
||||
if (raid_cpu_is_atom(family, model))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the processor has a slow extended set of SSE registers.
|
||||
* If yes, it's better to limit the unroll to the firsrt 8 registers.
|
||||
*/
|
||||
static inline int raid_cpu_has_slowextendedreg(void)
|
||||
{
|
||||
char vendor[CPU_VENDOR_MAX];
|
||||
unsigned family;
|
||||
unsigned model;
|
||||
|
||||
/*
|
||||
* In some cases the PAR2 implementation using 16 SSE registers
|
||||
* is a LITTLE slower than the one using only the first 8 registers.
|
||||
* This doesn't happen for PARZ.
|
||||
*/
|
||||
raid_cpu_info(vendor, &family, &model);
|
||||
|
||||
if (strcmp(vendor, "AuthenticAMD") == 0) {
|
||||
/*
|
||||
* AMD Bulldozer
|
||||
* par2_sse2:4922 MB/s, par2_sse2e:4465 MB/s
|
||||
*/
|
||||
if (family == 21)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(vendor, "GenuineIntel") == 0) {
|
||||
/*
|
||||
* Intel Atom (Model 77)
|
||||
* par2_sse2:5686 MB/s, par2_sse2e:5250 MB/s
|
||||
* parz_sse2:3100 MB/s, parz_sse2e:3400 MB/s
|
||||
* par3_sse3:1921 MB/s, par3_sse3e:1813 MB/s
|
||||
* par4_sse3:1175 MB/s, par4_sse3e:1113 MB/s
|
||||
* par5_sse3:876 MB/s, par5_sse3e:675 MB/s
|
||||
* par6_sse3:705 MB/s, par6_sse3e:529 MB/s
|
||||
*
|
||||
* Intel Atom (Model 77) "Avoton C2750"
|
||||
* par2_sse2:5661 MB/s, par2_sse2e:5382 MB/s
|
||||
* parz_sse2:3110 MB/s, parz_sse2e:3450 MB/s
|
||||
* par3_sse3:1769 MB/s, par3_sse3e:1856 MB/s
|
||||
* par4_sse3:1221 MB/s, par4_sse3e:1141 MB/s
|
||||
* par5_sse3:910 MB/s, par5_sse3e:675 MB/s
|
||||
* par6_sse3:720 MB/s, par6_sse3e:534 MB/s
|
||||
*/
|
||||
if (raid_cpu_is_atom(family, model))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
137
raid/gf.h
Normal file
137
raid/gf.h
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __RAID_GF_H
|
||||
#define __RAID_GF_H
|
||||
|
||||
/*
|
||||
* Galois field operations.
|
||||
*
|
||||
* Basic range checks are implemented using BUG_ON().
|
||||
*/
|
||||
|
||||
/*
|
||||
* GF a*b.
|
||||
*/
|
||||
static __always_inline uint8_t mul(uint8_t a, uint8_t b)
|
||||
{
|
||||
return gfmul[a][b];
|
||||
}
|
||||
|
||||
/*
|
||||
* GF 1/a.
|
||||
* Not defined for a == 0.
|
||||
*/
|
||||
static __always_inline uint8_t inv(uint8_t v)
|
||||
{
|
||||
BUG_ON(v == 0); /* division by zero */
|
||||
|
||||
return gfinv[v];
|
||||
}
|
||||
|
||||
/*
|
||||
* GF 2^a.
|
||||
*/
|
||||
static __always_inline uint8_t pow2(int v)
|
||||
{
|
||||
BUG_ON(v < 0 || v > 254); /* invalid exponent */
|
||||
|
||||
return gfexp[v];
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the multiplication table for a specified value.
|
||||
*/
|
||||
static __always_inline const uint8_t *table(uint8_t v)
|
||||
{
|
||||
return gfmul[v];
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the generator matrix coefficient for parity 'p' and disk 'd'.
|
||||
*/
|
||||
static __always_inline uint8_t A(int p, int d)
|
||||
{
|
||||
return gfgen[p][d];
|
||||
}
|
||||
|
||||
/*
|
||||
* Dereference as uint8_t
|
||||
*/
|
||||
#define v_8(p) (*(uint8_t *)&(p))
|
||||
|
||||
/*
|
||||
* Dereference as uint32_t
|
||||
*/
|
||||
#define v_32(p) (*(uint32_t *)&(p))
|
||||
|
||||
/*
|
||||
* Dereference as uint64_t
|
||||
*/
|
||||
#define v_64(p) (*(uint64_t *)&(p))
|
||||
|
||||
/*
|
||||
* Multiply each byte of a uint32 by 2 in the GF(2^8).
|
||||
*/
|
||||
static __always_inline uint32_t x2_32(uint32_t v)
|
||||
{
|
||||
uint32_t mask = v & 0x80808080U;
|
||||
|
||||
mask = (mask << 1) - (mask >> 7);
|
||||
v = (v << 1) & 0xfefefefeU;
|
||||
v ^= mask & 0x1d1d1d1dU;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Multiply each byte of a uint64 by 2 in the GF(2^8).
|
||||
*/
|
||||
static __always_inline uint64_t x2_64(uint64_t v)
|
||||
{
|
||||
uint64_t mask = v & 0x8080808080808080ULL;
|
||||
|
||||
mask = (mask << 1) - (mask >> 7);
|
||||
v = (v << 1) & 0xfefefefefefefefeULL;
|
||||
v ^= mask & 0x1d1d1d1d1d1d1d1dULL;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Divide each byte of a uint32 by 2 in the GF(2^8).
|
||||
*/
|
||||
static __always_inline uint32_t d2_32(uint32_t v)
|
||||
{
|
||||
uint32_t mask = v & 0x01010101U;
|
||||
|
||||
mask = (mask << 8) - mask;
|
||||
v = (v >> 1) & 0x7f7f7f7fU;
|
||||
v ^= mask & 0x8e8e8e8eU;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
* Divide each byte of a uint64 by 2 in the GF(2^8).
|
||||
*/
|
||||
static __always_inline uint64_t d2_64(uint64_t v)
|
||||
{
|
||||
uint64_t mask = v & 0x0101010101010101ULL;
|
||||
|
||||
mask = (mask << 8) - mask;
|
||||
v = (v >> 1) & 0x7f7f7f7f7f7f7f7fULL;
|
||||
v ^= mask & 0x8e8e8e8e8e8e8e8eULL;
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
94
raid/helper.c
Normal file
94
raid/helper.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define RAID_SWAP(a, b) \
|
||||
do { \
|
||||
if (v[a] > v[b]) { \
|
||||
int t = v[a]; \
|
||||
v[a] = v[b]; \
|
||||
v[b] = t; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
void raid_sort(int n, int *v)
|
||||
{
|
||||
/* sorting networks generated with Batcher's Merge-Exchange */
|
||||
switch (n) {
|
||||
case 2:
|
||||
RAID_SWAP(0, 1);
|
||||
break;
|
||||
case 3:
|
||||
RAID_SWAP(0, 2);
|
||||
RAID_SWAP(0, 1);
|
||||
RAID_SWAP(1, 2);
|
||||
break;
|
||||
case 4:
|
||||
RAID_SWAP(0, 2);
|
||||
RAID_SWAP(1, 3);
|
||||
RAID_SWAP(0, 1);
|
||||
RAID_SWAP(2, 3);
|
||||
RAID_SWAP(1, 2);
|
||||
break;
|
||||
case 5:
|
||||
RAID_SWAP(0, 4);
|
||||
RAID_SWAP(0, 2);
|
||||
RAID_SWAP(1, 3);
|
||||
RAID_SWAP(2, 4);
|
||||
RAID_SWAP(0, 1);
|
||||
RAID_SWAP(2, 3);
|
||||
RAID_SWAP(1, 4);
|
||||
RAID_SWAP(1, 2);
|
||||
RAID_SWAP(3, 4);
|
||||
break;
|
||||
case 6:
|
||||
RAID_SWAP(0, 4);
|
||||
RAID_SWAP(1, 5);
|
||||
RAID_SWAP(0, 2);
|
||||
RAID_SWAP(1, 3);
|
||||
RAID_SWAP(2, 4);
|
||||
RAID_SWAP(3, 5);
|
||||
RAID_SWAP(0, 1);
|
||||
RAID_SWAP(2, 3);
|
||||
RAID_SWAP(4, 5);
|
||||
RAID_SWAP(1, 4);
|
||||
RAID_SWAP(1, 2);
|
||||
RAID_SWAP(3, 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void raid_insert(int n, int *v, int i)
|
||||
{
|
||||
/* we don't use binary search because this is intended */
|
||||
/* for very small vectors and we want to optimize the case */
|
||||
/* of elements inserted already in order */
|
||||
|
||||
/* insert at the end */
|
||||
v[n] = i;
|
||||
|
||||
/* swap until in the correct position */
|
||||
while (n > 0 && v[n - 1] > v[n]) {
|
||||
/* swap */
|
||||
int t = v[n - 1];
|
||||
|
||||
v[n - 1] = v[n];
|
||||
v[n] = t;
|
||||
|
||||
/* previous position */
|
||||
--n;
|
||||
}
|
||||
}
|
||||
|
43
raid/helper.h
Normal file
43
raid/helper.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __RAID_HELPER_H
|
||||
#define __RAID_HELPER_H
|
||||
|
||||
/**
|
||||
* Inserts an integer in a sorted vector.
|
||||
*
|
||||
* This function can be used to insert indexes in order, ready to be used for
|
||||
* calling raid_rec().
|
||||
*
|
||||
* @n Number of integers currently in the vector.
|
||||
* @v Vector of integers already sorted.
|
||||
* It must have extra space for the new elemet at the end.
|
||||
* @i Value to insert.
|
||||
*/
|
||||
void raid_insert(int n, int *v, int i);
|
||||
|
||||
/**
|
||||
* Sorts a small vector of integers.
|
||||
*
|
||||
* If you have indexes not in order, you can use this function to sort them
|
||||
* before calling raid_rec().
|
||||
*
|
||||
* @n Number of integers. No more than RAID_PARITY_MAX.
|
||||
* @v Vector of integers.
|
||||
*/
|
||||
void raid_sort(int n, int *v);
|
||||
|
||||
#endif
|
||||
|
556
raid/int.c
Normal file
556
raid/int.c
Normal file
@ -0,0 +1,556 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "gf.h"
|
||||
|
||||
/*
|
||||
* GEN1 (RAID5 with xor) 32bit C implementation
|
||||
*/
|
||||
void raid_gen1_int32(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint32_t p0;
|
||||
uint32_t p1;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
|
||||
for (i = 0; i < size; i += 8) {
|
||||
p0 = v_32(v[l][i]);
|
||||
p1 = v_32(v[l][i + 4]);
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
p0 ^= v_32(v[d][i]);
|
||||
p1 ^= v_32(v[d][i + 4]);
|
||||
}
|
||||
v_32(p[i]) = p0;
|
||||
v_32(p[i + 4]) = p1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GEN1 (RAID5 with xor) 64bit C implementation
|
||||
*/
|
||||
void raid_gen1_int64(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint64_t p0;
|
||||
uint64_t p1;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
|
||||
for (i = 0; i < size; i += 16) {
|
||||
p0 = v_64(v[l][i]);
|
||||
p1 = v_64(v[l][i + 8]);
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
p0 ^= v_64(v[d][i]);
|
||||
p1 ^= v_64(v[d][i + 8]);
|
||||
}
|
||||
v_64(p[i]) = p0;
|
||||
v_64(p[i + 8]) = p1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GEN2 (RAID6 with powers of 2) 32bit C implementation
|
||||
*/
|
||||
void raid_gen2_int32(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint32_t d0, q0, p0;
|
||||
uint32_t d1, q1, p1;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
|
||||
for (i = 0; i < size; i += 8) {
|
||||
q0 = p0 = v_32(v[l][i]);
|
||||
q1 = p1 = v_32(v[l][i + 4]);
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
d0 = v_32(v[d][i]);
|
||||
d1 = v_32(v[d][i + 4]);
|
||||
|
||||
p0 ^= d0;
|
||||
p1 ^= d1;
|
||||
|
||||
q0 = x2_32(q0);
|
||||
q1 = x2_32(q1);
|
||||
|
||||
q0 ^= d0;
|
||||
q1 ^= d1;
|
||||
}
|
||||
v_32(p[i]) = p0;
|
||||
v_32(p[i + 4]) = p1;
|
||||
v_32(q[i]) = q0;
|
||||
v_32(q[i + 4]) = q1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GEN2 (RAID6 with powers of 2) 64bit C implementation
|
||||
*/
|
||||
void raid_gen2_int64(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint64_t d0, q0, p0;
|
||||
uint64_t d1, q1, p1;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
|
||||
for (i = 0; i < size; i += 16) {
|
||||
q0 = p0 = v_64(v[l][i]);
|
||||
q1 = p1 = v_64(v[l][i + 8]);
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
d0 = v_64(v[d][i]);
|
||||
d1 = v_64(v[d][i + 8]);
|
||||
|
||||
p0 ^= d0;
|
||||
p1 ^= d1;
|
||||
|
||||
q0 = x2_64(q0);
|
||||
q1 = x2_64(q1);
|
||||
|
||||
q0 ^= d0;
|
||||
q1 ^= d1;
|
||||
}
|
||||
v_64(p[i]) = p0;
|
||||
v_64(p[i + 8]) = p1;
|
||||
v_64(q[i]) = q0;
|
||||
v_64(q[i + 8]) = q1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GEN3 (triple parity with Cauchy matrix) 8bit C implementation
|
||||
*
|
||||
* Note that instead of a generic multiplication table, likely resulting
|
||||
* in multiple cache misses, a precomputed table could be used.
|
||||
* But this is only a kind of reference function, and we are not really
|
||||
* interested in speed.
|
||||
*/
|
||||
void raid_gen3_int8(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint8_t d0, r0, q0, p0;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
|
||||
for (i = 0; i < size; i += 1) {
|
||||
p0 = q0 = r0 = 0;
|
||||
for (d = l; d > 0; --d) {
|
||||
d0 = v_8(v[d][i]);
|
||||
|
||||
p0 ^= d0;
|
||||
q0 ^= gfmul[d0][gfgen[1][d]];
|
||||
r0 ^= gfmul[d0][gfgen[2][d]];
|
||||
}
|
||||
|
||||
/* first disk with all coefficients at 1 */
|
||||
d0 = v_8(v[0][i]);
|
||||
|
||||
p0 ^= d0;
|
||||
q0 ^= d0;
|
||||
r0 ^= d0;
|
||||
|
||||
v_8(p[i]) = p0;
|
||||
v_8(q[i]) = q0;
|
||||
v_8(r[i]) = r0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GEN4 (quad parity with Cauchy matrix) 8bit C implementation
|
||||
*
|
||||
* Note that instead of a generic multiplication table, likely resulting
|
||||
* in multiple cache misses, a precomputed table could be used.
|
||||
* But this is only a kind of reference function, and we are not really
|
||||
* interested in speed.
|
||||
*/
|
||||
void raid_gen4_int8(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
uint8_t *s;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint8_t d0, s0, r0, q0, p0;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
s = v[nd + 3];
|
||||
|
||||
for (i = 0; i < size; i += 1) {
|
||||
p0 = q0 = r0 = s0 = 0;
|
||||
for (d = l; d > 0; --d) {
|
||||
d0 = v_8(v[d][i]);
|
||||
|
||||
p0 ^= d0;
|
||||
q0 ^= gfmul[d0][gfgen[1][d]];
|
||||
r0 ^= gfmul[d0][gfgen[2][d]];
|
||||
s0 ^= gfmul[d0][gfgen[3][d]];
|
||||
}
|
||||
|
||||
/* first disk with all coefficients at 1 */
|
||||
d0 = v_8(v[0][i]);
|
||||
|
||||
p0 ^= d0;
|
||||
q0 ^= d0;
|
||||
r0 ^= d0;
|
||||
s0 ^= d0;
|
||||
|
||||
v_8(p[i]) = p0;
|
||||
v_8(q[i]) = q0;
|
||||
v_8(r[i]) = r0;
|
||||
v_8(s[i]) = s0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GEN5 (penta parity with Cauchy matrix) 8bit C implementation
|
||||
*
|
||||
* Note that instead of a generic multiplication table, likely resulting
|
||||
* in multiple cache misses, a precomputed table could be used.
|
||||
* But this is only a kind of reference function, and we are not really
|
||||
* interested in speed.
|
||||
*/
|
||||
void raid_gen5_int8(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
uint8_t *s;
|
||||
uint8_t *t;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint8_t d0, t0, s0, r0, q0, p0;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
s = v[nd + 3];
|
||||
t = v[nd + 4];
|
||||
|
||||
for (i = 0; i < size; i += 1) {
|
||||
p0 = q0 = r0 = s0 = t0 = 0;
|
||||
for (d = l; d > 0; --d) {
|
||||
d0 = v_8(v[d][i]);
|
||||
|
||||
p0 ^= d0;
|
||||
q0 ^= gfmul[d0][gfgen[1][d]];
|
||||
r0 ^= gfmul[d0][gfgen[2][d]];
|
||||
s0 ^= gfmul[d0][gfgen[3][d]];
|
||||
t0 ^= gfmul[d0][gfgen[4][d]];
|
||||
}
|
||||
|
||||
/* first disk with all coefficients at 1 */
|
||||
d0 = v_8(v[0][i]);
|
||||
|
||||
p0 ^= d0;
|
||||
q0 ^= d0;
|
||||
r0 ^= d0;
|
||||
s0 ^= d0;
|
||||
t0 ^= d0;
|
||||
|
||||
v_8(p[i]) = p0;
|
||||
v_8(q[i]) = q0;
|
||||
v_8(r[i]) = r0;
|
||||
v_8(s[i]) = s0;
|
||||
v_8(t[i]) = t0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GEN6 (hexa parity with Cauchy matrix) 8bit C implementation
|
||||
*
|
||||
* Note that instead of a generic multiplication table, likely resulting
|
||||
* in multiple cache misses, a precomputed table could be used.
|
||||
* But this is only a kind of reference function, and we are not really
|
||||
* interested in speed.
|
||||
*/
|
||||
void raid_gen6_int8(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
uint8_t *s;
|
||||
uint8_t *t;
|
||||
uint8_t *u;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint8_t d0, u0, t0, s0, r0, q0, p0;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
s = v[nd + 3];
|
||||
t = v[nd + 4];
|
||||
u = v[nd + 5];
|
||||
|
||||
for (i = 0; i < size; i += 1) {
|
||||
p0 = q0 = r0 = s0 = t0 = u0 = 0;
|
||||
for (d = l; d > 0; --d) {
|
||||
d0 = v_8(v[d][i]);
|
||||
|
||||
p0 ^= d0;
|
||||
q0 ^= gfmul[d0][gfgen[1][d]];
|
||||
r0 ^= gfmul[d0][gfgen[2][d]];
|
||||
s0 ^= gfmul[d0][gfgen[3][d]];
|
||||
t0 ^= gfmul[d0][gfgen[4][d]];
|
||||
u0 ^= gfmul[d0][gfgen[5][d]];
|
||||
}
|
||||
|
||||
/* first disk with all coefficients at 1 */
|
||||
d0 = v_8(v[0][i]);
|
||||
|
||||
p0 ^= d0;
|
||||
q0 ^= d0;
|
||||
r0 ^= d0;
|
||||
s0 ^= d0;
|
||||
t0 ^= d0;
|
||||
u0 ^= d0;
|
||||
|
||||
v_8(p[i]) = p0;
|
||||
v_8(q[i]) = q0;
|
||||
v_8(r[i]) = r0;
|
||||
v_8(s[i]) = s0;
|
||||
v_8(t[i]) = t0;
|
||||
v_8(u[i]) = u0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Recover failure of one data block at index id[0] using parity at index
|
||||
* ip[0] for any RAID level.
|
||||
*
|
||||
* Starting from the equation:
|
||||
*
|
||||
* Pd = A[ip[0],id[0]] * Dx
|
||||
*
|
||||
* and solving we get:
|
||||
*
|
||||
* Dx = A[ip[0],id[0]]^-1 * Pd
|
||||
*/
|
||||
void raid_rec1_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *pa;
|
||||
const uint8_t *T;
|
||||
uint8_t G;
|
||||
uint8_t V;
|
||||
size_t i;
|
||||
|
||||
(void)nr; /* unused, it's always 1 */
|
||||
|
||||
/* if it's RAID5 uses the faster function */
|
||||
if (ip[0] == 0) {
|
||||
raid_rec1of1(id, nd, size, vv);
|
||||
return;
|
||||
}
|
||||
|
||||
/* setup the coefficients matrix */
|
||||
G = A(ip[0], id[0]);
|
||||
|
||||
/* invert it to solve the system of linear equations */
|
||||
V = inv(G);
|
||||
|
||||
/* get multiplication tables */
|
||||
T = table(V);
|
||||
|
||||
/* compute delta parity */
|
||||
raid_delta_gen(1, id, ip, nd, size, vv);
|
||||
|
||||
p = v[nd + ip[0]];
|
||||
pa = v[id[0]];
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
/* delta */
|
||||
uint8_t Pd = p[i] ^ pa[i];
|
||||
|
||||
/* reconstruct */
|
||||
pa[i] = T[Pd];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Recover failure of two data blocks at indexes id[0],id[1] using parity at
|
||||
* indexes ip[0],ip[1] for any RAID level.
|
||||
*
|
||||
* Starting from the equations:
|
||||
*
|
||||
* Pd = A[ip[0],id[0]] * Dx + A[ip[0],id[1]] * Dy
|
||||
* Qd = A[ip[1],id[0]] * Dx + A[ip[1],id[1]] * Dy
|
||||
*
|
||||
* we solve inverting the coefficients matrix.
|
||||
*/
|
||||
void raid_rec2_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *pa;
|
||||
uint8_t *q;
|
||||
uint8_t *qa;
|
||||
const int N = 2;
|
||||
const uint8_t *T[N][N];
|
||||
uint8_t G[N * N];
|
||||
uint8_t V[N * N];
|
||||
size_t i;
|
||||
int j, k;
|
||||
|
||||
(void)nr; /* unused, it's always 2 */
|
||||
|
||||
/* if it's RAID6 recovering with P and Q uses the faster function */
|
||||
if (ip[0] == 0 && ip[1] == 1) {
|
||||
raid_rec2of2_int8(id, ip, nd, size, vv);
|
||||
return;
|
||||
}
|
||||
|
||||
/* setup the coefficients matrix */
|
||||
for (j = 0; j < N; ++j)
|
||||
for (k = 0; k < N; ++k)
|
||||
G[j * N + k] = A(ip[j], id[k]);
|
||||
|
||||
/* invert it to solve the system of linear equations */
|
||||
raid_invert(G, V, N);
|
||||
|
||||
/* get multiplication tables */
|
||||
for (j = 0; j < N; ++j)
|
||||
for (k = 0; k < N; ++k)
|
||||
T[j][k] = table(V[j * N + k]);
|
||||
|
||||
/* compute delta parity */
|
||||
raid_delta_gen(2, id, ip, nd, size, vv);
|
||||
|
||||
p = v[nd + ip[0]];
|
||||
q = v[nd + ip[1]];
|
||||
pa = v[id[0]];
|
||||
qa = v[id[1]];
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
/* delta */
|
||||
uint8_t Pd = p[i] ^ pa[i];
|
||||
uint8_t Qd = q[i] ^ qa[i];
|
||||
|
||||
/* reconstruct */
|
||||
pa[i] = T[0][0][Pd] ^ T[0][1][Qd];
|
||||
qa[i] = T[1][0][Pd] ^ T[1][1][Qd];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Recover failure of N data blocks at indexes id[N] using parity at indexes
|
||||
* ip[N] for any RAID level.
|
||||
*
|
||||
* Starting from the N equations, with 0<=i<N :
|
||||
*
|
||||
* PD[i] = sum(A[ip[i],id[j]] * D[i]) 0<=j<N
|
||||
*
|
||||
* we solve inverting the coefficients matrix.
|
||||
*
|
||||
* Note that referring at previous equations you have:
|
||||
* PD[0] = Pd, PD[1] = Qd, PD[2] = Rd, ...
|
||||
* D[0] = Dx, D[1] = Dy, D[2] = Dz, ...
|
||||
*/
|
||||
void raid_recX_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
uint8_t *p[RAID_PARITY_MAX];
|
||||
uint8_t *pa[RAID_PARITY_MAX];
|
||||
const uint8_t *T[RAID_PARITY_MAX][RAID_PARITY_MAX];
|
||||
uint8_t G[RAID_PARITY_MAX * RAID_PARITY_MAX];
|
||||
uint8_t V[RAID_PARITY_MAX * RAID_PARITY_MAX];
|
||||
size_t i;
|
||||
int j, k;
|
||||
|
||||
/* setup the coefficients matrix */
|
||||
for (j = 0; j < nr; ++j)
|
||||
for (k = 0; k < nr; ++k)
|
||||
G[j * nr + k] = A(ip[j], id[k]);
|
||||
|
||||
/* invert it to solve the system of linear equations */
|
||||
raid_invert(G, V, nr);
|
||||
|
||||
/* get multiplication tables */
|
||||
for (j = 0; j < nr; ++j)
|
||||
for (k = 0; k < nr; ++k)
|
||||
T[j][k] = table(V[j * nr + k]);
|
||||
|
||||
/* compute delta parity */
|
||||
raid_delta_gen(nr, id, ip, nd, size, vv);
|
||||
|
||||
for (j = 0; j < nr; ++j) {
|
||||
p[j] = v[nd + ip[j]];
|
||||
pa[j] = v[id[j]];
|
||||
}
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
uint8_t PD[RAID_PARITY_MAX];
|
||||
|
||||
/* delta */
|
||||
for (j = 0; j < nr; ++j)
|
||||
PD[j] = p[j][i] ^ pa[j][i];
|
||||
|
||||
/* reconstruct */
|
||||
for (j = 0; j < nr; ++j) {
|
||||
uint8_t b = 0;
|
||||
|
||||
for (k = 0; k < nr; ++k)
|
||||
b ^= T[j][k][PD[k]];
|
||||
pa[j][i] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
274
raid/internal.h
Normal file
274
raid/internal.h
Normal file
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __RAID_INTERNAL_H
|
||||
#define __RAID_INTERNAL_H
|
||||
|
||||
/*
|
||||
* Supported instruction sets.
|
||||
*
|
||||
* It may happen that the assembler is too old to support
|
||||
* all instructions, even if the architecture supports them.
|
||||
* These defines allow to exclude from the build the not supported ones.
|
||||
*
|
||||
* If in your project you use a predefined assembler, you can define them
|
||||
* using fixed values, instead of using the HAVE_* defines.
|
||||
*/
|
||||
#if HAVE_CONFIG_H
|
||||
|
||||
/* Includes the project configuration for HAVE_* defines */
|
||||
#include "config.h"
|
||||
|
||||
/* If the compiler supports assembly */
|
||||
#if HAVE_ASSEMBLY
|
||||
/* Autodetect from the compiler */
|
||||
#if defined(__i386__)
|
||||
#define CONFIG_X86 1
|
||||
#define CONFIG_X86_32 1
|
||||
#endif
|
||||
#if defined(__x86_64__)
|
||||
#define CONFIG_X86 1
|
||||
#define CONFIG_X86_64 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Enables SSE2, SSSE3, AVX2 only if the assembler supports it */
|
||||
#if HAVE_SSE2
|
||||
#define CONFIG_SSE2 1
|
||||
#endif
|
||||
#if HAVE_SSSE3
|
||||
#define CONFIG_SSSE3 1
|
||||
#endif
|
||||
#if HAVE_AVX2
|
||||
#define CONFIG_AVX2 1
|
||||
#endif
|
||||
|
||||
#else /* if HAVE_CONFIG_H is not defined */
|
||||
|
||||
/* Assume that assembly is always supported */
|
||||
#if defined(__i386__)
|
||||
#define CONFIG_X86 1
|
||||
#define CONFIG_X86_32 1
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__)
|
||||
#define CONFIG_X86 1
|
||||
#define CONFIG_X86_64 1
|
||||
#endif
|
||||
|
||||
/* Assumes that the assembler supports everything */
|
||||
#ifdef CONFIG_X86
|
||||
#define CONFIG_SSE2 1
|
||||
#define CONFIG_SSSE3 1
|
||||
#define CONFIG_AVX2 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Includes anything required for compatibility.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Inverse assert.
|
||||
*/
|
||||
#define BUG_ON(a) assert(!(a))
|
||||
|
||||
/*
|
||||
* Forced inline.
|
||||
*/
|
||||
#ifndef __always_inline
|
||||
#define __always_inline inline __attribute__((always_inline))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Forced alignment.
|
||||
*/
|
||||
#ifndef __aligned
|
||||
#define __aligned(a) __attribute__((aligned(a)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Align a pointer at the specified size.
|
||||
*/
|
||||
static __always_inline void *__align_ptr(void *ptr, uintptr_t size)
|
||||
{
|
||||
uintptr_t offset = (uintptr_t)ptr;
|
||||
|
||||
offset = (offset + size - 1U) & ~(size - 1U);
|
||||
|
||||
return (void *)offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Includes the main interface headers.
|
||||
*/
|
||||
#include "raid.h"
|
||||
#include "helper.h"
|
||||
|
||||
/*
|
||||
* Internal functions.
|
||||
*
|
||||
* These are intended to provide access for testing.
|
||||
*/
|
||||
int raid_selftest(void);
|
||||
void raid_gen_ref(int nd, int np, size_t size, void **vv);
|
||||
void raid_invert(uint8_t *M, uint8_t *V, int n);
|
||||
void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v);
|
||||
void raid_rec1of1(int *id, int nd, size_t size, void **v);
|
||||
void raid_rec2of2_int8(int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_gen1_int32(int nd, size_t size, void **vv);
|
||||
void raid_gen1_int64(int nd, size_t size, void **vv);
|
||||
void raid_gen1_sse2(int nd, size_t size, void **vv);
|
||||
void raid_gen1_avx2(int nd, size_t size, void **vv);
|
||||
void raid_gen2_int32(int nd, size_t size, void **vv);
|
||||
void raid_gen2_int64(int nd, size_t size, void **vv);
|
||||
void raid_gen2_sse2(int nd, size_t size, void **vv);
|
||||
void raid_gen2_avx2(int nd, size_t size, void **vv);
|
||||
void raid_gen2_sse2ext(int nd, size_t size, void **vv);
|
||||
void raid_genz_int32(int nd, size_t size, void **vv);
|
||||
void raid_genz_int64(int nd, size_t size, void **vv);
|
||||
void raid_genz_sse2(int nd, size_t size, void **vv);
|
||||
void raid_genz_sse2ext(int nd, size_t size, void **vv);
|
||||
void raid_genz_avx2ext(int nd, size_t size, void **vv);
|
||||
void raid_gen3_int8(int nd, size_t size, void **vv);
|
||||
void raid_gen3_ssse3(int nd, size_t size, void **vv);
|
||||
void raid_gen3_ssse3ext(int nd, size_t size, void **vv);
|
||||
void raid_gen3_avx2ext(int nd, size_t size, void **vv);
|
||||
void raid_gen4_int8(int nd, size_t size, void **vv);
|
||||
void raid_gen4_ssse3(int nd, size_t size, void **vv);
|
||||
void raid_gen4_ssse3ext(int nd, size_t size, void **vv);
|
||||
void raid_gen4_avx2ext(int nd, size_t size, void **vv);
|
||||
void raid_gen5_int8(int nd, size_t size, void **vv);
|
||||
void raid_gen5_ssse3(int nd, size_t size, void **vv);
|
||||
void raid_gen5_ssse3ext(int nd, size_t size, void **vv);
|
||||
void raid_gen5_avx2ext(int nd, size_t size, void **vv);
|
||||
void raid_gen6_int8(int nd, size_t size, void **vv);
|
||||
void raid_gen6_ssse3(int nd, size_t size, void **vv);
|
||||
void raid_gen6_ssse3ext(int nd, size_t size, void **vv);
|
||||
void raid_gen6_avx2ext(int nd, size_t size, void **vv);
|
||||
void raid_rec1_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_rec2_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_recX_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_rec1_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_rec2_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_recX_ssse3(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_rec1_avx2(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_rec2_avx2(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
void raid_recX_avx2(int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
|
||||
/*
|
||||
* Internal naming.
|
||||
*
|
||||
* These are intented to provide access for testing.
|
||||
*/
|
||||
const char *raid_gen1_tag(void);
|
||||
const char *raid_gen2_tag(void);
|
||||
const char *raid_genz_tag(void);
|
||||
const char *raid_gen3_tag(void);
|
||||
const char *raid_gen4_tag(void);
|
||||
const char *raid_gen5_tag(void);
|
||||
const char *raid_gen6_tag(void);
|
||||
const char *raid_rec1_tag(void);
|
||||
const char *raid_rec2_tag(void);
|
||||
const char *raid_recX_tag(void);
|
||||
|
||||
/*
|
||||
* Internal forwarders.
|
||||
*/
|
||||
extern void (*raid_gen3_ptr)(int nd, size_t size, void **vv);
|
||||
extern void (*raid_genz_ptr)(int nd, size_t size, void **vv);
|
||||
extern void (*raid_gen_ptr[RAID_PARITY_MAX])(
|
||||
int nd, size_t size, void **vv);
|
||||
extern void (*raid_rec_ptr[RAID_PARITY_MAX])(
|
||||
int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
|
||||
/*
|
||||
* Tables.
|
||||
*/
|
||||
extern const uint8_t raid_gfmul[256][256] __aligned(256);
|
||||
extern const uint8_t raid_gfexp[256] __aligned(256);
|
||||
extern const uint8_t raid_gfinv[256] __aligned(256);
|
||||
extern const uint8_t raid_gfvandermonde[3][256] __aligned(256);
|
||||
extern const uint8_t raid_gfcauchy[6][256] __aligned(256);
|
||||
extern const uint8_t raid_gfcauchypshufb[251][4][2][16] __aligned(256);
|
||||
extern const uint8_t raid_gfmulpshufb[256][2][16] __aligned(256);
|
||||
extern const uint8_t (*raid_gfgen)[256];
|
||||
#define gfmul raid_gfmul
|
||||
#define gfexp raid_gfexp
|
||||
#define gfinv raid_gfinv
|
||||
#define gfvandermonde raid_gfvandermonde
|
||||
#define gfcauchy raid_gfcauchy
|
||||
#define gfgenpshufb raid_gfcauchypshufb
|
||||
#define gfmulpshufb raid_gfmulpshufb
|
||||
#define gfgen raid_gfgen
|
||||
|
||||
/*
|
||||
* Assembler blocks.
|
||||
*/
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
static __always_inline void raid_sse_begin(void)
|
||||
{
|
||||
}
|
||||
|
||||
static __always_inline void raid_sse_end(void)
|
||||
{
|
||||
/* SSE and AVX code uses non-temporal writes, like MOVNTDQ, */
|
||||
/* that use a weak memory model. To ensure that other processors */
|
||||
/* see correctly the data written, we use a store-store memory */
|
||||
/* barrier at the end of the asm code */
|
||||
asm volatile ("sfence" : : : "memory");
|
||||
|
||||
/* clobbers registers used in the asm code */
|
||||
/* this is required because in the Windows ABI, */
|
||||
/* registers xmm6-xmm15 should be kept by the callee. */
|
||||
/* this clobber list force the compiler to save any */
|
||||
/* register that needs to be saved */
|
||||
/* we check for __SSE2_ because we require that the */
|
||||
/* compiler supports SSE2 registers in the clobber list */
|
||||
#ifdef __SSE2__
|
||||
asm volatile ("" : : : "%xmm0", "%xmm1", "%xmm2", "%xmm3");
|
||||
asm volatile ("" : : : "%xmm4", "%xmm5", "%xmm6", "%xmm7");
|
||||
#ifdef CONFIG_X86_64
|
||||
asm volatile ("" : : : "%xmm8", "%xmm9", "%xmm10", "%xmm11");
|
||||
asm volatile ("" : : : "%xmm12", "%xmm13", "%xmm14", "%xmm15");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AVX2
|
||||
static __always_inline void raid_avx_begin(void)
|
||||
{
|
||||
raid_sse_begin();
|
||||
}
|
||||
|
||||
static __always_inline void raid_avx_end(void)
|
||||
{
|
||||
raid_sse_end();
|
||||
|
||||
/* reset the upper part of the ymm registers */
|
||||
/* to avoid the 70 clocks penality on the next */
|
||||
/* xmm register use */
|
||||
asm volatile ("vzeroupper" : : : "memory");
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
#endif
|
||||
|
119
raid/intz.c
Normal file
119
raid/intz.c
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "gf.h"
|
||||
|
||||
/*
|
||||
* GENz (triple parity with powers of 2^-1) 32bit C implementation
|
||||
*/
|
||||
void raid_genz_int32(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t**)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint32_t d0, r0, q0, p0;
|
||||
uint32_t d1, r1, q1, p1;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
|
||||
for (i = 0; i < size; i += 8) {
|
||||
r0 = q0 = p0 = v_32(v[l][i]);
|
||||
r1 = q1 = p1 = v_32(v[l][i + 4]);
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
d0 = v_32(v[d][i]);
|
||||
d1 = v_32(v[d][i + 4]);
|
||||
|
||||
p0 ^= d0;
|
||||
p1 ^= d1;
|
||||
|
||||
q0 = x2_32(q0);
|
||||
q1 = x2_32(q1);
|
||||
|
||||
q0 ^= d0;
|
||||
q1 ^= d1;
|
||||
|
||||
r0 = d2_32(r0);
|
||||
r1 = d2_32(r1);
|
||||
|
||||
r0 ^= d0;
|
||||
r1 ^= d1;
|
||||
}
|
||||
v_32(p[i]) = p0;
|
||||
v_32(p[i + 4]) = p1;
|
||||
v_32(q[i]) = q0;
|
||||
v_32(q[i + 4]) = q1;
|
||||
v_32(r[i]) = r0;
|
||||
v_32(r[i + 4]) = r1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* GENz (triple parity with powers of 2^-1) 64bit C implementation
|
||||
*/
|
||||
void raid_genz_int64(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t**)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
uint64_t d0, r0, q0, p0;
|
||||
uint64_t d1, r1, q1, p1;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
|
||||
for (i = 0; i < size; i += 16) {
|
||||
r0 = q0 = p0 = v_64(v[l][i]);
|
||||
r1 = q1 = p1 = v_64(v[l][i + 8]);
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
d0 = v_64(v[d][i]);
|
||||
d1 = v_64(v[d][i + 8]);
|
||||
|
||||
p0 ^= d0;
|
||||
p1 ^= d1;
|
||||
|
||||
q0 = x2_64(q0);
|
||||
q1 = x2_64(q1);
|
||||
|
||||
q0 ^= d0;
|
||||
q1 ^= d1;
|
||||
|
||||
r0 = d2_64(r0);
|
||||
r1 = d2_64(r1);
|
||||
|
||||
r0 ^= d0;
|
||||
r1 ^= d1;
|
||||
}
|
||||
v_64(p[i]) = p0;
|
||||
v_64(p[i + 8]) = p1;
|
||||
v_64(q[i]) = q0;
|
||||
v_64(q[i + 8]) = q1;
|
||||
v_64(r[i]) = r0;
|
||||
v_64(r[i + 8]) = r1;
|
||||
}
|
||||
}
|
||||
|
154
raid/memory.c
Normal file
154
raid/memory.c
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "memory.h"
|
||||
|
||||
void *raid_malloc_align(size_t size, size_t align_size, void **freeptr)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
uintptr_t offset;
|
||||
|
||||
ptr = malloc(size + align_size);
|
||||
if (!ptr) {
|
||||
/* LCOV_EXCL_START */
|
||||
return 0;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
*freeptr = ptr;
|
||||
|
||||
offset = ((uintptr_t)ptr) % align_size;
|
||||
|
||||
if (offset != 0)
|
||||
ptr += align_size - offset;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *raid_malloc(size_t size, void **freeptr)
|
||||
{
|
||||
return raid_malloc_align(size, RAID_MALLOC_ALIGN, freeptr);
|
||||
}
|
||||
|
||||
void **raid_malloc_vector_align(int nd, int n, size_t size, size_t align_size, size_t displacement_size, void **freeptr)
|
||||
{
|
||||
void **v;
|
||||
unsigned char *va;
|
||||
int i;
|
||||
|
||||
BUG_ON(n <= 0 || nd < 0);
|
||||
|
||||
v = malloc(n * sizeof(void *));
|
||||
if (!v) {
|
||||
/* LCOV_EXCL_START */
|
||||
return 0;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
va = raid_malloc_align(n * (size + displacement_size), align_size, freeptr);
|
||||
if (!va) {
|
||||
/* LCOV_EXCL_START */
|
||||
free(v);
|
||||
return 0;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
v[i] = va;
|
||||
va += size + displacement_size;
|
||||
}
|
||||
|
||||
/* reverse order of the data blocks */
|
||||
/* because they are usually accessed from the last one */
|
||||
for (i = 0; i < nd / 2; ++i) {
|
||||
void *ptr = v[i];
|
||||
|
||||
v[i] = v[nd - 1 - i];
|
||||
v[nd - 1 - i] = ptr;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr)
|
||||
{
|
||||
return raid_malloc_vector_align(nd, n, size, RAID_MALLOC_ALIGN, RAID_MALLOC_DISPLACEMENT, freeptr);
|
||||
}
|
||||
|
||||
void raid_mrand_vector(unsigned seed, int n, size_t size, void **vv)
|
||||
{
|
||||
unsigned char **v = (unsigned char **)vv;
|
||||
int i;
|
||||
size_t j;
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
for (j = 0; j < size; ++j) {
|
||||
/* basic C99/C11 linear congruential generator */
|
||||
seed = seed * 1103515245U + 12345U;
|
||||
|
||||
v[i][j] = seed >> 16;
|
||||
}
|
||||
}
|
||||
|
||||
int raid_mtest_vector(int n, size_t size, void **vv)
|
||||
{
|
||||
unsigned char **v = (unsigned char **)vv;
|
||||
int i;
|
||||
size_t j;
|
||||
unsigned k;
|
||||
unsigned char d;
|
||||
unsigned char p;
|
||||
|
||||
/* fill with 0 */
|
||||
d = 0;
|
||||
for (i = 0; i < n; ++i)
|
||||
for (j = 0; j < size; ++j)
|
||||
v[i][j] = d;
|
||||
|
||||
/* test with all the byte patterns */
|
||||
for (k = 1; k < 256; ++k) {
|
||||
p = d;
|
||||
d = k;
|
||||
|
||||
/* forward fill */
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = 0; j < size; ++j) {
|
||||
if (v[i][j] != p) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
v[i][j] = d;
|
||||
}
|
||||
}
|
||||
|
||||
p = d;
|
||||
d = ~p;
|
||||
/* backward fill with complement */
|
||||
for (i = 0; i < n; ++i) {
|
||||
for (j = size; j > 0; --j) {
|
||||
if (v[i][j - 1] != p) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
v[i][j - 1] = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
96
raid/memory.h
Normal file
96
raid/memory.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __RAID_MEMORY_H
|
||||
#define __RAID_MEMORY_H
|
||||
|
||||
/**
|
||||
* Memory alignment provided by raid_malloc().
|
||||
*
|
||||
* It should guarantee good cache performance everywhere.
|
||||
*/
|
||||
#define RAID_MALLOC_ALIGN 256
|
||||
|
||||
/**
|
||||
* Memory displacement to avoid cache address sharing on contiguous blocks,
|
||||
* used by raid_malloc_vector().
|
||||
*
|
||||
* When allocating a sequence of blocks with a size of power of 2,
|
||||
* there is the risk that the addresses of each block are mapped into the
|
||||
* same cache line and prefetching predictor, resulting in a lot of cache
|
||||
* sharing if you access all the blocks in parallel, from the start to the
|
||||
* end.
|
||||
*
|
||||
* To avoid this effect, it's better if all the blocks are allocated
|
||||
* with a fixed displacement trying to reduce the cache addresses sharing.
|
||||
*
|
||||
* The selected displacement was chosen empirically with some speed tests
|
||||
* with 8/12/16/20/24 data buffers of 256 KB.
|
||||
*
|
||||
* These are the results in MB/s with no displacement:
|
||||
*
|
||||
* sse2
|
||||
* gen1 15368 [MB/s]
|
||||
* gen2 6814 [MB/s]
|
||||
* genz 3033 [MB/s]
|
||||
*
|
||||
* These are the results with displacement resulting in improvments
|
||||
* in the order of 20% or more:
|
||||
*
|
||||
* sse2
|
||||
* gen1 21936 [MB/s]
|
||||
* gen2 11902 [MB/s]
|
||||
* genz 5838 [MB/s]
|
||||
*
|
||||
*/
|
||||
#define RAID_MALLOC_DISPLACEMENT (7*256)
|
||||
|
||||
/**
|
||||
* Aligned malloc.
|
||||
* Use an alignment suitable for the raid functions.
|
||||
*/
|
||||
void *raid_malloc(size_t size, void **freeptr);
|
||||
|
||||
/**
|
||||
* Arbitrary aligned malloc.
|
||||
*/
|
||||
void *raid_malloc_align(size_t size, size_t align_size, void **freeptr);
|
||||
|
||||
/**
|
||||
* Aligned vector allocation.
|
||||
* Use an alignment suitable for the raid functions.
|
||||
* Returns a vector of @n pointers, each one pointing to a block of
|
||||
* the specified @size.
|
||||
* The first @nd elements are reversed in order.
|
||||
*/
|
||||
void **raid_malloc_vector(int nd, int n, size_t size, void **freeptr);
|
||||
|
||||
/**
|
||||
* Arbitrary aligned vector allocation.
|
||||
*/
|
||||
void **raid_malloc_vector_align(int nd, int n, size_t size, size_t align_size, size_t displacement_size, void **freeptr);
|
||||
|
||||
/**
|
||||
* Fills the memory vector with pseudo-random data based on the specified seed.
|
||||
*/
|
||||
void raid_mrand_vector(unsigned seed, int n, size_t size, void **vv);
|
||||
|
||||
/**
|
||||
* Tests the memory vector for RAM problems.
|
||||
* If a problem is found, it crashes.
|
||||
*/
|
||||
int raid_mtest_vector(int n, size_t size, void **vv);
|
||||
|
||||
#endif
|
||||
|
473
raid/module.c
Normal file
473
raid/module.c
Normal file
@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "memory.h"
|
||||
#include "cpu.h"
|
||||
|
||||
/*
|
||||
* Initializes and selects the best algorithm.
|
||||
*/
|
||||
void raid_init(void)
|
||||
{
|
||||
raid_gen3_ptr = raid_gen3_int8;
|
||||
raid_gen_ptr[3] = raid_gen4_int8;
|
||||
raid_gen_ptr[4] = raid_gen5_int8;
|
||||
raid_gen_ptr[5] = raid_gen6_int8;
|
||||
|
||||
if (sizeof(void *) == 4) {
|
||||
raid_gen_ptr[0] = raid_gen1_int32;
|
||||
raid_gen_ptr[1] = raid_gen2_int32;
|
||||
raid_genz_ptr = raid_genz_int32;
|
||||
} else {
|
||||
raid_gen_ptr[0] = raid_gen1_int64;
|
||||
raid_gen_ptr[1] = raid_gen2_int64;
|
||||
raid_genz_ptr = raid_genz_int64;
|
||||
}
|
||||
|
||||
raid_rec_ptr[0] = raid_rec1_int8;
|
||||
raid_rec_ptr[1] = raid_rec2_int8;
|
||||
raid_rec_ptr[2] = raid_recX_int8;
|
||||
raid_rec_ptr[3] = raid_recX_int8;
|
||||
raid_rec_ptr[4] = raid_recX_int8;
|
||||
raid_rec_ptr[5] = raid_recX_int8;
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
raid_gen_ptr[0] = raid_gen1_sse2;
|
||||
#ifdef CONFIG_X86_64
|
||||
if (raid_cpu_has_slowextendedreg()) {
|
||||
raid_gen_ptr[1] = raid_gen2_sse2;
|
||||
} else {
|
||||
raid_gen_ptr[1] = raid_gen2_sse2ext;
|
||||
}
|
||||
/* note that raid_cpu_has_slowextendedreg() doesn't affect parz */
|
||||
raid_genz_ptr = raid_genz_sse2ext;
|
||||
#else
|
||||
raid_gen_ptr[1] = raid_gen2_sse2;
|
||||
raid_genz_ptr = raid_genz_sse2;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
#ifdef CONFIG_X86_64
|
||||
if (raid_cpu_has_slowextendedreg()) {
|
||||
raid_gen3_ptr = raid_gen3_ssse3;
|
||||
raid_gen_ptr[3] = raid_gen4_ssse3;
|
||||
raid_gen_ptr[4] = raid_gen5_ssse3;
|
||||
raid_gen_ptr[5] = raid_gen6_ssse3;
|
||||
} else {
|
||||
raid_gen3_ptr = raid_gen3_ssse3ext;
|
||||
raid_gen_ptr[3] = raid_gen4_ssse3ext;
|
||||
raid_gen_ptr[4] = raid_gen5_ssse3ext;
|
||||
raid_gen_ptr[5] = raid_gen6_ssse3ext;
|
||||
}
|
||||
#else
|
||||
raid_gen3_ptr = raid_gen3_ssse3;
|
||||
raid_gen_ptr[3] = raid_gen4_ssse3;
|
||||
raid_gen_ptr[4] = raid_gen5_ssse3;
|
||||
raid_gen_ptr[5] = raid_gen6_ssse3;
|
||||
#endif
|
||||
raid_rec_ptr[0] = raid_rec1_ssse3;
|
||||
raid_rec_ptr[1] = raid_rec2_ssse3;
|
||||
raid_rec_ptr[2] = raid_recX_ssse3;
|
||||
raid_rec_ptr[3] = raid_recX_ssse3;
|
||||
raid_rec_ptr[4] = raid_recX_ssse3;
|
||||
raid_rec_ptr[5] = raid_recX_ssse3;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
raid_gen_ptr[0] = raid_gen1_avx2;
|
||||
raid_gen_ptr[1] = raid_gen2_avx2;
|
||||
#ifdef CONFIG_X86_64
|
||||
raid_gen3_ptr = raid_gen3_avx2ext;
|
||||
raid_genz_ptr = raid_genz_avx2ext;
|
||||
raid_gen_ptr[3] = raid_gen4_avx2ext;
|
||||
raid_gen_ptr[4] = raid_gen5_avx2ext;
|
||||
raid_gen_ptr[5] = raid_gen6_avx2ext;
|
||||
#endif
|
||||
raid_rec_ptr[0] = raid_rec1_avx2;
|
||||
raid_rec_ptr[1] = raid_rec2_avx2;
|
||||
raid_rec_ptr[2] = raid_recX_avx2;
|
||||
raid_rec_ptr[3] = raid_recX_avx2;
|
||||
raid_rec_ptr[4] = raid_recX_avx2;
|
||||
raid_rec_ptr[5] = raid_recX_avx2;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
/* set the default mode */
|
||||
raid_mode(RAID_MODE_CAUCHY);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reference parity computation.
|
||||
*/
|
||||
void raid_gen_ref(int nd, int np, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
uint8_t p[RAID_PARITY_MAX];
|
||||
int j, d;
|
||||
|
||||
for (j = 0; j < np; ++j)
|
||||
p[j] = 0;
|
||||
|
||||
for (d = 0; d < nd; ++d) {
|
||||
uint8_t b = v[d][i];
|
||||
|
||||
for (j = 0; j < np; ++j)
|
||||
p[j] ^= gfmul[b][gfgen[j][d]];
|
||||
}
|
||||
|
||||
for (j = 0; j < np; ++j)
|
||||
v[nd + j][i] = p[j];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Size of the blocks to test.
|
||||
*/
|
||||
#define TEST_SIZE 4096
|
||||
|
||||
/*
|
||||
* Number of data blocks to test.
|
||||
*/
|
||||
#define TEST_COUNT (65536 / TEST_SIZE)
|
||||
|
||||
/*
|
||||
* Parity generation test.
|
||||
*/
|
||||
static int raid_test_par(int nd, int np, size_t size, void **v, void **ref)
|
||||
{
|
||||
int i;
|
||||
void *t[TEST_COUNT + RAID_PARITY_MAX];
|
||||
|
||||
/* setup data */
|
||||
for (i = 0; i < nd; ++i)
|
||||
t[i] = ref[i];
|
||||
|
||||
/* setup parity */
|
||||
for (i = 0; i < np; ++i)
|
||||
t[nd + i] = v[nd + i];
|
||||
|
||||
raid_gen(nd, np, size, t);
|
||||
|
||||
/* compare parity */
|
||||
for (i = 0; i < np; ++i) {
|
||||
if (memcmp(t[nd + i], ref[nd + i], size) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recovering test.
|
||||
*/
|
||||
static int raid_test_rec(int nr, int *ir, int nd, int np, size_t size, void **v, void **ref)
|
||||
{
|
||||
int i, j;
|
||||
void *t[TEST_COUNT + RAID_PARITY_MAX];
|
||||
|
||||
/* setup data and parity vector */
|
||||
for (i = 0, j = 0; i < nd + np; ++i) {
|
||||
if (j < nr && ir[j] == i) {
|
||||
/* this block has to be recovered */
|
||||
t[i] = v[i];
|
||||
++j;
|
||||
} else {
|
||||
/* this block is used for recovering */
|
||||
t[i] = ref[i];
|
||||
}
|
||||
}
|
||||
|
||||
raid_rec(nr, ir, nd, np, size, t);
|
||||
|
||||
/* compare all data and parity */
|
||||
for (i = 0; i < nd + np; ++i) {
|
||||
if (t[i] != ref[i]
|
||||
&& memcmp(t[i], ref[i], size) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Recovering test for data.
|
||||
*/
|
||||
static int raid_test_data(int nr, int *id, int *ip, int nd, int np, size_t size, void **v, void **ref)
|
||||
{
|
||||
int i, j;
|
||||
void *t[TEST_COUNT + RAID_PARITY_MAX];
|
||||
|
||||
/* setup data vector */
|
||||
for (i = 0, j = 0; i < nd; ++i) {
|
||||
if (j < nr && id[j] == i) {
|
||||
/* this block has to be recovered */
|
||||
t[i] = v[i];
|
||||
++j;
|
||||
} else {
|
||||
/* this block is left unchanged */
|
||||
t[i] = ref[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* setup parity vector */
|
||||
for (i = 0, j = 0; i < np; ++i) {
|
||||
if (j < nr && ip[j] == i) {
|
||||
/* this block is used for recovering */
|
||||
t[nd + i] = ref[nd + i];
|
||||
++j;
|
||||
} else {
|
||||
/* this block should not be read or written */
|
||||
t[nd + i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
raid_data(nr, id, ip, nd, size, t);
|
||||
|
||||
/* compare all data and parity */
|
||||
for (i = 0; i < nd; ++i) {
|
||||
if (t[i] != ref[i]
|
||||
&& t[i] != 0
|
||||
&& memcmp(t[i], ref[i], size) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan test.
|
||||
*/
|
||||
static int raid_test_scan(int nr, int *ir, int nd, int np, size_t size, void **v, void **ref)
|
||||
{
|
||||
int i, j, ret;
|
||||
void *t[TEST_COUNT + RAID_PARITY_MAX];
|
||||
int is[RAID_PARITY_MAX];
|
||||
|
||||
/* setup data and parity vector */
|
||||
for (i = 0, j = 0; i < nd + np; ++i) {
|
||||
if (j < nr && ir[j] == i) {
|
||||
/* this block is bad */
|
||||
t[i] = v[i];
|
||||
++j;
|
||||
} else {
|
||||
/* this block is used for recovering */
|
||||
t[i] = ref[i];
|
||||
}
|
||||
}
|
||||
|
||||
ret = raid_scan(is, nd, np, size, t);
|
||||
|
||||
/* compare identified bad blocks */
|
||||
if (ret != nr)
|
||||
return -1;
|
||||
for (i = 0; i < nr; ++i) {
|
||||
if (ir[i] != is[i]) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic functionality self test.
|
||||
*/
|
||||
int raid_selftest(void)
|
||||
{
|
||||
const int nd = TEST_COUNT;
|
||||
const size_t size = TEST_SIZE;
|
||||
const int nv = nd + RAID_PARITY_MAX * 2 + 1;
|
||||
void *v_alloc;
|
||||
void **v;
|
||||
void *ref[nd + RAID_PARITY_MAX];
|
||||
int ir[RAID_PARITY_MAX];
|
||||
int ip[RAID_PARITY_MAX];
|
||||
int i, np;
|
||||
int ret = 0;
|
||||
|
||||
/* ensure to have enough space for data */
|
||||
BUG_ON(nd * size > 65536);
|
||||
|
||||
v = raid_malloc_vector(nd, nv, size, &v_alloc);
|
||||
if (!v) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
memset(v[nv - 1], 0, size);
|
||||
raid_zero(v[nv - 1]);
|
||||
|
||||
/* use the multiplication table as data */
|
||||
for (i = 0; i < nd; ++i)
|
||||
ref[i] = ((uint8_t *)gfmul) + size * i;
|
||||
|
||||
/* setup reference parity */
|
||||
for (i = 0; i < RAID_PARITY_MAX; ++i)
|
||||
ref[nd + i] = v[nd + RAID_PARITY_MAX + i];
|
||||
|
||||
/* compute reference parity */
|
||||
raid_gen_ref(nd, RAID_PARITY_MAX, size, ref);
|
||||
|
||||
/* test for each parity level */
|
||||
for (np = 1; np <= RAID_PARITY_MAX; ++np) {
|
||||
/* test parity generation */
|
||||
ret = raid_test_par(nd, np, size, v, ref);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* test recovering with broken ending data disks */
|
||||
for (i = 0; i < np; ++i) {
|
||||
/* bad data */
|
||||
ir[i] = nd - np + i;
|
||||
|
||||
/* good parity */
|
||||
ip[i] = i;
|
||||
}
|
||||
|
||||
ret = raid_test_rec(np, ir, nd, np, size, v, ref);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = raid_test_data(np, ir, ip, nd, np, size, v, ref);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* test recovering with broken leading data and broken leading parity */
|
||||
for (i = 0; i < np / 2; ++i) {
|
||||
/* bad data */
|
||||
ir[i] = i;
|
||||
|
||||
/* good parity */
|
||||
ip[i] = (np + 1) / 2 + i;
|
||||
}
|
||||
|
||||
/* bad parity */
|
||||
for (i = 0; i < (np + 1) / 2; ++i)
|
||||
ir[np / 2 + i] = nd + i;
|
||||
|
||||
ret = raid_test_rec(np, ir, nd, np, size, v, ref);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = raid_test_data(np / 2, ir, ip, nd, np, size, v, ref);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* test recovering with broken leading data and broken ending parity */
|
||||
for (i = 0; i < np / 2; ++i) {
|
||||
/* bad data */
|
||||
ir[i] = i;
|
||||
|
||||
/* good parity */
|
||||
ip[i] = i;
|
||||
}
|
||||
|
||||
/* bad parity */
|
||||
for (i = 0; i < (np + 1) / 2; ++i)
|
||||
ir[np / 2 + i] = nd + np - (np + 1) / 2 + i;
|
||||
|
||||
ret = raid_test_rec(np, ir, nd, np, size, v, ref);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = raid_test_data(np / 2, ir, ip, nd, np, size, v, ref);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* scan test with broken data and parity */
|
||||
for (i = 0; i < np / 2; ++i) {
|
||||
/* bad data */
|
||||
ir[i] = i;
|
||||
}
|
||||
for (i = 0; i < (np - 1) / 2; ++i) {
|
||||
/* bad parity */
|
||||
ir[np / 2 + i] = nd + i;
|
||||
}
|
||||
for (i = 0; i < np - 1; ++i) {
|
||||
/* make blocks bad */
|
||||
/* we cannot fill them with 0, because the original */
|
||||
/* data may be already filled with 0 */
|
||||
memset(v[ir[i]], 0x55, size);
|
||||
}
|
||||
|
||||
ret = raid_test_scan(np - 1, ir, nd, np, size, v, ref);
|
||||
if (ret != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* scan test with no parity */
|
||||
ret = raid_test_scan(0, 0, nd, 0, size, v, ref);
|
||||
if (ret != -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
bail:
|
||||
free(v);
|
||||
free(v_alloc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
586
raid/raid.c
Normal file
586
raid/raid.c
Normal file
@ -0,0 +1,586 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "gf.h"
|
||||
|
||||
/*
|
||||
* This is a RAID implementation working in the Galois Field GF(2^8) with
|
||||
* the primitive polynomial x^8 + x^4 + x^3 + x^2 + 1 (285 decimal), and
|
||||
* supporting up to six parity levels.
|
||||
*
|
||||
* For RAID5 and RAID6 it works as as described in the H. Peter Anvin's
|
||||
* paper "The mathematics of RAID-6" [1]. Please refer to this paper for a
|
||||
* complete explanation.
|
||||
*
|
||||
* To support triple parity, it was first evaluated and then dropped, an
|
||||
* extension of the same approach, with additional parity coefficients set
|
||||
* as powers of 2^-1, with equations:
|
||||
*
|
||||
* P = sum(Di)
|
||||
* Q = sum(2^i * Di)
|
||||
* R = sum(2^-i * Di) with 0<=i<N
|
||||
*
|
||||
* This approach works well for triple parity and it's very efficient,
|
||||
* because we can implement very fast parallel multiplications and
|
||||
* divisions by 2 in GF(2^8).
|
||||
*
|
||||
* It's also similar at the approach used by ZFS RAIDZ3, with the
|
||||
* difference that ZFS uses powers of 4 instead of 2^-1.
|
||||
*
|
||||
* Unfortunately it doesn't work beyond triple parity, because whatever
|
||||
* value we choose to generate the power coefficients to compute other
|
||||
* parities, the resulting equations are not solvable for some
|
||||
* combinations of missing disks.
|
||||
*
|
||||
* This is expected, because the Vandermonde matrix used to compute the
|
||||
* parity has no guarantee to have all submatrices not singular
|
||||
* [2, Chap 11, Problem 7] and this is a requirement to have
|
||||
* a MDS (Maximum Distance Separable) code [2, Chap 11, Theorem 8].
|
||||
*
|
||||
* To overcome this limitation, we use a Cauchy matrix [3][4] to compute
|
||||
* the parity. A Cauchy matrix has the property to have all the square
|
||||
* submatrices not singular, resulting in always solvable equations,
|
||||
* for any combination of missing disks.
|
||||
*
|
||||
* The problem of this approach is that it requires the use of
|
||||
* generic multiplications, and not only by 2 or 2^-1, potentially
|
||||
* affecting badly the performance.
|
||||
*
|
||||
* Hopefully there is a method to implement parallel multiplications
|
||||
* using SSSE3 or AVX2 instructions [1][5]. Method competitive with the
|
||||
* computation of triple parity using power coefficients.
|
||||
*
|
||||
* Another important property of the Cauchy matrix is that we can setup
|
||||
* the first two rows with coeffients equal at the RAID5 and RAID6 approach
|
||||
* decribed, resulting in a compatible extension, and requiring SSSE3
|
||||
* or AVX2 instructions only if triple parity or beyond is used.
|
||||
*
|
||||
* The matrix is also adjusted, multipling each row by a constant factor
|
||||
* to make the first column of all 1, to optimize the computation for
|
||||
* the first disk.
|
||||
*
|
||||
* This results in the matrix A[row,col] defined as:
|
||||
*
|
||||
* 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01...
|
||||
* 01 02 04 08 10 20 40 80 1d 3a 74 e8 cd 87 13 26 4c 98 2d 5a b4 75...
|
||||
* 01 f5 d2 c4 9a 71 f1 7f fc 87 c1 c6 19 2f 40 55 3d ba 53 04 9c 61...
|
||||
* 01 bb a6 d7 c7 07 ce 82 4a 2f a5 9b b6 60 f1 ad e7 f4 06 d2 df 2e...
|
||||
* 01 97 7f 9c 7c 18 bd a2 58 1a da 74 70 a3 e5 47 29 07 f5 80 23 e9...
|
||||
* 01 2b 3f cf 73 2c d6 ed cb 74 15 78 8a c1 17 c9 89 68 21 ab 76 3b...
|
||||
*
|
||||
* This matrix supports 6 level of parity, one for each row, for up to 251
|
||||
* data disks, one for each column, with all the 377,342,351,231 square
|
||||
* submatrices not singular, verified also with brute-force.
|
||||
*
|
||||
* This matrix can be extended to support any number of parities, just
|
||||
* adding additional rows, and removing one column for each new row.
|
||||
* (see mktables.c for more details in how the matrix is generated)
|
||||
*
|
||||
* In details, parity is computed as:
|
||||
*
|
||||
* P = sum(Di)
|
||||
* Q = sum(2^i * Di)
|
||||
* R = sum(A[2,i] * Di)
|
||||
* S = sum(A[3,i] * Di)
|
||||
* T = sum(A[4,i] * Di)
|
||||
* U = sum(A[5,i] * Di) with 0<=i<N
|
||||
*
|
||||
* To recover from a failure of six disks at indexes x,y,z,h,v,w,
|
||||
* with 0<=x<y<z<h<v<w<N, we compute the parity of the available N-6
|
||||
* disks as:
|
||||
*
|
||||
* Pa = sum(Di)
|
||||
* Qa = sum(2^i * Di)
|
||||
* Ra = sum(A[2,i] * Di)
|
||||
* Sa = sum(A[3,i] * Di)
|
||||
* Ta = sum(A[4,i] * Di)
|
||||
* Ua = sum(A[5,i] * Di) with 0<=i<N,i!=x,i!=y,i!=z,i!=h,i!=v,i!=w.
|
||||
*
|
||||
* And if we define:
|
||||
*
|
||||
* Pd = Pa + P
|
||||
* Qd = Qa + Q
|
||||
* Rd = Ra + R
|
||||
* Sd = Sa + S
|
||||
* Td = Ta + T
|
||||
* Ud = Ua + U
|
||||
*
|
||||
* we can sum these two sets of equations, obtaining:
|
||||
*
|
||||
* Pd = Dx + Dy + Dz + Dh + Dv + Dw
|
||||
* Qd = 2^x * Dx + 2^y * Dy + 2^z * Dz + 2^h * Dh + 2^v * Dv + 2^w * Dw
|
||||
* Rd = A[2,x] * Dx + A[2,y] * Dy + A[2,z] * Dz + A[2,h] * Dh + A[2,v] * Dv + A[2,w] * Dw
|
||||
* Sd = A[3,x] * Dx + A[3,y] * Dy + A[3,z] * Dz + A[3,h] * Dh + A[3,v] * Dv + A[3,w] * Dw
|
||||
* Td = A[4,x] * Dx + A[4,y] * Dy + A[4,z] * Dz + A[4,h] * Dh + A[4,v] * Dv + A[4,w] * Dw
|
||||
* Ud = A[5,x] * Dx + A[5,y] * Dy + A[5,z] * Dz + A[5,h] * Dh + A[5,v] * Dv + A[5,w] * Dw
|
||||
*
|
||||
* A linear system always solvable because the coefficients matrix is
|
||||
* always not singular due the properties of the matrix A[].
|
||||
*
|
||||
* Resulting speed in x64, with 8 data disks, using a stripe of 256 KiB,
|
||||
* for a Core i5-4670K Haswell Quad-Core 3.4GHz is:
|
||||
*
|
||||
* int8 int32 int64 sse2 ssse3 avx2
|
||||
* gen1 13339 25438 45438 50588
|
||||
* gen2 4115 6514 21840 32201
|
||||
* gen3 814 10154 18613
|
||||
* gen4 620 7569 14229
|
||||
* gen5 496 5149 10051
|
||||
* gen6 413 4239 8190
|
||||
*
|
||||
* Values are in MiB/s of data processed by a single thread, not counting
|
||||
* generated parity.
|
||||
*
|
||||
* You can replicate these results in your machine using the
|
||||
* "raid/test/speedtest.c" program.
|
||||
*
|
||||
* For comparison, the triple parity computation using the power
|
||||
* coeffients "1,2,2^-1" is only a little faster than the one based on
|
||||
* the Cauchy matrix if SSSE3 or AVX2 is present.
|
||||
*
|
||||
* int8 int32 int64 sse2 ssse3 avx2
|
||||
* genz 2337 2874 10920 18944
|
||||
*
|
||||
* In conclusion, the use of power coefficients, and specifically powers
|
||||
* of 1,2,2^-1, is the best option to implement triple parity in CPUs
|
||||
* without SSSE3 and AVX2.
|
||||
* But if a modern CPU with SSSE3 or AVX2 is available, the Cauchy
|
||||
* matrix is the best option because it provides a fast and general
|
||||
* approach working for any number of parities.
|
||||
*
|
||||
* References:
|
||||
* [1] Anvin, "The mathematics of RAID-6", 2004
|
||||
* [2] MacWilliams, Sloane, "The Theory of Error-Correcting Codes", 1977
|
||||
* [3] Blomer, "An XOR-Based Erasure-Resilient Coding Scheme", 1995
|
||||
* [4] Roth, "Introduction to Coding Theory", 2006
|
||||
* [5] Plank, "Screaming Fast Galois Field Arithmetic Using Intel SIMD Instructions", 2013
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generator matrix currently used.
|
||||
*/
|
||||
const uint8_t (*raid_gfgen)[256];
|
||||
|
||||
void raid_mode(int mode)
|
||||
{
|
||||
if (mode == RAID_MODE_VANDERMONDE) {
|
||||
raid_gen_ptr[2] = raid_genz_ptr;
|
||||
raid_gfgen = gfvandermonde;
|
||||
} else {
|
||||
raid_gen_ptr[2] = raid_gen3_ptr;
|
||||
raid_gfgen = gfcauchy;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Buffer filled with 0 used in recovering.
|
||||
*/
|
||||
static void *raid_zero_block;
|
||||
|
||||
void raid_zero(void *zero)
|
||||
{
|
||||
raid_zero_block = zero;
|
||||
}
|
||||
|
||||
/*
|
||||
* Forwarders for parity computation.
|
||||
*
|
||||
* These functions compute the parity blocks from the provided data.
|
||||
*
|
||||
* The number of parities to compute is implicit in the position in the
|
||||
* forwarder vector. Position at index #i, computes (#i+1) parities.
|
||||
*
|
||||
* All these functions give the guarantee that parities are written
|
||||
* in order. First parity P, then parity Q, and so on.
|
||||
* This allows to specify the same memory buffer for multiple parities
|
||||
* knowning that you'll get the latest written one.
|
||||
* This characteristic is used by the raid_delta_gen() function to
|
||||
* avoid to damage unused parities in recovering.
|
||||
*
|
||||
* @nd Number of data blocks
|
||||
* @size Size of the blocks pointed by @v. It must be a multipler of 64.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + #parities) elements. The starting elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
* Each block has @size bytes.
|
||||
*/
|
||||
void (*raid_gen_ptr[RAID_PARITY_MAX])(int nd, size_t size, void **vv);
|
||||
void (*raid_gen3_ptr)(int nd, size_t size, void **vv);
|
||||
void (*raid_genz_ptr)(int nd, size_t size, void **vv);
|
||||
|
||||
void raid_gen(int nd, int np, size_t size, void **v)
|
||||
{
|
||||
/* enforce limit on size */
|
||||
BUG_ON(size % 64 != 0);
|
||||
|
||||
/* enforce limit on number of failures */
|
||||
BUG_ON(np < 1);
|
||||
BUG_ON(np > RAID_PARITY_MAX);
|
||||
|
||||
raid_gen_ptr[np - 1](nd, size, v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverts the square matrix M of size nxn into V.
|
||||
*
|
||||
* This is not a general matrix inversion because we assume the matrix M
|
||||
* to have all the square submatrix not singular.
|
||||
* We use Gauss elimination to invert.
|
||||
*
|
||||
* @M Matrix to invert with @n rows and @n columns.
|
||||
* @V Destination matrix where the result is put.
|
||||
* @n Number of rows and columns of the matrix.
|
||||
*/
|
||||
void raid_invert(uint8_t *M, uint8_t *V, int n)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
/* set the identity matrix in V */
|
||||
for (i = 0; i < n; ++i)
|
||||
for (j = 0; j < n; ++j)
|
||||
V[i * n + j] = i == j;
|
||||
|
||||
/* for each element in the diagonal */
|
||||
for (k = 0; k < n; ++k) {
|
||||
uint8_t f;
|
||||
|
||||
/* the diagonal element cannot be 0 because */
|
||||
/* we are inverting matrices with all the square */
|
||||
/* submatrices not singular */
|
||||
BUG_ON(M[k * n + k] == 0);
|
||||
|
||||
/* make the diagonal element to be 1 */
|
||||
f = inv(M[k * n + k]);
|
||||
for (j = 0; j < n; ++j) {
|
||||
M[k * n + j] = mul(f, M[k * n + j]);
|
||||
V[k * n + j] = mul(f, V[k * n + j]);
|
||||
}
|
||||
|
||||
/* make all the elements over and under the diagonal */
|
||||
/* to be zero */
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (i == k)
|
||||
continue;
|
||||
f = M[i * n + k];
|
||||
for (j = 0; j < n; ++j) {
|
||||
M[i * n + j] ^= mul(f, M[k * n + j]);
|
||||
V[i * n + j] ^= mul(f, V[k * n + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the parity without the missing data blocks
|
||||
* and store it in the buffers of such data blocks.
|
||||
*
|
||||
* This is the parity expressed as Pa,Qa,Ra,Sa,Ta,Ua in the equations.
|
||||
*/
|
||||
void raid_delta_gen(int nr, int *id, int *ip, int nd, size_t size, void **v)
|
||||
{
|
||||
void *p[RAID_PARITY_MAX];
|
||||
void *pa[RAID_PARITY_MAX];
|
||||
int i, j;
|
||||
int np;
|
||||
void *latest;
|
||||
|
||||
/* total number of parities we are going to process */
|
||||
/* they are both the used and the unused ones */
|
||||
np = ip[nr - 1] + 1;
|
||||
|
||||
/* latest missing data block */
|
||||
latest = v[id[nr - 1]];
|
||||
|
||||
/* setup pointers for delta computation */
|
||||
for (i = 0, j = 0; i < np; ++i) {
|
||||
/* keep a copy of the original parity vector */
|
||||
p[i] = v[nd + i];
|
||||
|
||||
if (ip[j] == i) {
|
||||
/*
|
||||
* Set used parities to point to the missing
|
||||
* data blocks.
|
||||
*
|
||||
* The related data blocks are instead set
|
||||
* to point to the "zero" buffer.
|
||||
*/
|
||||
|
||||
/* the latest parity to use ends the for loop and */
|
||||
/* then it cannot happen to process more of them */
|
||||
BUG_ON(j >= nr);
|
||||
|
||||
/* buffer for missing data blocks */
|
||||
pa[j] = v[id[j]];
|
||||
|
||||
/* set at zero the missing data blocks */
|
||||
v[id[j]] = raid_zero_block;
|
||||
|
||||
/* compute the parity over the missing data blocks */
|
||||
v[nd + i] = pa[j];
|
||||
|
||||
/* check for the next used entry */
|
||||
++j;
|
||||
} else {
|
||||
/*
|
||||
* Unused parities are going to be rewritten with
|
||||
* not significative data, becase we don't have
|
||||
* functions able to compute only a subset of
|
||||
* parities.
|
||||
*
|
||||
* To avoid this, we reuse parity buffers,
|
||||
* assuming that all the parity functions write
|
||||
* parities in order.
|
||||
*
|
||||
* We assign the unused parity block to the same
|
||||
* block of the latest used parity that we know it
|
||||
* will be written.
|
||||
*
|
||||
* This means that this block will be written
|
||||
* multiple times and only the latest write will
|
||||
* contain the correct data.
|
||||
*/
|
||||
v[nd + i] = latest;
|
||||
}
|
||||
}
|
||||
|
||||
/* all the parities have to be processed */
|
||||
BUG_ON(j != nr);
|
||||
|
||||
/* recompute the parity, note that np may be smaller than the */
|
||||
/* total number of parities available */
|
||||
raid_gen(nd, np, size, v);
|
||||
|
||||
/* restore data buffers as before */
|
||||
for (j = 0; j < nr; ++j)
|
||||
v[id[j]] = pa[j];
|
||||
|
||||
/* restore parity buffers as before */
|
||||
for (i = 0; i < np; ++i)
|
||||
v[nd + i] = p[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Recover failure of one data block for PAR1.
|
||||
*
|
||||
* Starting from the equation:
|
||||
*
|
||||
* Pd = Dx
|
||||
*
|
||||
* and solving we get:
|
||||
*
|
||||
* Dx = Pd
|
||||
*/
|
||||
void raid_rec1of1(int *id, int nd, size_t size, void **v)
|
||||
{
|
||||
void *p;
|
||||
void *pa;
|
||||
|
||||
/* for PAR1 we can directly compute the missing block */
|
||||
/* and we don't need to use the zero buffer */
|
||||
p = v[nd];
|
||||
pa = v[id[0]];
|
||||
|
||||
/* use the parity as missing data block */
|
||||
v[id[0]] = p;
|
||||
|
||||
/* compute the parity over the missing data block */
|
||||
v[nd] = pa;
|
||||
|
||||
/* compute */
|
||||
raid_gen(nd, 1, size, v);
|
||||
|
||||
/* restore as before */
|
||||
v[id[0]] = pa;
|
||||
v[nd] = p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recover failure of two data blocks for PAR2.
|
||||
*
|
||||
* Starting from the equations:
|
||||
*
|
||||
* Pd = Dx + Dy
|
||||
* Qd = 2^id[0] * Dx + 2^id[1] * Dy
|
||||
*
|
||||
* and solving we get:
|
||||
*
|
||||
* 1 2^(-id[0])
|
||||
* Dy = ------------------- * Pd + ------------------- * Qd
|
||||
* 2^(id[1]-id[0]) + 1 2^(id[1]-id[0]) + 1
|
||||
*
|
||||
* Dx = Dy + Pd
|
||||
*
|
||||
* with conditions:
|
||||
*
|
||||
* 2^id[0] != 0
|
||||
* 2^(id[1]-id[0]) + 1 != 0
|
||||
*
|
||||
* That are always satisfied for any 0<=id[0]<id[1]<255.
|
||||
*/
|
||||
void raid_rec2of2_int8(int *id, int *ip, int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t **)vv;
|
||||
size_t i;
|
||||
uint8_t *p;
|
||||
uint8_t *pa;
|
||||
uint8_t *q;
|
||||
uint8_t *qa;
|
||||
const uint8_t *T[2];
|
||||
|
||||
/* get multiplication tables */
|
||||
T[0] = table(inv(pow2(id[1] - id[0]) ^ 1));
|
||||
T[1] = table(inv(pow2(id[0]) ^ pow2(id[1])));
|
||||
|
||||
/* compute delta parity */
|
||||
raid_delta_gen(2, id, ip, nd, size, vv);
|
||||
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
pa = v[id[0]];
|
||||
qa = v[id[1]];
|
||||
|
||||
for (i = 0; i < size; ++i) {
|
||||
/* delta */
|
||||
uint8_t Pd = p[i] ^ pa[i];
|
||||
uint8_t Qd = q[i] ^ qa[i];
|
||||
|
||||
/* reconstruct */
|
||||
uint8_t Dy = T[0][Pd] ^ T[1][Qd];
|
||||
uint8_t Dx = Pd ^ Dy;
|
||||
|
||||
/* set */
|
||||
pa[i] = Dx;
|
||||
qa[i] = Dy;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Forwarders for data recovery.
|
||||
*
|
||||
* These functions recover data blocks using the specified parity
|
||||
* to recompute the missing data.
|
||||
*
|
||||
* Note that the format of vectors @id/@ip is different than raid_rec().
|
||||
* For example, in the vector @ip the first parity is represented with the
|
||||
* value 0 and not @nd.
|
||||
*
|
||||
* @nr Number of failed data blocks to recover.
|
||||
* @id[] Vector of @nr indexes of the data blocks to recover.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* @ip[] Vector of @nr indexes of the parity blocks to use in the recovering.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* @nd Number of data blocks.
|
||||
* @np Number of parity blocks.
|
||||
* @size Size of the blocks pointed by @v. It must be a multipler of 64.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
* Each block has @size bytes.
|
||||
*/
|
||||
void (*raid_rec_ptr[RAID_PARITY_MAX])(
|
||||
int nr, int *id, int *ip, int nd, size_t size, void **vv);
|
||||
|
||||
void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v)
|
||||
{
|
||||
int nrd; /* number of data blocks to recover */
|
||||
int nrp; /* number of parity blocks to recover */
|
||||
|
||||
/* enforce limit on size */
|
||||
BUG_ON(size % 64 != 0);
|
||||
|
||||
/* enforce limit on number of failures */
|
||||
BUG_ON(nr > np);
|
||||
BUG_ON(np > RAID_PARITY_MAX);
|
||||
|
||||
/* enforce order in index vector */
|
||||
BUG_ON(nr >= 2 && ir[0] >= ir[1]);
|
||||
BUG_ON(nr >= 3 && ir[1] >= ir[2]);
|
||||
BUG_ON(nr >= 4 && ir[2] >= ir[3]);
|
||||
BUG_ON(nr >= 5 && ir[3] >= ir[4]);
|
||||
BUG_ON(nr >= 6 && ir[4] >= ir[5]);
|
||||
|
||||
/* enforce limit on index vector */
|
||||
BUG_ON(nr > 0 && ir[nr-1] >= nd + np);
|
||||
|
||||
/* count the number of data blocks to recover */
|
||||
nrd = 0;
|
||||
while (nrd < nr && ir[nrd] < nd)
|
||||
++nrd;
|
||||
|
||||
/* all the remaining are parity */
|
||||
nrp = nr - nrd;
|
||||
|
||||
/* enforce limit on number of failures */
|
||||
BUG_ON(nrd > nd);
|
||||
BUG_ON(nrp > np);
|
||||
|
||||
/* if failed data is present */
|
||||
if (nrd != 0) {
|
||||
int ip[RAID_PARITY_MAX];
|
||||
int i, j, k;
|
||||
|
||||
/* setup the vector of parities to use */
|
||||
for (i = 0, j = 0, k = 0; i < np; ++i) {
|
||||
if (j < nrp && ir[nrd + j] == nd + i) {
|
||||
/* this parity has to be recovered */
|
||||
++j;
|
||||
} else {
|
||||
/* this parity is used for recovering */
|
||||
ip[k] = i;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
|
||||
/* recover the nrd data blocks specified in ir[], */
|
||||
/* using the first nrd parity in ip[] for recovering */
|
||||
raid_rec_ptr[nrd - 1](nrd, ir, ip, nd, size, v);
|
||||
}
|
||||
|
||||
/* recompute all the parities up to the last bad one */
|
||||
if (nrp != 0)
|
||||
raid_gen(nd, ir[nr - 1] - nd + 1, size, v);
|
||||
}
|
||||
|
||||
void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v)
|
||||
{
|
||||
/* enforce limit on size */
|
||||
BUG_ON(size % 64 != 0);
|
||||
|
||||
/* enforce limit on number of failures */
|
||||
BUG_ON(nr > nd);
|
||||
BUG_ON(nr > RAID_PARITY_MAX);
|
||||
|
||||
/* enforce order in index vector for data */
|
||||
BUG_ON(nr >= 2 && id[0] >= id[1]);
|
||||
BUG_ON(nr >= 3 && id[1] >= id[2]);
|
||||
BUG_ON(nr >= 4 && id[2] >= id[3]);
|
||||
BUG_ON(nr >= 5 && id[3] >= id[4]);
|
||||
BUG_ON(nr >= 6 && id[4] >= id[5]);
|
||||
|
||||
/* enforce limit on index vector for data */
|
||||
BUG_ON(nr > 0 && id[nr-1] >= nd);
|
||||
|
||||
/* enforce order in index vector for parity */
|
||||
BUG_ON(nr >= 2 && ip[0] >= ip[1]);
|
||||
BUG_ON(nr >= 3 && ip[1] >= ip[2]);
|
||||
BUG_ON(nr >= 4 && ip[2] >= ip[3]);
|
||||
BUG_ON(nr >= 5 && ip[3] >= ip[4]);
|
||||
BUG_ON(nr >= 6 && ip[4] >= ip[5]);
|
||||
|
||||
/* if failed data is present */
|
||||
if (nr != 0)
|
||||
raid_rec_ptr[nr - 1](nr, id, ip, nd, size, v);
|
||||
}
|
||||
|
229
raid/raid.h
Normal file
229
raid/raid.h
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __RAID_H
|
||||
#define __RAID_H
|
||||
|
||||
/**
|
||||
* RAID mode supporting up to 6 parities.
|
||||
*
|
||||
* It requires SSSE3 to get good performance with triple or more parities.
|
||||
*
|
||||
* This is the default mode set after calling raid_init().
|
||||
*/
|
||||
#define RAID_MODE_CAUCHY 0
|
||||
|
||||
/**
|
||||
* RAID mode supporting up to 3 parities,
|
||||
*
|
||||
* It has a fast triple parity implementation without SSSE3, but it cannot
|
||||
* go beyond triple parity.
|
||||
*
|
||||
* This is mostly intended for low end CPUs like ARM and AMD Athlon.
|
||||
*/
|
||||
#define RAID_MODE_VANDERMONDE 1
|
||||
|
||||
/**
|
||||
* Maximum number of parity disks supported.
|
||||
*/
|
||||
#define RAID_PARITY_MAX 6
|
||||
|
||||
/**
|
||||
* Maximum number of data disks supported.
|
||||
*/
|
||||
#define RAID_DATA_MAX 251
|
||||
|
||||
/**
|
||||
* Initializes the RAID system.
|
||||
*
|
||||
* You must call this function before any other.
|
||||
*
|
||||
* The RAID system is initialized in the RAID_MODE_CAUCHY mode.
|
||||
*/
|
||||
void raid_init(void);
|
||||
|
||||
/**
|
||||
* Runs a basic functionality self test.
|
||||
*
|
||||
* The test is immediate, and it's intended to be run at application
|
||||
* startup to check the integrity of the RAID system.
|
||||
*
|
||||
* It returns 0 on success.
|
||||
*/
|
||||
int raid_selftest(void);
|
||||
|
||||
/**
|
||||
* Sets the mode to use. One of RAID_MODE_*.
|
||||
*
|
||||
* You can change mode at any time, and it will affect next calls to raid_gen(),
|
||||
* raid_rec() and raid_data().
|
||||
*
|
||||
* The two modes are compatible for the first two levels of parity.
|
||||
* The third one is different.
|
||||
*/
|
||||
void raid_mode(int mode);
|
||||
|
||||
/**
|
||||
* Sets the zero buffer to use in recovering.
|
||||
*
|
||||
* Before calling raid_rec() and raid_data() you must provide a memory
|
||||
* buffer filled with zero with the same size of the blocks to recover.
|
||||
*
|
||||
* This buffer is only read and never written.
|
||||
*/
|
||||
void raid_zero(void *zero);
|
||||
|
||||
/**
|
||||
* Computes parity blocks.
|
||||
*
|
||||
* This function computes the specified number of parity blocks of the
|
||||
* provided set of data blocks.
|
||||
*
|
||||
* Each parity block allows to recover one data block.
|
||||
*
|
||||
* @nd Number of data blocks.
|
||||
* @np Number of parities blocks to compute.
|
||||
* @size Size of the blocks pointed by @v. It must be a multiplier of 64.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks for
|
||||
* data, following with the parity blocks.
|
||||
* Data blocks are only read and not modified. Parity blocks are written.
|
||||
* Each block has @size bytes.
|
||||
*/
|
||||
void raid_gen(int nd, int np, size_t size, void **v);
|
||||
|
||||
/**
|
||||
* Recovers failures in data and parity blocks.
|
||||
*
|
||||
* This function recovers all the data and parity blocks marked as bad
|
||||
* in the @ir vector.
|
||||
*
|
||||
* Ensure to have @nr <= @np, otherwise recovering is not possible.
|
||||
*
|
||||
* The parities blocks used for recovering are automatically selected from
|
||||
* the ones NOT present in the @ir vector.
|
||||
*
|
||||
* In case there are more parity blocks than needed, the parities at lower
|
||||
* indexes are used in the recovering, and the others are ignored.
|
||||
*
|
||||
* Note that no internal integrity check is done when recovering. If the
|
||||
* provided parities are correct, the resulting data will be correct.
|
||||
* If parities are wrong, the resulting recovered data will be wrong.
|
||||
* This happens even in the case you have more parities blocks than needed,
|
||||
* and some form of integrity verification would be possible.
|
||||
*
|
||||
* @nr Number of failed data and parity blocks to recover.
|
||||
* @ir[] Vector of @nr indexes of the failed data and parity blocks.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* The first parity is represented with value @nd, the second with value
|
||||
* @nd + 1, just like positions in the @v vector.
|
||||
* @nd Number of data blocks.
|
||||
* @np Number of parity blocks.
|
||||
* @size Size of the blocks pointed by @v. It must be a multiplier of 64.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
* Each block has @size bytes.
|
||||
*/
|
||||
void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v);
|
||||
|
||||
/**
|
||||
* Recovers failures in data blocks only.
|
||||
*
|
||||
* This function recovers all the data blocks marked as bad in the @id vector.
|
||||
* The parity blocks are not modified.
|
||||
*
|
||||
* @nr Number of failed data blocks to recover.
|
||||
* @id[] Vector of @nr indexes of the data blocks to recover.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* @ip[] Vector of @nr indexes of the parity blocks to use for recovering.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* @nd Number of data blocks.
|
||||
* @size Size of the blocks pointed by @v. It must be a multiplier of 64.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @ip[@nr - 1] + 1) elements. The starting elements are the
|
||||
* blocks for data, following with the parity blocks.
|
||||
* Each blocks has @size bytes.
|
||||
*/
|
||||
void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v);
|
||||
|
||||
/**
|
||||
* Check the provided failed blocks combination.
|
||||
*
|
||||
* This function checks if the specified failed blocks combination satisfies
|
||||
* the redundancy information. A combination is assumed matching, if the
|
||||
* remaining valid parity is matching the expected value after recovering.
|
||||
*
|
||||
* The number of failed blocks @nr must be strictly less than the number of
|
||||
* parities @np, because you need one more parity to validate the recovering.
|
||||
*
|
||||
* No data or parity blocks are modified.
|
||||
*
|
||||
* @nr Number of failed data and parity blocks.
|
||||
* @ir[] Vector of @nr indexes of the failed data and parity blocks.
|
||||
* The indexes start from 0. They must be in order.
|
||||
* The first parity is represented with value @nd, the second with value
|
||||
* @nd + 1, just like positions in the @v vector.
|
||||
* @nd Number of data blocks.
|
||||
* @np Number of parity blocks.
|
||||
* @size Size of the blocks pointed by @v. It must be a multiplier of 64.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
* Each block has @size bytes.
|
||||
* @return 0 if the check is satisfied. -1 otherwise.
|
||||
*/
|
||||
int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v);
|
||||
|
||||
/**
|
||||
* Scan for failed blocks.
|
||||
*
|
||||
* This function identifies the failed data and parity blocks using the
|
||||
* available redundancy.
|
||||
*
|
||||
* It uses a brute force method, and then the call can be expansive.
|
||||
* The expected execution time is proportional at the binomial coefficient
|
||||
* @np + @nd choose @np - 1, usually written as:
|
||||
*
|
||||
* ( @np + @nd )
|
||||
* ( )
|
||||
* ( @np - 1 )
|
||||
*
|
||||
* No data or parity blocks are modified.
|
||||
*
|
||||
* The failed block indexes are returned in the @ir vector.
|
||||
* It must have space for at least @np - 1 values.
|
||||
*
|
||||
* The returned @ir vector can then be used in a raid_rec() call to recover
|
||||
* the failed data and parity blocks.
|
||||
*
|
||||
* @ir[] Vector filled with the indexes of the failed data and parity blocks.
|
||||
* The indexes start from 0 and they are in order.
|
||||
* The first parity is represented with value @nd, the second with value
|
||||
* @nd + 1, just like positions in the @v vector.
|
||||
* @nd Number of data blocks.
|
||||
* @np Number of parity blocks.
|
||||
* @size Size of the blocks pointed by @v. It must be a multiplier of 64.
|
||||
* @v Vector of pointers to the blocks of data and parity.
|
||||
* It has (@nd + @np) elements. The starting elements are the blocks
|
||||
* for data, following with the parity blocks.
|
||||
* Each block has @size bytes.
|
||||
* @return Number of block indexes returned in the @ir vector.
|
||||
* 0 if no error is detected.
|
||||
* -1 if it's not possible to identify the failed disks.
|
||||
*/
|
||||
int raid_scan(int *ir, int nd, int np, size_t size, void **v);
|
||||
|
||||
#endif
|
||||
|
14696
raid/tables.c
Normal file
14696
raid/tables.c
Normal file
File diff suppressed because it is too large
Load Diff
145
raid/tag.c
Normal file
145
raid/tag.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
static struct raid_func {
|
||||
const char *name;
|
||||
void (*p)();
|
||||
} RAID_FUNC[] = {
|
||||
{ "int8", raid_gen3_int8 },
|
||||
{ "int8", raid_gen4_int8 },
|
||||
{ "int8", raid_gen5_int8 },
|
||||
{ "int8", raid_gen6_int8 },
|
||||
{ "int32", raid_gen1_int32 },
|
||||
{ "int64", raid_gen1_int64 },
|
||||
{ "int32", raid_gen2_int32 },
|
||||
{ "int64", raid_gen2_int64 },
|
||||
{ "int32", raid_genz_int32 },
|
||||
{ "int64", raid_genz_int64 },
|
||||
{ "int8", raid_rec1_int8 },
|
||||
{ "int8", raid_rec2_int8 },
|
||||
{ "int8", raid_recX_int8 },
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
{ "sse2", raid_gen1_sse2 },
|
||||
{ "sse2", raid_gen2_sse2 },
|
||||
{ "sse2", raid_genz_sse2 },
|
||||
#endif
|
||||
#ifdef CONFIG_SSSE3
|
||||
{ "ssse3", raid_gen3_ssse3 },
|
||||
{ "ssse3", raid_gen4_ssse3 },
|
||||
{ "ssse3", raid_gen5_ssse3 },
|
||||
{ "ssse3", raid_gen6_ssse3 },
|
||||
{ "ssse3", raid_rec1_ssse3 },
|
||||
{ "ssse3", raid_rec2_ssse3 },
|
||||
{ "ssse3", raid_recX_ssse3 },
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
{ "avx2", raid_gen1_avx2 },
|
||||
{ "avx2", raid_gen2_avx2 },
|
||||
{ "avx2", raid_rec1_avx2 },
|
||||
{ "avx2", raid_rec2_avx2 },
|
||||
{ "avx2", raid_recX_avx2 },
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_SSE2
|
||||
{ "sse2e", raid_gen2_sse2ext },
|
||||
{ "sse2e", raid_genz_sse2ext },
|
||||
#endif
|
||||
#ifdef CONFIG_SSSE3
|
||||
{ "ssse3e", raid_gen3_ssse3ext },
|
||||
{ "ssse3e", raid_gen4_ssse3ext },
|
||||
{ "ssse3e", raid_gen5_ssse3ext },
|
||||
{ "ssse3e", raid_gen6_ssse3ext },
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
{ "avx2e", raid_gen3_avx2ext },
|
||||
{ "avx2e", raid_genz_avx2ext },
|
||||
{ "avx2e", raid_gen4_avx2ext },
|
||||
{ "avx2e", raid_gen5_avx2ext },
|
||||
{ "avx2e", raid_gen6_avx2ext },
|
||||
#endif
|
||||
#endif
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static const char *raid_tag(void (*func)())
|
||||
{
|
||||
struct raid_func *i = RAID_FUNC;
|
||||
|
||||
while (i->name != 0) {
|
||||
if (i->p == func)
|
||||
return i->name;
|
||||
++i;
|
||||
}
|
||||
|
||||
/* LCOV_EXCL_START */
|
||||
return "unknown";
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
const char *raid_gen1_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[0]);
|
||||
}
|
||||
|
||||
const char *raid_gen2_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[1]);
|
||||
}
|
||||
|
||||
const char *raid_genz_tag(void)
|
||||
{
|
||||
return raid_tag(raid_genz_ptr);
|
||||
}
|
||||
|
||||
const char *raid_gen3_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[2]);
|
||||
}
|
||||
|
||||
const char *raid_gen4_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[3]);
|
||||
}
|
||||
|
||||
const char *raid_gen5_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[4]);
|
||||
}
|
||||
|
||||
const char *raid_gen6_tag(void)
|
||||
{
|
||||
return raid_tag(raid_gen_ptr[5]);
|
||||
}
|
||||
|
||||
const char *raid_rec1_tag(void)
|
||||
{
|
||||
return raid_tag(raid_rec_ptr[0]);
|
||||
}
|
||||
|
||||
const char *raid_rec2_tag(void)
|
||||
{
|
||||
return raid_tag(raid_rec_ptr[1]);
|
||||
}
|
||||
|
||||
const char *raid_recX_tag(void)
|
||||
{
|
||||
return raid_tag(raid_rec_ptr[2]);
|
||||
}
|
||||
|
452
raid/test.c
Normal file
452
raid/test.c
Normal file
@ -0,0 +1,452 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "cpu.h"
|
||||
#include "combo.h"
|
||||
#include "memory.h"
|
||||
|
||||
/**
|
||||
* Binomial coefficient of n over r.
|
||||
*/
|
||||
static int ibc(int n, int r)
|
||||
{
|
||||
if (r == 0 || n == r)
|
||||
return 1;
|
||||
else
|
||||
return ibc(n - 1, r - 1) + ibc(n - 1, r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Power n ^ r;
|
||||
*/
|
||||
static int ipow(int n, int r)
|
||||
{
|
||||
int v = 1;
|
||||
|
||||
while (r) {
|
||||
v *= n;
|
||||
--r;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int raid_test_combo(void)
|
||||
{
|
||||
int r;
|
||||
int count;
|
||||
int p[RAID_PARITY_MAX];
|
||||
|
||||
for (r = 1; r <= RAID_PARITY_MAX; ++r) {
|
||||
/* count combination (r of RAID_PARITY_MAX) elements */
|
||||
count = 0;
|
||||
combination_first(r, RAID_PARITY_MAX, p);
|
||||
|
||||
do {
|
||||
++count;
|
||||
} while (combination_next(r, RAID_PARITY_MAX, p));
|
||||
|
||||
if (count != ibc(RAID_PARITY_MAX, r)) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (r = 1; r <= RAID_PARITY_MAX; ++r) {
|
||||
/* count permutation (r of RAID_PARITY_MAX) elements */
|
||||
count = 0;
|
||||
permutation_first(r, RAID_PARITY_MAX, p);
|
||||
|
||||
do {
|
||||
++count;
|
||||
} while (permutation_next(r, RAID_PARITY_MAX, p));
|
||||
|
||||
if (count != ipow(RAID_PARITY_MAX, r)) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int raid_test_insert(void)
|
||||
{
|
||||
int p[RAID_PARITY_MAX];
|
||||
int r;
|
||||
|
||||
for (r = 1; r <= RAID_PARITY_MAX; ++r) {
|
||||
permutation_first(r, RAID_PARITY_MAX, p);
|
||||
do {
|
||||
int i[RAID_PARITY_MAX];
|
||||
int j;
|
||||
|
||||
/* insert in order */
|
||||
for (j = 0; j < r; ++j)
|
||||
raid_insert(j, i, p[j]);
|
||||
|
||||
/* check order */
|
||||
for (j = 1; j < r; ++j) {
|
||||
if (i[j - 1] > i[j]) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
} while (permutation_next(r, RAID_PARITY_MAX, p));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int raid_test_sort(void)
|
||||
{
|
||||
int p[RAID_PARITY_MAX];
|
||||
int r;
|
||||
|
||||
for (r = 1; r <= RAID_PARITY_MAX; ++r) {
|
||||
permutation_first(r, RAID_PARITY_MAX, p);
|
||||
do {
|
||||
int i[RAID_PARITY_MAX];
|
||||
int j;
|
||||
|
||||
/* make a copy */
|
||||
for (j = 0; j < r; ++j)
|
||||
i[j] = p[j];
|
||||
|
||||
raid_sort(r, i);
|
||||
|
||||
/* check order */
|
||||
for (j = 1; j < r; ++j) {
|
||||
if (i[j - 1] > i[j]) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
} while (permutation_next(r, RAID_PARITY_MAX, p));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int raid_test_rec(int mode, int nd, size_t size)
|
||||
{
|
||||
void (*f[RAID_PARITY_MAX][4])(
|
||||
int nr, int *id, int *ip, int nd, size_t size, void **vbuf);
|
||||
void *v_alloc;
|
||||
void **v;
|
||||
void **data;
|
||||
void **parity;
|
||||
void **test;
|
||||
void *data_save[RAID_PARITY_MAX];
|
||||
void *parity_save[RAID_PARITY_MAX];
|
||||
void *waste;
|
||||
int nv;
|
||||
int id[RAID_PARITY_MAX];
|
||||
int ip[RAID_PARITY_MAX];
|
||||
int i;
|
||||
int j;
|
||||
int nr;
|
||||
int nf[RAID_PARITY_MAX];
|
||||
int np;
|
||||
|
||||
raid_mode(mode);
|
||||
if (mode == RAID_MODE_CAUCHY)
|
||||
np = RAID_PARITY_MAX;
|
||||
else
|
||||
np = 3;
|
||||
|
||||
nv = nd + np * 2 + 2;
|
||||
|
||||
v = raid_malloc_vector(nd, nv, size, &v_alloc);
|
||||
if (!v) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
data = v;
|
||||
parity = v + nd;
|
||||
test = v + nd + np;
|
||||
|
||||
for (i = 0; i < np; ++i)
|
||||
parity_save[i] = parity[i];
|
||||
|
||||
memset(v[nv - 2], 0, size);
|
||||
raid_zero(v[nv - 2]);
|
||||
|
||||
waste = v[nv - 1];
|
||||
|
||||
/* fill with pseudo-random data with the arbitrary seed "1" */
|
||||
raid_mrand_vector(1, nd, size, v);
|
||||
|
||||
/* setup recov functions */
|
||||
for (i = 0; i < np; ++i) {
|
||||
nf[i] = 0;
|
||||
if (i == 0) {
|
||||
f[i][nf[i]++] = raid_rec1_int8;
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3())
|
||||
f[i][nf[i]++] = raid_rec1_ssse3;
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2())
|
||||
f[i][nf[i]++] = raid_rec1_avx2;
|
||||
#endif
|
||||
#endif
|
||||
} else if (i == 1) {
|
||||
f[i][nf[i]++] = raid_rec2_int8;
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3())
|
||||
f[i][nf[i]++] = raid_rec2_ssse3;
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2())
|
||||
f[i][nf[i]++] = raid_rec2_avx2;
|
||||
#endif
|
||||
#endif
|
||||
} else {
|
||||
f[i][nf[i]++] = raid_recX_int8;
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3())
|
||||
f[i][nf[i]++] = raid_recX_ssse3;
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2())
|
||||
f[i][nf[i]++] = raid_recX_avx2;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* compute the parity */
|
||||
raid_gen_ref(nd, np, size, v);
|
||||
|
||||
/* set all the parity to the waste v */
|
||||
for (i = 0; i < np; ++i)
|
||||
parity[i] = waste;
|
||||
|
||||
/* all parity levels */
|
||||
for (nr = 1; nr <= np; ++nr) {
|
||||
/* all combinations (nr of nd) disks */
|
||||
combination_first(nr, nd, id);
|
||||
do {
|
||||
/* all combinations (nr of np) parities */
|
||||
combination_first(nr, np, ip);
|
||||
do {
|
||||
/* for each recover function */
|
||||
for (j = 0; j < nf[nr - 1]; ++j) {
|
||||
/* set */
|
||||
for (i = 0; i < nr; ++i) {
|
||||
/* remove the missing data */
|
||||
data_save[i] = data[id[i]];
|
||||
data[id[i]] = test[i];
|
||||
/* set the parity to use */
|
||||
parity[ip[i]] = parity_save[ip[i]];
|
||||
}
|
||||
|
||||
/* recover */
|
||||
f[nr - 1][j](nr, id, ip, nd, size, v);
|
||||
|
||||
/* check */
|
||||
for (i = 0; i < nr; ++i) {
|
||||
if (memcmp(test[i], data_save[i], size) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/* restore */
|
||||
for (i = 0; i < nr; ++i) {
|
||||
/* restore the data */
|
||||
data[id[i]] = data_save[i];
|
||||
/* restore the parity */
|
||||
parity[ip[i]] = waste;
|
||||
}
|
||||
}
|
||||
} while (combination_next(nr, np, ip));
|
||||
} while (combination_next(nr, nd, id));
|
||||
}
|
||||
|
||||
free(v_alloc);
|
||||
free(v);
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
free(v_alloc);
|
||||
free(v);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
int raid_test_par(int mode, int nd, size_t size)
|
||||
{
|
||||
void (*f[64])(int nd, size_t size, void **vbuf);
|
||||
void *v_alloc;
|
||||
void **v;
|
||||
int nv;
|
||||
int i, j;
|
||||
int nf;
|
||||
int np;
|
||||
|
||||
raid_mode(mode);
|
||||
if (mode == RAID_MODE_CAUCHY)
|
||||
np = RAID_PARITY_MAX;
|
||||
else
|
||||
np = 3;
|
||||
|
||||
nv = nd + np * 2;
|
||||
|
||||
v = raid_malloc_vector(nd, nv, size, &v_alloc);
|
||||
if (!v) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* check memory */
|
||||
if (raid_mtest_vector(nv, size, v) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* fill with pseudo-random data with the arbitrary seed "2" */
|
||||
raid_mrand_vector(2, nv, size, v);
|
||||
|
||||
/* compute the parity */
|
||||
raid_gen_ref(nd, np, size, v);
|
||||
|
||||
/* copy in back buffers */
|
||||
for (i = 0; i < np; ++i)
|
||||
memcpy(v[nd + np + i], v[nd + i], size);
|
||||
|
||||
/* load all the available functions */
|
||||
nf = 0;
|
||||
|
||||
f[nf++] = raid_gen1_int32;
|
||||
f[nf++] = raid_gen1_int64;
|
||||
f[nf++] = raid_gen2_int32;
|
||||
f[nf++] = raid_gen2_int64;
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
f[nf++] = raid_gen1_sse2;
|
||||
f[nf++] = raid_gen2_sse2;
|
||||
#ifdef CONFIG_X86_64
|
||||
f[nf++] = raid_gen2_sse2ext;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
f[nf++] = raid_gen1_avx2;
|
||||
f[nf++] = raid_gen2_avx2;
|
||||
}
|
||||
#endif
|
||||
#endif /* CONFIG_X86 */
|
||||
|
||||
if (mode == RAID_MODE_CAUCHY) {
|
||||
f[nf++] = raid_gen3_int8;
|
||||
f[nf++] = raid_gen4_int8;
|
||||
f[nf++] = raid_gen5_int8;
|
||||
f[nf++] = raid_gen6_int8;
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
f[nf++] = raid_gen3_ssse3;
|
||||
f[nf++] = raid_gen4_ssse3;
|
||||
f[nf++] = raid_gen5_ssse3;
|
||||
f[nf++] = raid_gen6_ssse3;
|
||||
#ifdef CONFIG_X86_64
|
||||
f[nf++] = raid_gen3_ssse3ext;
|
||||
f[nf++] = raid_gen4_ssse3ext;
|
||||
f[nf++] = raid_gen5_ssse3ext;
|
||||
f[nf++] = raid_gen6_ssse3ext;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AVX2
|
||||
#ifdef CONFIG_X86_64
|
||||
if (raid_cpu_has_avx2()) {
|
||||
f[nf++] = raid_gen3_avx2ext;
|
||||
f[nf++] = raid_gen4_avx2ext;
|
||||
f[nf++] = raid_gen5_avx2ext;
|
||||
f[nf++] = raid_gen6_avx2ext;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* CONFIG_X86 */
|
||||
} else {
|
||||
f[nf++] = raid_genz_int32;
|
||||
f[nf++] = raid_genz_int64;
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
f[nf++] = raid_genz_sse2;
|
||||
#ifdef CONFIG_X86_64
|
||||
f[nf++] = raid_genz_sse2ext;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AVX2
|
||||
#ifdef CONFIG_X86_64
|
||||
if (raid_cpu_has_avx2())
|
||||
f[nf++] = raid_genz_avx2ext;
|
||||
#endif
|
||||
#endif
|
||||
#endif /* CONFIG_X86 */
|
||||
}
|
||||
|
||||
/* check all the functions */
|
||||
for (j = 0; j < nf; ++j) {
|
||||
/* compute parity */
|
||||
f[j](nd, size, v);
|
||||
|
||||
/* check it */
|
||||
for (i = 0; i < np; ++i) {
|
||||
if (memcmp(v[nd + np + i], v[nd + i], size) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(v_alloc);
|
||||
free(v);
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
free(v_alloc);
|
||||
free(v);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
68
raid/test.h
Normal file
68
raid/test.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __RAID_TEST_H
|
||||
#define __RAID_TEST_H
|
||||
|
||||
/**
|
||||
* Tests insertion function.
|
||||
*
|
||||
* Test raid_insert() with all the possible combinations of elements to insert.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int raid_test_insert(void);
|
||||
|
||||
/**
|
||||
* Tests sorting function.
|
||||
*
|
||||
* Test raid_sort() with all the possible combinations of elements to sort.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int raid_test_sort(void);
|
||||
|
||||
/**
|
||||
* Tests combination functions.
|
||||
*
|
||||
* Tests combination_first() and combination_next() for all the parity levels.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int raid_test_combo(void);
|
||||
|
||||
/**
|
||||
* Tests recovering functions.
|
||||
*
|
||||
* All the recovering functions are tested with all the combinations
|
||||
* of failing disks and recovering parities.
|
||||
*
|
||||
* Take care that the test time grows exponentially with the number of disks.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int raid_test_rec(unsigned mode, int nd, size_t size);
|
||||
|
||||
/**
|
||||
* Tests parity generation functions.
|
||||
*
|
||||
* All the parity generation functions are tested with the specified
|
||||
* number of disks.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
int raid_test_par(unsigned mode, int nd, size_t size);
|
||||
|
||||
#endif
|
||||
|
99
raid/test/Makefile
Normal file
99
raid/test/Makefile
Normal file
@ -0,0 +1,99 @@
|
||||
#
|
||||
# Test programs for the RAID library
|
||||
#
|
||||
# selftest - Runs the same selftest and speedtest executed at the module startup.
|
||||
# fulltest - Runs a more extensive test that checks all the built-in functions.
|
||||
# speetest - Runs a more complete speed test.
|
||||
# invtest - Runs an extensive matrix inversion test of all the 377.342.351.231
|
||||
# possible square submatrices of the Cauchy matrix used.
|
||||
# covtest - Runs a coverage test.
|
||||
# sdecovtest - Runs a coverage test with the sde emulator.
|
||||
#
|
||||
|
||||
MACHINE = $(shell uname -m)
|
||||
ifeq ($(MACHINE),i686)
|
||||
SDE = sde
|
||||
else
|
||||
SDE = sde64
|
||||
endif
|
||||
CC = gcc
|
||||
LD = ld
|
||||
CFLAGS = -I.. -Wall -Wextra -g
|
||||
ifeq ($(COVERAGE),)
|
||||
CFLAGS += -O2
|
||||
else
|
||||
CFLAGS += -O0 --coverage -DCOVERAGE=1 -DNDEBUG=1
|
||||
endif
|
||||
OBJS = raid.o check.o int.o intz.o x86.o x86z.o tables.o memory.o test.o helper.o module.o tag.o
|
||||
|
||||
%.o: ../%.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
all: fulltest speedtest selftest invtest
|
||||
|
||||
fulltest: $(OBJS) fulltest.o
|
||||
$(CC) $(CFLAGS) -o fulltest $^
|
||||
|
||||
speedtest: $(OBJS) speedtest.o
|
||||
$(CC) $(CFLAGS) -o speedtest $^
|
||||
|
||||
selftest: $(OBJS) selftest.o
|
||||
$(CC) $(CFLAGS) -o selftest $^
|
||||
|
||||
invtest: $(OBJS) invtest.o
|
||||
$(CC) $(CFLAGS) -o invtest $^
|
||||
|
||||
mktables: mktables.o
|
||||
$(CC) $(CFLAGS) -o mktables $^
|
||||
|
||||
tables.c: mktables
|
||||
./mktables > tables.c
|
||||
|
||||
# Use this target to run a coverage test using lcov
|
||||
covtest:
|
||||
$(MAKE) clean
|
||||
$(MAKE) lcov_reset
|
||||
$(MAKE) COVERAGE=1 all
|
||||
./fulltest
|
||||
./selftest
|
||||
./speedtest
|
||||
$(MAKE) lcov_capture
|
||||
$(MAKE) lcov_html
|
||||
|
||||
# Use this target to run a coverage test using lcov and the sde
|
||||
sdecovtest:
|
||||
$(MAKE) clean
|
||||
$(MAKE) lcov_reset
|
||||
$(MAKE) COVERAGE=1 all
|
||||
$(SDE) -p4p -- ./fulltest
|
||||
$(SDE) -mrm -- ./fulltest
|
||||
$(SDE) -nhm -- ./fulltest
|
||||
$(SDE) -hsw -- ./fulltest
|
||||
$(SDE) -p4p -- ./selftest
|
||||
$(SDE) -mrm -- ./selftest
|
||||
$(SDE) -nhm -- ./selftest
|
||||
$(SDE) -hsw -- ./selftest
|
||||
$(SDE) -hsw -- ./speedtest
|
||||
$(MAKE) lcov_capture
|
||||
$(MAKE) lcov_html
|
||||
|
||||
lcov_reset:
|
||||
lcov --directory . -z
|
||||
rm -f lcov.info
|
||||
|
||||
lcov_capture:
|
||||
lcov --directory . --capture --rc lcov_branch_coverage=1 -o lcov.info
|
||||
|
||||
lcov_html:
|
||||
rm -rf coverage
|
||||
mkdir coverage
|
||||
genhtml --branch-coverage -o coverage lcov.info
|
||||
|
||||
clean:
|
||||
rm -f *.o mktables tables.c
|
||||
rm -f *.gcda *.gcno lcov.info
|
||||
rm -rf coverage
|
||||
|
||||
distclean: clean
|
||||
rm -f fulltest speedtest selftest invtest
|
||||
|
124
raid/test/fulltest.c
Normal file
124
raid/test/fulltest.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/* Full sanity test for the RAID library */
|
||||
|
||||
#include "internal.h"
|
||||
#include "test.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Size of the blocks to test.
|
||||
*/
|
||||
#define TEST_SIZE 256
|
||||
|
||||
/**
|
||||
* Number of disks in the long parity test.
|
||||
*/
|
||||
#ifdef COVERAGE
|
||||
#define TEST_COUNT 10
|
||||
#else
|
||||
#define TEST_COUNT 32
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Full sanity test for the RAID Cauchy library\n\n");
|
||||
|
||||
raid_init();
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
if (raid_cpu_has_sse2())
|
||||
printf("Including x86 SSE2 functions\n");
|
||||
if (raid_cpu_has_ssse3())
|
||||
printf("Including x86 SSSE3 functions\n");
|
||||
if (raid_cpu_has_avx2())
|
||||
printf("Including x86 AVX2 functions\n");
|
||||
#endif
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("Including x64 extended SSE register set\n");
|
||||
#endif
|
||||
|
||||
printf("\nPlease wait about 60 seconds...\n\n");
|
||||
|
||||
printf("Test sorting...\n");
|
||||
if (raid_test_sort() != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
printf("Test insertion...\n");
|
||||
if (raid_test_insert() != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
printf("Test combinations/permutations...\n");
|
||||
if (raid_test_combo() != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
printf("Test Cauchy parity generation with %u data disks...\n", RAID_DATA_MAX);
|
||||
if (raid_test_par(RAID_MODE_CAUCHY, RAID_DATA_MAX, TEST_SIZE) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
printf("Test Cauchy parity generation with 1 data disk...\n");
|
||||
if (raid_test_par(RAID_MODE_CAUCHY, 1, TEST_SIZE) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
printf("Test Cauchy recovering with all combinations of %u data and 6 parity blocks...\n", TEST_COUNT);
|
||||
if (raid_test_rec(RAID_MODE_CAUCHY, TEST_COUNT, TEST_SIZE) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
printf("Test Vandermonde parity generation with %u data disks...\n", RAID_DATA_MAX);
|
||||
if (raid_test_par(RAID_MODE_VANDERMONDE, RAID_DATA_MAX, TEST_SIZE) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
printf("Test Vandermonde recovering with all combinations of %u data and 3 parity blocks...\n", TEST_COUNT);
|
||||
if (raid_test_rec(RAID_MODE_VANDERMONDE, TEST_COUNT, TEST_SIZE) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
|
||||
printf("OK\n");
|
||||
return 0;
|
||||
|
||||
bail:
|
||||
/* LCOV_EXCL_START */
|
||||
printf("FAILED!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
176
raid/test/invtest.c
Normal file
176
raid/test/invtest.c
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/* Matrix inversion test for the RAID library */
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include "combo.h"
|
||||
#include "gf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/**
|
||||
* Like raid_invert() but optimized to only check if the matrix is
|
||||
* invertible.
|
||||
*/
|
||||
static __always_inline int raid_invert_fast(uint8_t *M, int n)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
/* for each element in the diagonal */
|
||||
for (k = 0; k < n; ++k) {
|
||||
uint8_t f;
|
||||
|
||||
/* the diagonal element cannot be 0 because */
|
||||
/* we are inverting matrices with all the square */
|
||||
/* submatrices not singular */
|
||||
if (M[k * n + k] == 0)
|
||||
return -1;
|
||||
|
||||
/* make the diagonal element to be 1 */
|
||||
f = inv(M[k * n + k]);
|
||||
for (j = 0; j < n; ++j)
|
||||
M[k * n + j] = mul(f, M[k * n + j]);
|
||||
|
||||
/* make all the elements over and under the diagonal */
|
||||
/* to be zero */
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (i == k)
|
||||
continue;
|
||||
f = M[i * n + k];
|
||||
for (j = 0; j < n; ++j)
|
||||
M[i * n + j] ^= mul(f, M[k * n + j]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_REFRESH (4 * 1024 * 1024)
|
||||
|
||||
/**
|
||||
* Precomputed number of square submatrices of size nr.
|
||||
*
|
||||
* It's bc(np,nr) * bc(nd,nr)
|
||||
*
|
||||
* With 1<=nr<=6 and bc(n, r) == binomial coefficient of (n over r).
|
||||
*/
|
||||
long long EXPECTED[RAID_PARITY_MAX] = {
|
||||
1506LL,
|
||||
470625LL,
|
||||
52082500LL,
|
||||
2421836250LL,
|
||||
47855484300LL,
|
||||
327012476050LL
|
||||
};
|
||||
|
||||
static __always_inline int test_sub_matrix(int nr, long long *total)
|
||||
{
|
||||
uint8_t M[RAID_PARITY_MAX * RAID_PARITY_MAX];
|
||||
int np = RAID_PARITY_MAX;
|
||||
int nd = RAID_DATA_MAX;
|
||||
int ip[RAID_PARITY_MAX];
|
||||
int id[RAID_DATA_MAX];
|
||||
long long count;
|
||||
long long expected;
|
||||
|
||||
printf("\n%ux%u\n", nr, nr);
|
||||
|
||||
count = 0;
|
||||
expected = EXPECTED[nr - 1];
|
||||
|
||||
/* all combinations (nr of nd) disks */
|
||||
combination_first(nr, nd, id);
|
||||
do {
|
||||
/* all combinations (nr of np) parities */
|
||||
combination_first(nr, np, ip);
|
||||
do {
|
||||
int i, j;
|
||||
|
||||
/* setup the submatrix */
|
||||
for (i = 0; i < nr; ++i)
|
||||
for (j = 0; j < nr; ++j)
|
||||
M[i * nr + j] = gfgen[ip[i]][id[j]];
|
||||
|
||||
/* invert */
|
||||
if (raid_invert_fast(M, nr) != 0)
|
||||
return -1;
|
||||
|
||||
if (++count % TEST_REFRESH == 0) {
|
||||
printf("\r%.3f %%", count * (double)100 / expected);
|
||||
fflush(stdout);
|
||||
}
|
||||
} while (combination_next(nr, np, ip));
|
||||
} while (combination_next(nr, nd, id));
|
||||
|
||||
if (count != expected)
|
||||
return -1;
|
||||
|
||||
printf("\rTested %" PRIi64 " matrix\n", count);
|
||||
|
||||
*total += count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_all_sub_matrix(void)
|
||||
{
|
||||
long long total;
|
||||
|
||||
printf("Invert all square submatrices of the %dx%d Cauchy matrix\n",
|
||||
RAID_PARITY_MAX, RAID_DATA_MAX);
|
||||
|
||||
printf("\nPlease wait about 2 days...\n");
|
||||
|
||||
total = 0;
|
||||
|
||||
/* force inlining of everything */
|
||||
if (test_sub_matrix(1, &total) != 0)
|
||||
return -1;
|
||||
if (test_sub_matrix(2, &total) != 0)
|
||||
return -1;
|
||||
if (test_sub_matrix(3, &total) != 0)
|
||||
return -1;
|
||||
if (test_sub_matrix(4, &total) != 0)
|
||||
return -1;
|
||||
if (test_sub_matrix(5, &total) != 0)
|
||||
return -1;
|
||||
if (test_sub_matrix(6, &total) != 0)
|
||||
return -1;
|
||||
|
||||
printf("\nTested in total %" PRIi64 " matrix\n", total);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Matrix inversion test for the RAID Cauchy library\n\n");
|
||||
|
||||
/* required to set the gfgen table */
|
||||
raid_init();
|
||||
|
||||
if (test_all_sub_matrix() != 0) {
|
||||
printf("FAILED!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
printf("OK\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
40
raid/test/selftest.c
Normal file
40
raid/test/selftest.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/* Self sanity test for the RAID library */
|
||||
|
||||
#include "internal.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Self sanity test for the RAID Cauchy library\n\n");
|
||||
|
||||
raid_init();
|
||||
|
||||
printf("Self test...\n");
|
||||
if (raid_selftest() != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
printf("FAILED!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
printf("OK\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
851
raid/test/speedtest.c
Normal file
851
raid/test/speedtest.c
Normal file
@ -0,0 +1,851 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
/* Speed test for the RAID library */
|
||||
|
||||
#include "internal.h"
|
||||
#include "memory.h"
|
||||
#include "cpu.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Size of the blocks to test.
|
||||
*/
|
||||
#define TEST_SIZE (256 * 1024)
|
||||
|
||||
/*
|
||||
* Number of data blocks to test.
|
||||
*/
|
||||
#define TEST_COUNT (8)
|
||||
|
||||
/**
|
||||
* Differential us of two timeval.
|
||||
*/
|
||||
static int64_t diffgettimeofday(struct timeval *start, struct timeval *stop)
|
||||
{
|
||||
int64_t d;
|
||||
|
||||
d = 1000000LL * (stop->tv_sec - start->tv_sec);
|
||||
d += stop->tv_usec - start->tv_usec;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test period.
|
||||
*/
|
||||
#ifdef COVERAGE
|
||||
#define TEST_PERIOD 100000LL
|
||||
#define TEST_DELTA 1
|
||||
#else
|
||||
#define TEST_PERIOD 1000000LL
|
||||
#define TEST_DELTA 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Start time measurement.
|
||||
*/
|
||||
#define SPEED_START \
|
||||
count = 0; \
|
||||
gettimeofday(&start, 0); \
|
||||
do { \
|
||||
for (i = 0; i < delta; ++i)
|
||||
|
||||
/**
|
||||
* Stop time measurement.
|
||||
*/
|
||||
#define SPEED_STOP \
|
||||
count += delta; \
|
||||
gettimeofday(&stop, 0); \
|
||||
} while (diffgettimeofday(&start, &stop) < TEST_PERIOD); \
|
||||
ds = size * (int64_t)count * nd; \
|
||||
dt = diffgettimeofday(&start, &stop);
|
||||
|
||||
void speed(void)
|
||||
{
|
||||
struct timeval start;
|
||||
struct timeval stop;
|
||||
int64_t ds;
|
||||
int64_t dt;
|
||||
int i, j;
|
||||
int id[RAID_PARITY_MAX];
|
||||
int ip[RAID_PARITY_MAX];
|
||||
int count;
|
||||
int delta = TEST_DELTA;
|
||||
int size = TEST_SIZE;
|
||||
int nd = TEST_COUNT;
|
||||
int nv;
|
||||
void *v_alloc;
|
||||
void **v;
|
||||
|
||||
nv = nd + RAID_PARITY_MAX + 1;
|
||||
|
||||
v = raid_malloc_vector(nd, nv, size, &v_alloc);
|
||||
|
||||
/* initialize disks with fixed data */
|
||||
for (i = 0; i < nd; ++i)
|
||||
memset(v[i], i, size);
|
||||
|
||||
/* zero buffer */
|
||||
memset(v[nd + RAID_PARITY_MAX], 0, size);
|
||||
raid_zero(v[nd + RAID_PARITY_MAX]);
|
||||
|
||||
/* basic disks and parity mapping */
|
||||
for (i = 0; i < RAID_PARITY_MAX; ++i) {
|
||||
id[i] = i;
|
||||
ip[i] = i;
|
||||
}
|
||||
|
||||
printf("Speed test using %u data buffers of %u bytes, for a total of %u KiB.\n", nd, size, nd * size / 1024);
|
||||
printf("Memory blocks have a displacement of %u bytes to improve cache performance.\n", RAID_MALLOC_DISPLACEMENT);
|
||||
printf("The reported values are the aggregate bandwidth of all data blocks in MiB/s,\n");
|
||||
printf("not counting parity blocks.\n");
|
||||
printf("\n");
|
||||
|
||||
printf("Memory write speed using the C memset() function:\n");
|
||||
printf("%8s", "memset");
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
memset(v[j], j, size);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
/* RAID table */
|
||||
printf("RAID functions used for computing the parity:\n");
|
||||
printf("%8s", "");
|
||||
printf("%8s", "best");
|
||||
printf("%8s", "int8");
|
||||
printf("%8s", "int32");
|
||||
printf("%8s", "int64");
|
||||
#ifdef CONFIG_X86
|
||||
printf("%8s", "sse2");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "sse2e");
|
||||
#endif
|
||||
printf("%8s", "ssse3");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "ssse3e");
|
||||
#endif
|
||||
printf("%8s", "avx2");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "avx2e");
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN1 */
|
||||
printf("%8s", "gen1");
|
||||
printf("%8s", raid_gen1_tag());
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
SPEED_START {
|
||||
raid_gen1_int32(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen1_int64(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
SPEED_START {
|
||||
raid_gen1_sse2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
printf("%8s", "");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen1_avx2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN2 */
|
||||
printf("%8s", "gen2");
|
||||
printf("%8s", raid_gen2_tag());
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
SPEED_START {
|
||||
raid_gen2_int32(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen2_int64(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
SPEED_START {
|
||||
raid_gen2_sse2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen2_sse2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen2_avx2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GENz */
|
||||
printf("%8s", "genz");
|
||||
printf("%8s", raid_genz_tag());
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
SPEED_START {
|
||||
raid_genz_int32(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_genz_int64(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
SPEED_START {
|
||||
raid_genz_sse2(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_genz_sse2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_genz_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN3 */
|
||||
printf("%8s", "gen3");
|
||||
printf("%8s", raid_gen3_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen3_int8(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
if (raid_cpu_has_sse2()) {
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
raid_gen3_ssse3(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen3_ssse3ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen3_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN4 */
|
||||
printf("%8s", "gen4");
|
||||
printf("%8s", raid_gen4_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen4_int8(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
raid_gen4_ssse3(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen4_ssse3ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen4_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN5 */
|
||||
printf("%8s", "gen5");
|
||||
printf("%8s", raid_gen5_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen5_int8(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
raid_gen5_ssse3(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen5_ssse3ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen5_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
/* GEN6 */
|
||||
printf("%8s", "gen6");
|
||||
printf("%8s", raid_gen6_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
raid_gen6_int8(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
printf("%8s", "");
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSE2
|
||||
if (raid_cpu_has_sse2()) {
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("%8s", "");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
raid_gen6_ssse3(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
SPEED_START {
|
||||
raid_gen6_ssse3ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("%8s", "");
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
raid_gen6_avx2ext(nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
/* recover table */
|
||||
printf("RAID functions used for recovering:\n");
|
||||
printf("%8s", "");
|
||||
printf("%8s", "best");
|
||||
printf("%8s", "int8");
|
||||
#ifdef CONFIG_X86
|
||||
printf("%8s", "ssse3");
|
||||
printf("%8s", "avx2");
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec1");
|
||||
printf("%8s", raid_rec1_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN1 optimized case */
|
||||
raid_rec1_int8(1, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN1 optimized case */
|
||||
raid_rec1_ssse3(1, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN1 optimized case */
|
||||
raid_rec1_avx2(1, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec2");
|
||||
printf("%8s", raid_rec2_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN2 optimized case */
|
||||
raid_rec2_int8(2, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN2 optimized case */
|
||||
raid_rec2_ssse3(2, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
/* +1 to avoid GEN1 optimized case */
|
||||
raid_rec2_avx2(2, id, ip + 1, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec3");
|
||||
printf("%8s", raid_recX_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_int8(3, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_ssse3(3, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_avx2(3, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec4");
|
||||
printf("%8s", raid_recX_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_int8(4, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_ssse3(4, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_avx2(4, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec5");
|
||||
printf("%8s", raid_recX_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_int8(5, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_ssse3(5, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_avx2(5, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
|
||||
printf("%8s", "rec6");
|
||||
printf("%8s", raid_recX_tag());
|
||||
fflush(stdout);
|
||||
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_int8(6, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#ifdef CONFIG_SSSE3
|
||||
if (raid_cpu_has_ssse3()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_ssse3(6, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_AVX2
|
||||
if (raid_cpu_has_avx2()) {
|
||||
SPEED_START {
|
||||
for (j = 0; j < nd; ++j)
|
||||
raid_recX_avx2(6, id, ip, nd, size, v);
|
||||
} SPEED_STOP
|
||||
|
||||
printf("%8" PRIu64, ds / dt);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
free(v_alloc);
|
||||
free(v);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Speed test for the RAID Cauchy library\n\n");
|
||||
|
||||
raid_init();
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
if (raid_cpu_has_sse2())
|
||||
printf("Including x86 SSE2 functions\n");
|
||||
if (raid_cpu_has_ssse3())
|
||||
printf("Including x86 SSSE3 functions\n");
|
||||
if (raid_cpu_has_avx2())
|
||||
printf("Including x86 AVX2 functions\n");
|
||||
#endif
|
||||
#ifdef CONFIG_X86_64
|
||||
printf("Including x64 extended SSE register set\n");
|
||||
#endif
|
||||
|
||||
printf("\nPlease wait about 30 seconds...\n\n");
|
||||
|
||||
speed();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
2452
raid/x86.c
Normal file
2452
raid/x86.c
Normal file
File diff suppressed because it is too large
Load Diff
255
raid/x86z.c
Normal file
255
raid/x86z.c
Normal file
@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Andrea Mazzoleni
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(CONFIG_X86) && defined(CONFIG_SSE2)
|
||||
static const struct gfzconst16 {
|
||||
uint8_t poly[16];
|
||||
uint8_t half[16];
|
||||
uint8_t low7[16];
|
||||
} gfzconst16 __aligned(64) =
|
||||
{
|
||||
{
|
||||
0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
|
||||
0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d
|
||||
},
|
||||
{
|
||||
0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
|
||||
0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e
|
||||
},
|
||||
{
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_X86) && defined(CONFIG_SSE2)
|
||||
/*
|
||||
* GENz (triple parity with powers of 2^-1) SSE2 implementation
|
||||
*/
|
||||
void raid_genz_sse2(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t**)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
|
||||
raid_sse_begin();
|
||||
|
||||
asm volatile ("movdqa %0,%%xmm7" : : "m" (gfzconst16.poly[0]));
|
||||
asm volatile ("movdqa %0,%%xmm3" : : "m" (gfzconst16.half[0]));
|
||||
asm volatile ("movdqa %0,%%xmm6" : : "m" (gfzconst16.low7[0]));
|
||||
|
||||
for (i = 0; i < size; i += 16) {
|
||||
asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
|
||||
asm volatile ("movdqa %xmm0,%xmm1");
|
||||
asm volatile ("movdqa %xmm0,%xmm2");
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
asm volatile ("pxor %xmm4,%xmm4");
|
||||
asm volatile ("pcmpgtb %xmm1,%xmm4");
|
||||
asm volatile ("paddb %xmm1,%xmm1");
|
||||
asm volatile ("pand %xmm7,%xmm4");
|
||||
asm volatile ("pxor %xmm4,%xmm1");
|
||||
|
||||
asm volatile ("movdqa %xmm2,%xmm4");
|
||||
asm volatile ("pxor %xmm5,%xmm5");
|
||||
asm volatile ("psllw $7,%xmm4");
|
||||
asm volatile ("psrlw $1,%xmm2");
|
||||
asm volatile ("pcmpgtb %xmm4,%xmm5");
|
||||
asm volatile ("pand %xmm6,%xmm2");
|
||||
asm volatile ("pand %xmm3,%xmm5");
|
||||
asm volatile ("pxor %xmm5,%xmm2");
|
||||
|
||||
asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
|
||||
asm volatile ("pxor %xmm4,%xmm0");
|
||||
asm volatile ("pxor %xmm4,%xmm1");
|
||||
asm volatile ("pxor %xmm4,%xmm2");
|
||||
}
|
||||
asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
|
||||
asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
|
||||
asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
|
||||
}
|
||||
|
||||
raid_sse_end();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_X86_64) && defined(CONFIG_SSE2)
|
||||
/*
|
||||
* GENz (triple parity with powers of 2^-1) SSE2 implementation
|
||||
*
|
||||
* Note that it uses 16 registers, meaning that x64 is required.
|
||||
*/
|
||||
void raid_genz_sse2ext(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t**)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
|
||||
raid_sse_begin();
|
||||
|
||||
asm volatile ("movdqa %0,%%xmm7" : : "m" (gfzconst16.poly[0]));
|
||||
asm volatile ("movdqa %0,%%xmm3" : : "m" (gfzconst16.half[0]));
|
||||
asm volatile ("movdqa %0,%%xmm11" : : "m" (gfzconst16.low7[0]));
|
||||
|
||||
for (i = 0; i < size; i += 32) {
|
||||
asm volatile ("movdqa %0,%%xmm0" : : "m" (v[l][i]));
|
||||
asm volatile ("movdqa %0,%%xmm8" : : "m" (v[l][i + 16]));
|
||||
asm volatile ("movdqa %xmm0,%xmm1");
|
||||
asm volatile ("movdqa %xmm8,%xmm9");
|
||||
asm volatile ("movdqa %xmm0,%xmm2");
|
||||
asm volatile ("movdqa %xmm8,%xmm10");
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
asm volatile ("movdqa %xmm2,%xmm6");
|
||||
asm volatile ("movdqa %xmm10,%xmm14");
|
||||
asm volatile ("pxor %xmm4,%xmm4");
|
||||
asm volatile ("pxor %xmm12,%xmm12");
|
||||
asm volatile ("pxor %xmm5,%xmm5");
|
||||
asm volatile ("pxor %xmm13,%xmm13");
|
||||
asm volatile ("psllw $7,%xmm6");
|
||||
asm volatile ("psllw $7,%xmm14");
|
||||
asm volatile ("psrlw $1,%xmm2");
|
||||
asm volatile ("psrlw $1,%xmm10");
|
||||
asm volatile ("pcmpgtb %xmm1,%xmm4");
|
||||
asm volatile ("pcmpgtb %xmm9,%xmm12");
|
||||
asm volatile ("pcmpgtb %xmm6,%xmm5");
|
||||
asm volatile ("pcmpgtb %xmm14,%xmm13");
|
||||
asm volatile ("paddb %xmm1,%xmm1");
|
||||
asm volatile ("paddb %xmm9,%xmm9");
|
||||
asm volatile ("pand %xmm11,%xmm2");
|
||||
asm volatile ("pand %xmm11,%xmm10");
|
||||
asm volatile ("pand %xmm7,%xmm4");
|
||||
asm volatile ("pand %xmm7,%xmm12");
|
||||
asm volatile ("pand %xmm3,%xmm5");
|
||||
asm volatile ("pand %xmm3,%xmm13");
|
||||
asm volatile ("pxor %xmm4,%xmm1");
|
||||
asm volatile ("pxor %xmm12,%xmm9");
|
||||
asm volatile ("pxor %xmm5,%xmm2");
|
||||
asm volatile ("pxor %xmm13,%xmm10");
|
||||
|
||||
asm volatile ("movdqa %0,%%xmm4" : : "m" (v[d][i]));
|
||||
asm volatile ("movdqa %0,%%xmm12" : : "m" (v[d][i + 16]));
|
||||
asm volatile ("pxor %xmm4,%xmm0");
|
||||
asm volatile ("pxor %xmm4,%xmm1");
|
||||
asm volatile ("pxor %xmm4,%xmm2");
|
||||
asm volatile ("pxor %xmm12,%xmm8");
|
||||
asm volatile ("pxor %xmm12,%xmm9");
|
||||
asm volatile ("pxor %xmm12,%xmm10");
|
||||
}
|
||||
asm volatile ("movntdq %%xmm0,%0" : "=m" (p[i]));
|
||||
asm volatile ("movntdq %%xmm8,%0" : "=m" (p[i + 16]));
|
||||
asm volatile ("movntdq %%xmm1,%0" : "=m" (q[i]));
|
||||
asm volatile ("movntdq %%xmm9,%0" : "=m" (q[i + 16]));
|
||||
asm volatile ("movntdq %%xmm2,%0" : "=m" (r[i]));
|
||||
asm volatile ("movntdq %%xmm10,%0" : "=m" (r[i + 16]));
|
||||
}
|
||||
|
||||
raid_sse_end();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_X86_64) && defined(CONFIG_AVX2)
|
||||
/*
|
||||
* GENz (triple parity with powers of 2^-1) AVX2 implementation
|
||||
*
|
||||
* Note that it uses 16 registers, meaning that x64 is required.
|
||||
*/
|
||||
void raid_genz_avx2ext(int nd, size_t size, void **vv)
|
||||
{
|
||||
uint8_t **v = (uint8_t**)vv;
|
||||
uint8_t *p;
|
||||
uint8_t *q;
|
||||
uint8_t *r;
|
||||
int d, l;
|
||||
size_t i;
|
||||
|
||||
l = nd - 1;
|
||||
p = v[nd];
|
||||
q = v[nd + 1];
|
||||
r = v[nd + 2];
|
||||
|
||||
raid_avx_begin();
|
||||
|
||||
asm volatile ("vbroadcasti128 %0,%%ymm7" : : "m" (gfzconst16.poly[0]));
|
||||
asm volatile ("vbroadcasti128 %0,%%ymm3" : : "m" (gfzconst16.half[0]));
|
||||
asm volatile ("vbroadcasti128 %0,%%ymm11" : : "m" (gfzconst16.low7[0]));
|
||||
asm volatile ("vpxor %ymm15,%ymm15,%ymm15");
|
||||
|
||||
for (i = 0; i < size; i += 64) {
|
||||
asm volatile ("vmovdqa %0,%%ymm0" : : "m" (v[l][i]));
|
||||
asm volatile ("vmovdqa %0,%%ymm8" : : "m" (v[l][i + 32]));
|
||||
asm volatile ("vmovdqa %ymm0,%ymm1");
|
||||
asm volatile ("vmovdqa %ymm8,%ymm9");
|
||||
asm volatile ("vmovdqa %ymm0,%ymm2");
|
||||
asm volatile ("vmovdqa %ymm8,%ymm10");
|
||||
for (d = l - 1; d >= 0; --d) {
|
||||
asm volatile ("vpsllw $7,%ymm2,%ymm6");
|
||||
asm volatile ("vpsllw $7,%ymm10,%ymm14");
|
||||
asm volatile ("vpsrlw $1,%ymm2,%ymm2");
|
||||
asm volatile ("vpsrlw $1,%ymm10,%ymm10");
|
||||
asm volatile ("vpcmpgtb %ymm1,%ymm15,%ymm4");
|
||||
asm volatile ("vpcmpgtb %ymm9,%ymm15,%ymm12");
|
||||
asm volatile ("vpcmpgtb %ymm6,%ymm15,%ymm5");
|
||||
asm volatile ("vpcmpgtb %ymm14,%ymm15,%ymm13");
|
||||
asm volatile ("vpaddb %ymm1,%ymm1,%ymm1");
|
||||
asm volatile ("vpaddb %ymm9,%ymm9,%ymm9");
|
||||
asm volatile ("vpand %ymm11,%ymm2,%ymm2");
|
||||
asm volatile ("vpand %ymm11,%ymm10,%ymm10");
|
||||
asm volatile ("vpand %ymm7,%ymm4,%ymm4");
|
||||
asm volatile ("vpand %ymm7,%ymm12,%ymm12");
|
||||
asm volatile ("vpand %ymm3,%ymm5,%ymm5");
|
||||
asm volatile ("vpand %ymm3,%ymm13,%ymm13");
|
||||
asm volatile ("vpxor %ymm4,%ymm1,%ymm1");
|
||||
asm volatile ("vpxor %ymm12,%ymm9,%ymm9");
|
||||
asm volatile ("vpxor %ymm5,%ymm2,%ymm2");
|
||||
asm volatile ("vpxor %ymm13,%ymm10,%ymm10");
|
||||
|
||||
asm volatile ("vmovdqa %0,%%ymm4" : : "m" (v[d][i]));
|
||||
asm volatile ("vmovdqa %0,%%ymm12" : : "m" (v[d][i + 32]));
|
||||
asm volatile ("vpxor %ymm4,%ymm0,%ymm0");
|
||||
asm volatile ("vpxor %ymm4,%ymm1,%ymm1");
|
||||
asm volatile ("vpxor %ymm4,%ymm2,%ymm2");
|
||||
asm volatile ("vpxor %ymm12,%ymm8,%ymm8");
|
||||
asm volatile ("vpxor %ymm12,%ymm9,%ymm9");
|
||||
asm volatile ("vpxor %ymm12,%ymm10,%ymm10");
|
||||
}
|
||||
asm volatile ("vmovntdq %%ymm0,%0" : "=m" (p[i]));
|
||||
asm volatile ("vmovntdq %%ymm8,%0" : "=m" (p[i + 32]));
|
||||
asm volatile ("vmovntdq %%ymm1,%0" : "=m" (q[i]));
|
||||
asm volatile ("vmovntdq %%ymm9,%0" : "=m" (q[i + 32]));
|
||||
asm volatile ("vmovntdq %%ymm2,%0" : "=m" (r[i]));
|
||||
asm volatile ("vmovntdq %%ymm10,%0" : "=m" (r[i + 32]));
|
||||
}
|
||||
|
||||
raid_avx_end();
|
||||
}
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user