initial commit
commit
030129423f
@ -0,0 +1,37 @@
|
||||
*~
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
*.dvi
|
||||
*.synctex.gz
|
||||
.deps
|
||||
.libs
|
||||
autom4te.cache/
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
intltool-extract.in
|
||||
intltool-merge.in
|
||||
intltool-update.in
|
||||
lib/libtdata-0.2.pc
|
||||
libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
po/Makefile.in.in
|
||||
po/POTFILES
|
||||
po/stamp-it
|
||||
stamp-h1
|
||||
include/version.h
|
||||
.emacs.desktop
|
||||
nbproject
|
@ -0,0 +1,5 @@
|
||||
This software was developed by Askele companies group.
|
||||
* EU part: http://askele.com
|
||||
* NW European part of Russia: http://askele-ingria.com
|
||||
Team:
|
||||
* General SW Architect and PM: Alexander Vdolainen <vdo@askele.com>
|
@ -0,0 +1,3 @@
|
||||
Askele business software license.
|
||||
|
||||
Libs and others might be under LGPLv3.
|
@ -0,0 +1,166 @@
|
||||
GNU LESSER 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.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
|
@ -0,0 +1,10 @@
|
||||
2013-09-22 Alexander Vdolainen <vdo@askele.com>
|
||||
* (a set of files): added autotools
|
||||
|
||||
2014-11-23 Alexander Vdolainen <vdo@askele.com>
|
||||
* Initial import of 0.2 version
|
||||
|
||||
|
||||
Copyright 2013-2014 Askele, Inc.
|
||||
Copying and distribution of this file, with or without modification, are
|
||||
permitted provided the copyright notice and this notice are preserved.
|
@ -0,0 +1,370 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
notice and this notice are preserved. This file is offered as-is,
|
||||
without warranty of any kind.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package. Some packages provide this
|
||||
`INSTALL' file but do not implement all of the features documented
|
||||
below. The lack of an optional feature in a given package is not
|
||||
necessarily a bug. More recommendations for GNU packages can be found
|
||||
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package, generally using the just-built uninstalled binaries.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation. When installing into a prefix owned by root, it is
|
||||
recommended that the package be configured and built as a regular
|
||||
user, and only the `make install' phase executed with root
|
||||
privileges.
|
||||
|
||||
5. Optionally, type `make installcheck' to repeat any self-tests, but
|
||||
this time using the binaries in their final installed location.
|
||||
This target does not install anything. Running this target as a
|
||||
regular user, particularly if the prior `make install' required
|
||||
root privileges, verifies that the installation completed
|
||||
correctly.
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
7. Often, you can also type `make uninstall' to remove the installed
|
||||
files again. In practice, not all packages have tested that
|
||||
uninstallation works correctly, even though it is required by the
|
||||
GNU Coding Standards.
|
||||
|
||||
8. Some packages, particularly those that use Automake, provide `make
|
||||
distcheck', which can by used by developers to test that all other
|
||||
targets like `make install' and `make uninstall' work correctly.
|
||||
This target is generally not run by end users.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'. This
|
||||
is known as a "VPATH" build.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX', where PREFIX must be an
|
||||
absolute file name.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them. In general, the
|
||||
default for these options is expressed in terms of `${prefix}', so that
|
||||
specifying just `--prefix' will affect all of the other directory
|
||||
specifications that were not explicitly provided.
|
||||
|
||||
The most portable way to affect installation locations is to pass the
|
||||
correct locations to `configure'; however, many packages provide one or
|
||||
both of the following shortcuts of passing variable assignments to the
|
||||
`make install' command line to change installation locations without
|
||||
having to reconfigure or recompile.
|
||||
|
||||
The first method involves providing an override variable for each
|
||||
affected directory. For example, `make install
|
||||
prefix=/alternate/directory' will choose an alternate location for all
|
||||
directory configuration variables that were expressed in terms of
|
||||
`${prefix}'. Any directories that were specified during `configure',
|
||||
but not in terms of `${prefix}', must each be overridden at install
|
||||
time for the entire installation to be relocated. The approach of
|
||||
makefile variable overrides for each directory variable is required by
|
||||
the GNU Coding Standards, and ideally causes no recompilation.
|
||||
However, some platforms have known limitations with the semantics of
|
||||
shared libraries that end up requiring recompilation when using this
|
||||
method, particularly noticeable in packages that use GNU Libtool.
|
||||
|
||||
The second method involves providing the `DESTDIR' variable. For
|
||||
example, `make install DESTDIR=/alternate/directory' will prepend
|
||||
`/alternate/directory' before all installation names. The approach of
|
||||
`DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
does not work on platforms that have drive letters. On the other hand,
|
||||
it does better at avoiding recompilation issues, and works well even
|
||||
when some directory options were not specified in terms of `${prefix}'
|
||||
at `configure' time.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Some packages offer the ability to configure how verbose the
|
||||
execution of `make' will be. For these packages, running `./configure
|
||||
--enable-silent-rules' sets the default to minimal output, which can be
|
||||
overridden with `make V=1'; while running `./configure
|
||||
--disable-silent-rules' sets the default to verbose, which can be
|
||||
overridden with `make V=0'.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
HP-UX `make' updates targets which have the same time stamps as
|
||||
their prerequisites, which makes it generally unusable when shipped
|
||||
generated files such as `configure' are involved. Use GNU `make'
|
||||
instead.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||
in your `PATH', put it _after_ `/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in `/boot/common',
|
||||
not `/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
@ -0,0 +1,32 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = po include lib
|
||||
|
||||
libtdatadocdir = ${prefix}/doc/libtdata
|
||||
libtdatadoc_DATA = \
|
||||
README\
|
||||
COPYING\
|
||||
AUTHORS\
|
||||
ChangeLog\
|
||||
INSTALL\
|
||||
NEWS
|
||||
|
||||
|
||||
INTLTOOL_FILES = intltool-extract.in \
|
||||
intltool-merge.in \
|
||||
intltool-update.in
|
||||
|
||||
EXTRA_DIST = $(libtdatadoc_DATA) \
|
||||
$(INTLTOOL_FILES)
|
||||
|
||||
DISTCLEANFILES = intltool-extract \
|
||||
intltool-merge \
|
||||
intltool-update \
|
||||
po/.intltool-merge-cache
|
||||
|
||||
clean-local:
|
||||
|
||||
|
||||
# Remove doc directory on uninstall
|
||||
uninstall-local:
|
||||
-rm -r $(libtdatadocdir)
|
@ -0,0 +1,157 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
DIE=0
|
||||
|
||||
if [ -n "$GNOME2_DIR" ]; then
|
||||
ACLOCAL_FLAGS="-I $GNOME2_DIR/share/aclocal $ACLOCAL_FLAGS"
|
||||
LD_LIBRARY_PATH="$GNOME2_DIR/lib:$LD_LIBRARY_PATH"
|
||||
PATH="$GNOME2_DIR/bin:$PATH"
|
||||
export PATH
|
||||
export LD_LIBRARY_PATH
|
||||
fi
|
||||
|
||||
(test -f $srcdir/configure.ac) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level package directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`autoconf' installed."
|
||||
echo "Download the appropriate package for your distribution,"
|
||||
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
(grep "^IT_PROG_INTLTOOL" $srcdir/configure.ac >/dev/null) && {
|
||||
(intltoolize --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`intltool' installed."
|
||||
echo "You can get it from:"
|
||||
echo " ftp://ftp.gnome.org/pub/GNOME/"
|
||||
DIE=1
|
||||
}
|
||||
}
|
||||
|
||||
(grep "^AM_PROG_XML_I18N_TOOLS" $srcdir/configure.ac >/dev/null) && {
|
||||
(xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`xml-i18n-toolize' installed."
|
||||
echo "You can get it from:"
|
||||
echo " ftp://ftp.gnome.org/pub/GNOME/"
|
||||
DIE=1
|
||||
}
|
||||
}
|
||||
|
||||
(grep "^LT_INIT" $srcdir/configure.ac >/dev/null) && {
|
||||
(libtool --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`libtool' installed."
|
||||
echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
}
|
||||
|
||||
(grep "^AM_GLIB_GNU_GETTEXT" $srcdir/configure.ac >/dev/null) && {
|
||||
(grep "sed.*POTFILES" $srcdir/configure.ac) > /dev/null || \
|
||||
(glib-gettextize --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`glib' installed."
|
||||
echo "You can get it from: ftp://ftp.gtk.org/pub/gtk"
|
||||
DIE=1
|
||||
}
|
||||
}
|
||||
|
||||
(automake --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: You must have \`automake' installed."
|
||||
echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
NO_AUTOMAKE=yes
|
||||
}
|
||||
|
||||
|
||||
# if no automake, don't bother testing for aclocal
|
||||
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
|
||||
echo
|
||||
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
|
||||
echo "installed doesn't appear recent enough."
|
||||
echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
|
||||
DIE=1
|
||||
}
|
||||
|
||||
if test "$DIE" -eq 1; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if test -z "$*"; then
|
||||
echo "**Warning**: I am going to run \`configure' with no arguments."
|
||||
echo "If you wish to pass any to it, please specify them on the"
|
||||
echo \`$0\'" command line."
|
||||
echo
|
||||
fi
|
||||
|
||||
case $CC in
|
||||
xlc )
|
||||
am_opt=--include-deps;;
|
||||
esac
|
||||
|
||||
for coin in `find $srcdir -path $srcdir/CVS -prune -o -name configure.ac -print`
|
||||
do
|
||||
dr=`dirname $coin`
|
||||
if test -f $dr/NO-AUTO-GEN; then
|
||||
echo skipping $dr -- flagged as no auto-gen
|
||||
else
|
||||
echo processing $dr
|
||||
( cd $dr
|
||||
|
||||
aclocalinclude="$ACLOCAL_FLAGS"
|
||||
|
||||
if grep "^AM_GLIB_GNU_GETTEXT" configure.ac >/dev/null; then
|
||||
echo "Creating $dr/aclocal.m4 ..."
|
||||
test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
|
||||
echo "Running glib-gettextize... Ignore non-fatal messages."
|
||||
echo "no" | glib-gettextize --force --copy
|
||||
echo "Making $dr/aclocal.m4 writable ..."
|
||||
test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
|
||||
fi
|
||||
if grep "^IT_PROG_INTLTOOL" configure.ac >/dev/null; then
|
||||
echo "Running intltoolize..."
|
||||
intltoolize --copy --force --automake
|
||||
fi
|
||||
if grep "^AM_PROG_XML_I18N_TOOLS" configure.ac >/dev/null; then
|
||||
echo "Running xml-i18n-toolize..."
|
||||
xml-i18n-toolize --copy --force --automake
|
||||
fi
|
||||
if grep "^LT_INIT" configure.ac >/dev/null; then
|
||||
if test -z "$NO_LIBTOOLIZE" ; then
|
||||
echo "Running libtoolize..."
|
||||
libtoolize --force --copy
|
||||
fi
|
||||
fi
|
||||
echo "Running aclocal $aclocalinclude ..."
|
||||
aclocal $aclocalinclude
|
||||
if grep "^A[CM]_CONFIG_HEADER" configure.ac >/dev/null; then
|
||||
echo "Running autoheader..."
|
||||
autoheader
|
||||
fi
|
||||
echo "Running automake --gnu $am_opt ..."
|
||||
automake --add-missing --copy --gnu $am_opt
|
||||
echo "Running autoconf ..."
|
||||
autoconf
|
||||
)
|
||||
fi
|
||||
done
|
||||
|
||||
if test x$NOCONFIGURE = x; then
|
||||
echo Running $srcdir/configure "$@" ...
|
||||
$srcdir/configure "$@" \
|
||||
&& echo Now type \`make\' to compile. || exit 1
|
||||
else
|
||||
echo Skipping configure process.
|
||||
fi
|
@ -0,0 +1,42 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT(libtdata, 0.2)
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.11])
|
||||
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
AC_PROG_CC
|
||||
|
||||
dnl ***************************************************************************
|
||||
dnl Internationalization
|
||||
dnl ***************************************************************************
|
||||
IT_PROG_INTLTOOL([0.35.0])
|
||||
|
||||
GETTEXT_PACKAGE=libtdata
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", [GETTEXT package name])
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
|
||||
LT_INIT
|
||||
|
||||
dnl *****************
|
||||
dnl ***** options *****
|
||||
dnl *****************
|
||||
|
||||
AC_ARG_ENABLE([build_examples],
|
||||
AS_HELP_STRING([--enable-build-examples], [Enable examples build]))
|
||||
|
||||
AS_IF([test "x$enable_build_examples" = "xyes"], [
|
||||
AC_DEFINE([BUILD_EXAMPLES], 1, [build of examples enabled])
|
||||
])
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
lib/libtdata-0.2.pc
|
||||
lib/Makefile
|
||||
include/Makefile
|
||||
po/Makefile.in])
|
@ -0,0 +1 @@
|
||||
nobase_include_HEADERS = tdata/bitwise.h tdata/idx_allocator.h tdata/macro.h tdata/tree.h tdata/usrtc.h
|
@ -0,0 +1,429 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* (c) Copyright 2006,2007,2008 Jari OS Core Team <http://jarios.org>
|
||||
* (c) Copyright 2008 Dmitry Gromada <gromada82@gmail.com>
|
||||
* (c) Copyright 2010 Alexander Vdolainen <vdo@askele.com>
|
||||
*
|
||||
* (c) Copyright 2012 - 2013 Askele Oy <http://askele.com>
|
||||
*
|
||||
* Implements bitwise operations with multiword bitmaps
|
||||
*/
|
||||
|
||||
#ifndef __BITWISE_H__
|
||||
#define __BITWISE_H__
|
||||
|
||||
/* TODO: add arch deps */
|
||||
//#include <arch/bitwise.h>
|
||||
|
||||
/* TODO: add linux headers tests */
|
||||
#include <asm-generic/bitsperlong.h>
|
||||
|
||||
#ifdef __BITS_PER_LONG
|
||||
#define BITS_PER_LONG __BITS_PER_LONG
|
||||
#endif
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
#define TYPE_LONG_SHIFT 6
|
||||
#endif
|
||||
|
||||
#if BITS_PER_LONG == 32
|
||||
#define TYPE_LONG_SHIFT 5
|
||||
#endif
|
||||
|
||||
typedef struct __bitmap {
|
||||
int nwords;
|
||||
unsigned long *map;
|
||||
} bitmap_t;
|
||||
|
||||
/**
|
||||
* @fn static inline void bit_set(void *bitmap, int bit)
|
||||
* Set bit number @a bit in the bitmap @a bitmap
|
||||
* @note The limit of @a bitmap = sizeof(unsigned long)
|
||||
*
|
||||
* @param[out] bitmap - A pointer to the bitmap
|
||||
* @param bit - Number of bit to set
|
||||
*/
|
||||
#ifndef ARCH_BIT_SET
|
||||
static inline void bit_set(void *bitmap, int bit)
|
||||
{
|
||||
*(unsigned long *)bitmap |= (1 << bit);
|
||||
}
|
||||
#else
|
||||
#define bit_set(bitmap, bit) arch_bit_set(bitmap, bit)
|
||||
#endif /* ARCH_BIT_SET */
|
||||
|
||||
/**
|
||||
* @fn static inline void bit_clear(void *bitmap, int bit)
|
||||
* Clear bit number @a bit in the bitmap @a bitmap
|
||||
* @note The limit of @a bitmap = sizeof(unsigned long)
|
||||
*
|
||||
* @param[out] bitmap - A pointer to the bitmap
|
||||
* @param bit - Number of bit to clear
|
||||
*/
|
||||
#ifndef ARCH_BIT_CLEAR
|
||||
static inline void bit_clear(void *bitmap, int bit)
|
||||
{
|
||||
*(unsigned long *)bitmap &= ~(1 << bit);
|
||||
}
|
||||
#else
|
||||
#define bit_clear(bitmap, bit) arch_bit_clear(bitmap, bit)
|
||||
#endif /* ARCH_BIT_CLEAR */
|
||||
|
||||
/**
|
||||
* @fn static inline void bit_toggle(void *bitmap, int bit)
|
||||
* Toggle bit @a bit in the bitmap @a bitmap.
|
||||
* @note The limit of @a bitmap = sizeof(unsigned long)
|
||||
*
|
||||
* @param[out] bitmap - A pointer to the bitmap.
|
||||
* @param bit - Number of bit to toggle
|
||||
*/
|
||||
#ifndef ARCH_BIT_TOGGLE
|
||||
static inline void bit_toggle(void *bitmap, int bit)
|
||||
{
|
||||
*(unsigned long *)bitmap ^= (1 << bit);
|
||||
}
|
||||
#else
|
||||
#define bit_toggle(bitmap, bit) arch_bit_toggle(bitmap, bit)
|
||||
#endif /* ARCH_BIT_TOGGLE */
|
||||
|
||||
/**
|
||||
* @fn static inline int bit_test(void *bitmap, int bitno)
|
||||
* Test if bit with number @a bitno is set in the bitmap @a bitmap.
|
||||
* @note The limit of @a bitmap = sizeof(unsigned long)
|
||||
*
|
||||
* @param bitmap - A pointer to the bitmap.
|
||||
* @param bitno - Number of bit to test
|
||||
* @return 1 if bit is set and 0 otherwise
|
||||
*/
|
||||
#ifndef ARCH_BIT_TEST
|
||||
static inline int bit_test(void *bitmap, int bitno)
|
||||
{
|
||||
return ((*(unsigned long *)bitmap & (1 << bitno)) >> bitno);
|
||||
}
|
||||
#else
|
||||
#define bit_test(bitmap, bitno) arch_bit_test(bitmap, bitno)
|
||||
#endif /* ARCH_BIT_TEST */
|
||||
|
||||
/**
|
||||
* @fn static inline int bit_test_and_set(void *bitmap, int bitno)
|
||||
* @brief Get old value of bit with number @a bitno and set @a bitno bit in the bitmap
|
||||
*
|
||||
* This function is similar to bit_set() except it copies old bit value before
|
||||
* setting it to 1 and return that value after needed bit was setted.
|
||||
* @note The limit of @a bitmap = sizeof(unsigned long)
|
||||
*
|
||||
* @param bitmap - A pointer to the bitmap
|
||||
* @param bitno - The number of bit to test and set
|
||||
* @return Old value of bit with number @a bitno
|
||||
*/
|
||||
#ifndef ARCH_BIT_TEST_AND_SET
|
||||
static inline int bit_test_and_set(void *bitmap, int bitno)
|
||||
{
|
||||
int val = (*(unsigned long *)bitmap & (1 << bitno));
|
||||
*(unsigned long *)bitmap |= (1 << bitno);
|
||||
|
||||
return val;
|
||||
}
|
||||
#else
|
||||
#define bit_test_and_set(bitmap, bitno) arch_bit_test_and_set(bitmap, bitno)
|
||||
#endif /* ARCH_BIT_TEST_AND_SET */
|
||||
|
||||
/**
|
||||
* @fn static inline int bit_test_and_reset(void *bitmap, int bitno)
|
||||
* @brief Get old value of bit with number @a bitno and clear @a bitno bit in the bitmap
|
||||
*
|
||||
* This function is similar to bit_clear() except it copies old bit value before
|
||||
* setting it to 1 and return that value after needed bit was setted.
|
||||
* @note The limit of @a bitmap = sizeof(unsigned long)
|
||||
*
|
||||
* @param bitmap - A pointer to the bitmap
|
||||
* @param bitno - The number of bit to test and set
|
||||
* @return Old value of bit with number @a bitno
|
||||
*/
|
||||
#ifndef ARCH_BIT_TEST_AND_RESET
|
||||
static inline int bit_test_and_reset(void *bitmap, int bitno)
|
||||
{
|
||||
int val = (*(unsigned long *)bitmap & (1 << bitno));
|
||||
*(unsigned long *)bitmap &= ~(1 << bitno);
|
||||
|
||||
return val;
|
||||
}
|
||||
#else
|
||||
#define bit_test_and_reset(bitmap, bitno) arch_bit_test_and_reset(bitmap, bitno)
|
||||
#endif /* ARCH_BIT_TEST_AND_RESET */
|
||||
|
||||
/**
|
||||
* @fn static inline long bit_find_lsf(unsigned long word)
|
||||
* Find first set least significant bit.
|
||||
*
|
||||
* @param word - Where to search
|
||||
* @return Found bit number on success, negative value on failure.
|
||||
*/
|
||||
#ifndef ARCH_BIT_FIND_LSF
|
||||
static inline long bit_find_lsf(unsigned long word)
|
||||
{
|
||||
long c = -1;
|
||||
|
||||
for (; word; c++, word >>= 1) {
|
||||
if ((word & 0x01)) {
|
||||
c++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#else
|
||||
#define bit_find_lsf(word) arch_bit_find_lsf(word)
|
||||
#endif /* ARCH_BIT_FIND_LSF */
|
||||
|
||||
#ifndef ARCH_ZERO_BIT_FIND_LSF
|
||||
#define zero_bit_find_lsf(word) bit_find_lsf(~(word))
|
||||
#else
|
||||
#define zero_bit_find_lsf(word) arch_zero_bit_find_lsf(word)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @fn static inline long bit_find_msf(unsigned long word)
|
||||
* Find most significant set bit in the @a word.
|
||||
*
|
||||
* @param word - Where to search.
|
||||
* @return Found bit number on success, negative value on failure.
|
||||
*/
|
||||
#ifndef ARCH_BIT_FIND_MSF
|
||||
static inline long bit_find_msf(unsigned long word)
|
||||
{
|
||||
long c = -1;
|
||||
|
||||
while (word) {
|
||||
c++;
|
||||
word >>= 1;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#else
|
||||
#define bit_find_msf(word) arch_bit_find_msf(word)
|
||||
#endif /* ARCH_BIT_FIND_MSF */
|
||||
|
||||
/**
|
||||
* @fn static inline long bit_find_lsfz(unsigned long word)
|
||||
* Find first zero least significant bit.
|
||||
*
|
||||
* @param word - Where to search
|
||||
* @return Found bit number on success, negative value on failure.
|
||||
*/
|
||||
#ifndef ARCH_BIT_FIND_LSFZ
|
||||
static inline long bit_find_lsfz(unsigned long word)
|
||||
{
|
||||
long c = -1;
|
||||
|
||||
word = ~word;
|
||||
|
||||
for (; word; c++, word >>= 1) {
|
||||
if ((word & 0x01)) {
|
||||
c++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#else
|
||||
#define bit_find_lsfz(word) arch_bit_find_lsfz(word)
|
||||
#endif /* ARCH_BIT_FIND_LSFZ */
|
||||
|
||||
/**
|
||||
* @fn static inline long bit_find_msfz(unsigned long word)
|
||||
* Find most significant zero bit in the @a word.
|
||||
*
|
||||
* @param word - Where to search.
|
||||
* @return Found bit number on success, negative value on failure.
|
||||
*/
|
||||
#ifndef ARCH_BIT_FIND_MSFZ
|
||||
static inline long bit_find_msfz(unsigned long word)
|
||||
{
|
||||
long c = -1;
|
||||
|
||||
word = ~word;
|
||||
|
||||
while (word) {
|
||||
c++;
|
||||
word >>= 1;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
#else
|
||||
#define bit_find_msfz(word) arch_bit_find_msfz(word)
|
||||
#endif /* ARCH_BIT_FIND_MSFZ */
|
||||
|
||||
/**
|
||||
* @fn static inline void bits_or(void *word, unsigned long flags)
|
||||
* Executes logical OR with @a word and @a flags and writes result to @a word
|
||||
* @note The limit of @a word = sizeof(unsigned long)
|
||||
*
|
||||
* @param[out] word - A pointer to memory results will be written to
|
||||
* @param flsgs - Flags that will be OR'ed with @a word
|
||||
*/
|
||||
#ifndef ARCH_BITS_OR
|
||||
static inline void bits_or(void *word, unsigned long flags)
|
||||
{
|
||||
*(unsigned long *)word |= flags;
|
||||
}
|
||||
#define bits_or(word, flags) panic("bits_or uniplemented")
|
||||
#else
|
||||
#define bits_or(word, flags) arch_bits_or(word, flags)
|
||||
#endif /* ARCH_BITS_OR */
|
||||
|
||||
/**
|
||||
* @fn static inline void bits_and(void *word, unsigned long mask)
|
||||
* Executes logical AND with @a word and @a mask and writes result to @a word.
|
||||
* @note The limit of @a word = sizeof(unsigned long)
|
||||
*
|
||||
* @param[out] word - A pointer to memory results will be written to
|
||||
* @param mask - A mask that will be AND'ed with @a word
|
||||
*/
|
||||
#ifndef ARCH_BITS_AND
|
||||
static inline void bits_and(void *word, unsigned long mask)
|
||||
{
|
||||
*(unsigned long *)word &= mask;
|
||||
}
|
||||
#else
|
||||
#define bits_and(word, mask) arch_bits_and(word, mask)
|
||||
#endif /* ARCH_BITS_AND */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize multiword bitmap
|
||||
*
|
||||
* @param map - pointer to the multiword bitmap
|
||||
* @param bitno - memory size in bits to allocate
|
||||
*
|
||||
* @return 0 on success, -1 if can't allocate memory
|
||||
*/
|
||||
int init_bitmap(bitmap_t *bitmap, int nbits);
|
||||
|
||||
/*
|
||||
* Free memory taken by multiword bitmap
|
||||
*
|
||||
* @param bitmap - bitmap to free
|
||||
*/
|
||||
void free_bitmap(bitmap_t *map);
|
||||
|
||||
/**
|
||||
* Set bit number @a bit in the bitmap @a bitmap
|
||||
*
|
||||
* @param bitmap - A pointer to the bitmap
|
||||
* @param bit - Number of bit to set
|
||||
*/
|
||||
void bit_set_multi(bitmap_t *bitmap, int bitno);
|
||||
|
||||
/**
|
||||
* test bit of a multiword bitmap
|
||||
*
|
||||
* @param bitmap - A pointer to the bitmap
|
||||
* @param bitno - The number of bit to test
|
||||
*
|
||||
* @return value of the specified bit
|
||||
*/
|
||||
int bit_test_multi(bitmap_t *bitmap, int bitno);
|
||||
|
||||
/**
|
||||
* @brief Get old value of bit with number @a bitno and set @a bitno bit in the bitmap
|
||||
*
|
||||
* This function is similar to bit_set() except it copies old bit value before
|
||||
* setting it to 1 and return that value after needed bit was setted.
|
||||
*
|
||||
* @param bitmap - A pointer to the bitmap
|
||||
* @param bitno - The number of bit to test and set
|
||||
*
|
||||
* @return Old value of bit with number @a bitno or -1 if bitno is illegal
|
||||
*/
|
||||
int bit_test_and_set_multi(bitmap_t *bitmap, int bitno);
|
||||
|
||||
/**
|
||||
* @brief Get old value of bit with number @a bitno and clear @a bitno bit in the bitmap
|
||||
*
|
||||
* This function is similar to bit_set() except it copies old bit value before
|
||||
* setting it to 1 and return that value after needed bit was setted.
|
||||
*
|
||||
* @param bitmap - A pointer to the bitmap
|
||||
* @param bitno - The number of bit to test and set
|
||||
*
|
||||
* @return Old value of bit with number @a bitno or -1 if bitno is illegal
|
||||
*/
|
||||
int bit_test_and_reset_multi(bitmap_t *bitmap, int bitno);
|
||||
|
||||
|
||||
/**
|
||||
* Clear bit number @a bit in the bitmap @a bitmap
|
||||
*
|
||||
* @param bitmap - A pointer to the bitmap
|
||||
* @param bit - Number of bit to clear
|
||||
*/
|
||||
void bit_clear_multi(bitmap_t *bitmap, int bitno);
|
||||
|
||||
/*
|
||||
* Set multiple bits in the multiword bitmap
|
||||
*
|
||||
* @param bitmap - pointer to the multimap bitmap
|
||||
* @param start_bit - bit to set from
|
||||
* int end_bit - bit to set upto
|
||||
*/
|
||||
void bitrange_set_multi(bitmap_t *bitmap, int start_bit, int end_bit);
|
||||
|
||||
/*
|
||||
* Clear multiple bits in the multiword bitmap
|
||||
*
|
||||
* @param bitmap - pointer to the multimap bitmap
|
||||
* @param start_bit - bit to clear from
|
||||
* int end_bit - bit to clear upto
|
||||
*/
|
||||
void bitrange_clear_multi(bitmap_t *bitmap, int start_bit, int end_bit);
|
||||
|
||||
/**
|
||||
* Find most significant set bit in multimap word which from the 0 bit
|
||||
* upto @end_bit
|
||||
*
|
||||
* @param word - Where to search.
|
||||
* @param end_bit - most bit to search upto
|
||||
* @return Found bit number on success, negative value on failure.
|
||||
*/
|
||||
int bit_find_msf_multi(bitmap_t *bitmap, int mbit);
|
||||
|
||||
/**
|
||||
* Find first set least significant bit.
|
||||
*
|
||||
* @param word - Where to search
|
||||
* @param sbit - least bit to search from
|
||||
* @return Found bit number on success, negative value on failure.
|
||||
*/
|
||||
int bit_find_lsf_multi(bitmap_t *bitmap, int lbit);
|
||||
|
||||
#ifndef ARCH_BIT_TEST_AND_CLEAR
|
||||
static inline int bit_test_and_clear(void *bitmap, int bitno)
|
||||
{
|
||||
int val = bit_test(bitmap, bitno);
|
||||
bit_clear(bitmap, bitno);
|
||||
return val;
|
||||
}
|
||||
#else
|
||||
#define bit_test_and_clear(bitmap, bitno) arch_bit_test_and_clear(bitmap, bitno)
|
||||
#endif
|
||||
|
||||
#endif /* __BITWISE_H__ */
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* (c) Copyright 2006,2007,2008 MString Core Team <http://mstring.jarios.org>
|
||||
* (c) Copyright 2009 Dan Kruchinin <dan.kruchinin@gmail.com>
|
||||
* (c) Copyright 2009 Alfeiks Kaanoken <madtirra@jarios.org> (libc adaptation)
|
||||
* (c) Copyright 2009 Dmitry Gromada <gromada@jarios.org> (locking added)
|
||||
* (c) Copyright 2013 Alexander Vdolainen <vdo@askele.com> (verios changes to make it run on linux)
|
||||
*
|
||||
* (c) Copyright 2012 - 2013 Askele Oy <http://askele.com>
|
||||
*
|
||||
* Index allocator
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file include/libdata/idx_allocator.h
|
||||
* @brief Index allocator API and definitions
|
||||
*
|
||||
* Index allocator is a quite simple bitmaps based data
|
||||
* structure allowing to allocate non-negative integers
|
||||
* from an ordered continuous numbers set.
|
||||
* It may be useful for dynamic allocation of pids, uids and
|
||||
* other identifiers that must be unique.
|
||||
* Any identifier from a given set may be allocated, deallocated and reserved
|
||||
* (which prevents its allocation).
|
||||
* Note, there is no any sence to use index allocator for relatively
|
||||
* small(for example for sets containing less than 1024 items) identifier sets.
|
||||
* Allocator uses *at least* BYTES_PER_ITEM + sizeof(ulong_t) bytes for its internal bitmaps.
|
||||
*/
|
||||
|
||||
#ifndef __IDX_ALLOCATOR_H__
|
||||
#define __IDX_ALLOCATOR_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef unsigned long ulong_t;
|
||||
|
||||
#define BYTES_PER_ITEM 64 /**< Number of bytes per one entry of a second-level bitmap */
|
||||
#define WORDS_PER_ITEM (BYTES_PER_ITEM / sizeof(ulong_t)) /**< Number of machine words(ulong_t) per second-level bitmap item */
|
||||
#define IDX_INVAL ~0UL /**< Invalid index value */
|
||||
|
||||
#define ida_lock_init(lock) pthread_mutex_init(lock, NULL)
|
||||
#define ida_lock_destroy(lock) pthread_mutex_destroy(lock);
|
||||
#define ida_lock(a) pthread_mutex_lock(&a->lock)
|
||||
#define ida_unlock(a) pthread_mutex_unlock(&a->lock)
|
||||
#define ida_lockable(a) (a->lck)
|
||||
|
||||
typedef pthread_mutex_t ida_lock_t;
|
||||
|
||||
/**
|
||||
* @struct idx_allocator_t
|
||||
* @brief Index allocator structure
|
||||
*/
|
||||
typedef struct __idx_allocator {
|
||||
int size; /**< Total number of words used for second-level bitmap */
|
||||
ulong_t max_id; /**< Maximum index value(exclusive) */
|
||||
ulong_t *main_bmap; /**< First-level(main) bitmap that splits second-level bitmap on several parts */
|
||||
ulong_t *ids_bmap; /**< Second-level bitmap whose each bit corresponds to particular unique identifier */
|
||||
ida_lock_t lock;
|
||||
int lck;
|
||||
} idx_allocator_t;
|
||||
|
||||
#define idx_allocator_initialized(ida) (((idx_allocator_t*)(ida))->max_id)
|
||||
|
||||
/**
|
||||
* @brief Initialize an index allocator.
|
||||
* @param ida - A pointer to particular index allocator
|
||||
* @param idx_max - Maximum index value.
|
||||
* @lockable - flag to indicate the allocator must support locking itself
|
||||
*/
|
||||
int idx_allocator_init(idx_allocator_t *ida, ulong_t idx_max, int lockable);
|
||||
|
||||
/**
|
||||
* @brief Destroy index allocator.
|
||||
*
|
||||
* This function frees space used by allocator's internal
|
||||
* bitmaps. After it is called, allocator can not be used.
|
||||
*
|
||||
* @param ida - A pointer to praticular index allocator.
|
||||
*/
|
||||
void idx_allocator_destroy(idx_allocator_t *ida);
|
||||
|
||||
/**
|
||||
* @brief Allocate new index from an allocator's set.
|
||||
* @param ida - A pointer to target index allocator.
|
||||
* @return Valid index value on success, IDX_INVAL on error.
|
||||
* @see IDX_INVAL
|
||||
* @see idx_reserve
|
||||
* @see idx_free
|
||||
*/
|
||||
ulong_t idx_allocate(idx_allocator_t *ida);
|
||||
|
||||
/**
|
||||
* @brief Reserves particular index number.
|
||||
*
|
||||
* This action prevents named index number from
|
||||
* allocation. Index allocator skips reserved indices until
|
||||
* they are fried with idx_free
|
||||
*
|
||||
* @param ida - A pointer to particular index allocator.
|
||||
* @param idx - Number of index to reserve.
|
||||
* @see idx_free
|
||||
* @see idx_allocate
|
||||
*/
|
||||
void idx_reserve(idx_allocator_t *ida, ulong_t idx);
|
||||
|
||||
/**
|
||||
* @brief Free back index @a idx to named allocator @a ida.
|
||||
* @param ida - Allocator index will be freed back to.
|
||||
* @param idx - An index to free.
|
||||
* @see idx_allocate
|
||||
* @see idx_reserve
|
||||
*/
|
||||
void idx_free(idx_allocator_t *ida, ulong_t idx);
|
||||
|
||||
#endif /* __IDX_ALLOCATOR_H__ */
|
@ -0,0 +1,45 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* macro.h
|
||||
* Copyright (C) 2006-2013 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#ifndef __MACRO_H__
|
||||
#define __MACRO_H__
|
||||
|
||||
/*this macros just for better source code look and feel*/
|
||||
|
||||
#define left usrtc_left
|
||||
#define right usrtc_right
|
||||
#define parent usrtc_parent
|
||||
#define next usrtc_right
|
||||
#define prev usrtc_left
|
||||
#define data usrtc_data
|
||||
#define key usrtc_node_key
|
||||
#define rb_color usrtc_rb_color
|
||||
#define impl_specific usrtc_impldata
|
||||
|
||||
#define futable usrtc_futable
|
||||
#define nodecount usrtc_nodecount
|
||||
#define maxcount usrtc_maxcount
|
||||
#define dupes_allowed usrtc_dupes_allowed
|
||||
#define sentinel usrtc_sentinel
|
||||
#define compare usrtc_compare
|
||||
#define node_alloc usrtc_node_alloc
|
||||
#define node_free usrtc_node_free
|
||||
#define context usrtc_context
|
||||
|
||||
#endif /*__MACRO_H__*/
|
@ -0,0 +1,47 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* tree.h
|
||||
* Copyright (C) 2006-2013 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#ifndef __TREE_H__
|
||||
#define __TREE_H__
|
||||
|
||||
#include <tdata/usrtc.h>
|
||||
|
||||
#define tree_root_priv(T) ((T)->sentinel.left)
|
||||
#define tree_null_priv(L) (&(L)->sentinel)
|
||||
#define TREE_DEPTH_MAX 64
|
||||
|
||||
/*tree functions*/
|
||||
void usrtc_tree_init(usrtc_t *us);
|
||||
void usrtc_tree_insert(usrtc_t *us, usrtc_node_t *node, const void *key);
|
||||
void usrtc_tree_delete(usrtc_t *us, usrtc_node_t *node, usrtc_node_t **pswap,
|
||||
usrtc_node_t **pchild);
|
||||
usrtc_node_t *usrtc_tree_lookup(usrtc_t *us, const void *key);
|
||||
usrtc_node_t *usrtc_tree_lower_bound(usrtc_t *us, const void *key);
|
||||
usrtc_node_t *usrtc_tree_upper_bound(usrtc_t *us, const void *key);
|
||||
usrtc_node_t *usrtc_tree_first(usrtc_t *us);
|
||||
usrtc_node_t *usrtc_tree_last(usrtc_t *us);
|
||||
usrtc_node_t *usrtc_tree_next(usrtc_t *us, usrtc_node_t *curr);
|
||||
usrtc_node_t *usrtc_tree_prev(usrtc_t *us, usrtc_node_t *curr);
|
||||
void usrtc_tree_convert_to_list(usrtc_t *us);
|
||||
void usrtc_tree_convert_from_list(usrtc_t *us);
|
||||
void usrtc_tree_rotate_left(usrtc_node_t *child, usrtc_node_t *parent);
|
||||
void usrtc_tree_rotate_right(usrtc_node_t *child, usrtc_node_t *parent);
|
||||
|
||||
|
||||
#endif /*__TREE_H__*/
|
@ -0,0 +1,136 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* usrtc.h
|
||||
* Copyright (C) 2006-2013 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#ifndef __USRTC_H__
|
||||
#define __USRTC_H__
|
||||
|
||||
#define USRTC_COUNT_T_MAX ((1 << (sizeof(unsigned long)*(sizeof(char) << 1)))-1)
|
||||
|
||||
/*count and some misc typedefs*/
|
||||
typedef unsigned long usrtc_count_t;
|
||||
typedef unsigned int usrtc_impl_id_t;
|
||||
|
||||
/* implementations ids,
|
||||
* if you want to add some
|
||||
* add the id here, don't forget to do it.
|
||||
*/
|
||||
#define USRTC_LIST 0
|
||||
#define USRTC_BST 1
|
||||
#define USRTC_REDBLACK 2
|
||||
#define USRTC_SPLAY 3
|
||||
#define USRTC_AVL 4
|
||||
|
||||
typedef enum {
|
||||
usrtc_lst,
|
||||
usrtc_bst,
|
||||
usrtc_other
|
||||
} usrtc_impltype_t;
|
||||
|
||||
typedef enum {
|
||||
usrtc_red,
|
||||
usrtc_black
|
||||
} usrtc_rb_color_t;
|
||||
typedef enum {
|
||||
usrtc_balanced,
|
||||
usrtc_leftheavy,
|
||||
usrtc_rightheavy
|
||||
} usrtc_avl_balance_t;
|
||||
|
||||
/*used for the specific implementation features*/
|
||||
typedef union {
|
||||
int usrtc_dummy;
|
||||
usrtc_rb_color_t usrtc_rb_color;
|
||||
usrtc_avl_balance_t usrtc_avl_balance;
|
||||
} usrtc_impldata_t;
|
||||
|
||||
/*universal node*/
|
||||
typedef struct __usrtc_node_t {
|
||||
struct __usrtc_node_t *usrtc_left;
|
||||
struct __usrtc_node_t *usrtc_right;
|
||||
struct __usrtc_node_t *usrtc_parent;
|
||||
void *usrtc_data;
|
||||
const void *usrtc_node_key;
|
||||
usrtc_impldata_t usrtc_impldata;
|
||||
} usrtc_node_t;
|
||||
|
||||
typedef long (*usrtc_compare_t)(const void*, const void*);
|
||||
typedef usrtc_node_t *(*usrtc_node_alloc_t)(void *);
|
||||
typedef void (*usrtc_node_free_t)(void *, usrtc_node_t *);
|
||||
|
||||
typedef struct __usrtc_t {
|
||||
struct __usrtc_functions_t *usrtc_futable;
|
||||
usrtc_count_t usrtc_nodecount;
|
||||
usrtc_count_t usrtc_maxcount;
|
||||
int usrtc_dupes_allowed;
|
||||
usrtc_node_t usrtc_sentinel;
|
||||
usrtc_compare_t usrtc_compare;
|
||||
usrtc_node_alloc_t usrtc_node_alloc;
|
||||
usrtc_node_free_t usrtc_node_free;
|
||||
void *usrtc_context;
|
||||
} usrtc_t;
|
||||
|
||||
typedef struct __usrtc_functions_t {
|
||||
void (*usrtc_init)(usrtc_t *);
|
||||
void (*usrtc_insert)(usrtc_t *, usrtc_node_t *, const void *);
|
||||
void (*usrtc_delete)(usrtc_t *, usrtc_node_t *);
|
||||
usrtc_node_t *(*usrtc_lookup)(usrtc_t *, const void *);
|
||||
usrtc_node_t *(*usrtc_lower_bound)(usrtc_t *, const void *);
|
||||
usrtc_node_t *(*usrtc_upper_bound)(usrtc_t *, const void *);
|
||||
usrtc_node_t *(*usrtc_first)(usrtc_t *);
|
||||
usrtc_node_t *(*usrtc_last)(usrtc_t *);
|
||||
usrtc_node_t *(*usrtc_next)(usrtc_t *, usrtc_node_t *);
|
||||
usrtc_node_t *(*usrtc_prev)(usrtc_t *, usrtc_node_t *);
|
||||
void (*usrtc_convert_to_list)(usrtc_t *);
|
||||
void (*usrtc_convert_from_list)(usrtc_t *);
|
||||
usrtc_impltype_t usrtc_type;
|
||||
} usrtc_functions_t;
|
||||
|
||||
/*basic rtc functions*/
|
||||
void usrtc_init(usrtc_t *us,int impl,usrtc_count_t maxcount,usrtc_compare_t compare);
|
||||
usrtc_t *usrtc_create(int impl,usrtc_count_t maxcount,usrtc_compare_t compare);
|
||||
void usrtc_destroy(usrtc_t *us);
|
||||
void usrtc_convert_to(usrtc_t *us,int impl);
|
||||
usrtc_count_t usrtc_count(usrtc_t *us);
|
||||
int usrtc_isempty(usrtc_t *us);
|
||||
int usrtc_isfull(usrtc_t *us);
|
||||
int usrtc_alloc_insert(usrtc_t *us,const void *key,void *data);
|
||||
void usrtc_delete_free(usrtc_t *us,usrtc_node_t *node);
|
||||
void usrtc_set_allocator(usrtc_t *us,usrtc_node_alloc_t alloc,usrtc_node_free_t n_free,void *context);
|
||||
void usrtc_allow_dupes(usrtc_t *ud);
|
||||
|
||||
/*basic node functions*/
|
||||
void usrtc_node_init(usrtc_node_t *node,void *data);
|
||||
usrtc_node_t *usrtc_node_create(void *data);
|
||||
void usrtc_node_destroy(usrtc_node_t *node);
|
||||
void *usrtc_node_getdata(usrtc_node_t *node);
|
||||
void usrtc_node_setdata(usrtc_node_t *node,void *data);
|
||||
const void *usrtc_node_getkey(usrtc_node_t *node);
|
||||
|
||||
/*rtc wrappers for the specific data structure functions*/
|
||||
void usrtc_insert(usrtc_t *us,usrtc_node_t *node,const void *key);
|
||||
void usrtc_delete(usrtc_t *us,usrtc_node_t *node);
|
||||
usrtc_node_t *usrtc_lookup(usrtc_t *us,const void *key);
|
||||
usrtc_node_t *usrtc_lower_bound(usrtc_t *us,const void *key);
|
||||
usrtc_node_t *usrtc_upper_bound(usrtc_t *us,const void *key);
|
||||
usrtc_node_t *usrtc_first(usrtc_t *us);
|
||||
usrtc_node_t *usrtc_last(usrtc_t *us);
|
||||
usrtc_node_t *usrtc_next(usrtc_t *us,usrtc_node_t *node);
|
||||
usrtc_node_t *usrtc_prev(usrtc_t *us,usrtc_node_t *node);
|
||||
|
||||
#endif /*__USRTC_H__*/
|
@ -0,0 +1,33 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
|
||||
-DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
|
||||
-DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \
|
||||
$(LIBTDATA_CFLAGS) -I../include
|
||||
|
||||
AM_CFLAGS =\
|
||||
-Wall\
|
||||
-g
|
||||
|
||||
lib_LTLIBRARIES = libtdata.la
|
||||
|
||||
|
||||
libtdata_la_SOURCES = \
|
||||
avl.c lslist.c redblack.c splay.c \
|
||||
tree.c usrtc.c bitwise.c idx_allocator.c
|
||||
|
||||
libtdata_la_LDFLAGS =
|
||||
|
||||
libtdata_la_LIBADD =
|
||||
|
||||
##include_HEADERS = \
|
||||
## ../include/tdata/macro.h ../include/tdata/tree.h ../include/tdata/usrtc.h \
|
||||
## ../include/tdata/bitwise.h ../include/tdata/idx_allocator.h
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libtdata-0.2.pc
|
||||
|
||||
EXTRA_DIST = \
|
||||
libtdata-0.2.pc.in
|
||||
|
@ -0,0 +1,327 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* avl.c
|
||||
* Copyright (C) 2006-2013, 2014 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#include <tdata/usrtc.h>
|
||||
#include <tdata/macro.h>
|
||||
#include <tdata/tree.h>
|
||||
|
||||
#define balance usrtc_impldata.usrtc_avl_balance
|
||||
#define BALANCED usrtc_balanced
|
||||
#define LEFTHEAVY usrtc_leftheavy
|
||||
#define RIGHTHEAVY usrtc_rightheavy
|
||||
|
||||
/*local functions prototypes*/
|
||||
static void avl_init(usrtc_t *);
|
||||
static void avl_insert(usrtc_t *,usrtc_node_t *,const void *);
|
||||
static void avl_delete(usrtc_t *,usrtc_node_t *);
|
||||
static void avl_convert_from_list(usrtc_t *);
|
||||
|
||||
usrtc_functions_t usrtc_avl_fu = {
|
||||
avl_init,
|
||||
avl_insert,
|
||||
avl_delete,
|
||||
usrtc_tree_lookup,
|
||||
usrtc_tree_lower_bound,
|
||||
usrtc_tree_upper_bound,
|
||||
usrtc_tree_first,
|
||||
usrtc_tree_last,
|
||||
usrtc_tree_next,
|
||||
usrtc_tree_prev,
|
||||
usrtc_tree_convert_to_list,
|
||||
avl_convert_from_list,
|
||||
usrtc_bst
|
||||
};
|
||||
|
||||
/*internal use*/
|
||||
static void rotate_left(usrtc_node_t **);
|
||||
static void rotate_right(usrtc_node_t **);
|
||||
static void fix_balance(usrtc_node_t **,usrtc_avl_balance_t );
|
||||
static int insert(usrtc_t *,usrtc_node_t *,usrtc_node_t **,usrtc_node_t *);
|
||||
static usrtc_node_t *make_tree(usrtc_node_t **,usrtc_count_t ,int *,usrtc_node_t *);
|
||||
|
||||
/*implementation*/
|
||||
static void avl_init(usrtc_t *us)
|
||||
{
|
||||
usrtc_tree_init(us);
|
||||
us->sentinel.balance=BALANCED;
|
||||
}
|
||||
|
||||
static void avl_insert(usrtc_t *us,usrtc_node_t *node,const void *key)
|
||||
{
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
|
||||
node->key=key;
|
||||
node->left=nil;
|
||||
node->right=nil;
|
||||
node->balance=BALANCED;
|
||||
|
||||
if(insert(us,node,&nil->left,nil)) {
|
||||
nil->balance=LEFTHEAVY;
|
||||
}
|
||||
|
||||
us->nodecount++;
|
||||
}
|
||||
|
||||
static void avl_delete(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *swap;
|
||||
usrtc_node_t *child;
|
||||
usrtc_node_t *parent;
|
||||
|
||||
/*basic deletion*/
|
||||
usrtc_tree_delete(us,node,&swap,&child);
|
||||
|
||||
/*implementation specific*/
|
||||
swap->balance=node->balance;
|
||||
parent=child->parent;
|
||||
|
||||
if(parent==nil) {
|
||||
if(child==nil) {
|
||||
parent->balance=BALANCED;
|
||||
}
|
||||
}
|
||||
|
||||
while(parent!=nil) {
|
||||
if((parent->left==nil) && (parent->right==nil)) {
|
||||
if(child!=nil)
|
||||
return;
|
||||
if(parent==BALANCED)
|
||||
return;
|
||||
parent->balance=BALANCED;
|
||||
}
|
||||
else {
|
||||
usrtc_node_t **pparent;
|
||||
if(parent==parent->parent->left)
|
||||
pparent=&parent->parent->left;
|
||||
else
|
||||
pparent=&parent->parent->right;
|
||||
|
||||
if(child==parent->left)
|
||||
fix_balance(pparent,RIGHTHEAVY);
|
||||
else {
|
||||
if(child!=parent->right)
|
||||
return;
|
||||
|
||||
fix_balance(pparent,LEFTHEAVY);
|
||||
}
|
||||
|
||||
parent=*pparent;
|
||||
}
|
||||
|
||||
if(parent->balance==BALANCED) {
|
||||
child=parent;
|
||||
parent=child->parent;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void avl_convert_from_list(usrtc_t *us)
|
||||
{
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *root;
|
||||
int height;
|
||||
|
||||
if(us->nodecount==0) {
|
||||
nil->balance=BALANCED;
|
||||
return;
|
||||
}
|
||||
|
||||
root=make_tree(&nil->next,us->nodecount,&height,nil);
|
||||
|
||||
if(nil->next!=nil)
|
||||
return;
|
||||
|
||||
nil->left=root;
|
||||
root->parent=nil;
|
||||
nil->balance=LEFTHEAVY;
|
||||
}
|
||||
|
||||
/*---*/
|
||||
static void rotate_left(usrtc_node_t **top)
|
||||
{
|
||||
usrtc_node_t *parent=*top;
|
||||
usrtc_node_t *child=parent->right;
|
||||
|
||||
child->parent=parent->parent;
|
||||
parent->right=child->left;
|
||||
parent->right->parent=parent;
|
||||
child->left=parent;
|
||||
parent->parent=child;
|
||||
*top=child;
|
||||
}
|
||||
|
||||
static void rotate_right(usrtc_node_t **top)
|
||||
{
|
||||
usrtc_node_t *parent=*top;
|
||||
usrtc_node_t *child=parent->left;
|
||||
|
||||
child->parent=parent->parent;
|
||||
parent->left=child->right;
|
||||
parent->left->parent=parent;
|
||||
child->right=parent;
|
||||
parent->parent=child;
|
||||
*top=child;
|
||||
}
|
||||
|
||||
static void fix_balance(usrtc_node_t **pnode,usrtc_avl_balance_t bal)
|
||||
{
|
||||
usrtc_node_t *node=*pnode;
|
||||
usrtc_node_t *child;
|
||||
usrtc_node_t *grandchild;
|
||||
|
||||
if(node->balance==BALANCED)
|
||||
node->balance=bal;
|
||||
else if(node->balance!=bal)
|
||||
node->balance=BALANCED;
|
||||
else {
|
||||
if(node->balance!=bal)
|
||||
return;
|
||||
|
||||
if(bal==LEFTHEAVY) {
|
||||
child=node->left;
|
||||
if(child->balance==LEFTHEAVY) {
|
||||
node->balance=BALANCED;
|
||||
child->balance=BALANCED;
|
||||
rotate_right(pnode);
|
||||
}
|
||||
else if(child->balance==BALANCED) {
|
||||
node->balance=LEFTHEAVY;
|
||||
child->balance=RIGHTHEAVY;
|
||||
rotate_right(pnode);
|
||||
}
|
||||
else {
|
||||
grandchild=child->right;
|
||||
if(grandchild->balance==LEFTHEAVY) {
|
||||
node->balance=RIGHTHEAVY;
|
||||
child->balance=BALANCED;
|
||||
}
|
||||
else if(grandchild->balance==RIGHTHEAVY) {
|
||||
node->balance=BALANCED;
|
||||
child->balance=LEFTHEAVY;
|
||||
}
|
||||
else {
|
||||
node->balance=BALANCED;
|
||||
child->balance=BALANCED;
|
||||
}
|
||||
grandchild->balance=BALANCED;
|
||||
rotate_left(&node->left);
|
||||
rotate_right(pnode);
|
||||
}
|
||||
}
|
||||
else {
|
||||
child=node->right;
|
||||
if(child->balance==RIGHTHEAVY) {
|
||||
node->balance=BALANCED;
|
||||
child->balance=BALANCED;
|
||||
rotate_left(pnode);
|
||||
}
|
||||
else if(child->balance==BALANCED) {
|
||||
node->balance=RIGHTHEAVY;
|
||||
child->balance=LEFTHEAVY;
|
||||
rotate_left(pnode);
|
||||
}
|
||||
else {
|
||||
grandchild=child->left;
|
||||
if(grandchild->balance==RIGHTHEAVY) {
|
||||
node->balance=LEFTHEAVY;
|
||||
child->balance=BALANCED;
|
||||
}
|
||||
else if(grandchild->balance==LEFTHEAVY) {
|
||||
node->balance=BALANCED;
|
||||
child->balance=RIGHTHEAVY;
|
||||
}
|
||||
else {
|
||||
node->balance=BALANCED;
|
||||
child->balance=BALANCED;
|
||||
}
|
||||
grandchild->balance=BALANCED;
|
||||
rotate_right(&node->right);
|
||||
rotate_left(pnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int insert(usrtc_t *us,usrtc_node_t *what,usrtc_node_t **where,usrtc_node_t *parent)
|
||||
{
|
||||
usrtc_node_t *here=*where;
|
||||
int result;
|
||||
|
||||
if(here==tree_null_priv(us)) {
|
||||
*where=what;
|
||||
what->parent=parent;
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
result=us->compare(what->key,here->key);
|
||||
|
||||
if(result < 0) {
|
||||
if(insert(us,what,&here->left,here)) {
|
||||
fix_balance(where,LEFTHEAVY);
|
||||
return ((*where)->balance!=BALANCED);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(insert(us,what,&here->right,here)) {
|
||||
fix_balance(where,RIGHTHEAVY);
|
||||
return ((*where)->balance!=BALANCED);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static usrtc_node_t *make_tree(usrtc_node_t **pnode,usrtc_count_t count,
|
||||
int *pheight,usrtc_node_t *nil)
|
||||
{
|
||||
usrtc_count_t leftcount;
|
||||
int leftheight, rightheight;
|
||||
usrtc_node_t *root;
|
||||
usrtc_node_t *leftroot;
|
||||
|
||||
if(count==0) {
|
||||
*pheight=0;
|
||||
return nil;
|
||||
}
|
||||
|
||||
leftcount=(count-1)/2;
|
||||
leftroot=make_tree(pnode,leftcount,&leftheight,nil);
|
||||
count-=leftcount;
|
||||
|
||||
root=*pnode;
|
||||
*pnode=root->next;
|
||||
--count;
|
||||
|
||||
root->left=leftroot;
|
||||
leftroot->parent=root;
|
||||
root->right=make_tree(pnode,count,&rightheight,nil);
|
||||
root->right->parent=root;
|
||||
|
||||
if(leftheight>rightheight)
|
||||
return (void *)0;
|
||||
|
||||
*pheight=rightheight+1;
|
||||
root->balance=(leftheight==rightheight) ? BALANCED : RIGHTHEAVY;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*
|
||||
* (c) Copyright 2006,2007,2008 Jari OS Core Team <http://jarios.org>
|
||||
* (c) Copyright 2008 Dmitry Gromada <gromada82@gmail.com>
|
||||
* (c) Copyright 2010 Alexander Vdolainen <vdo@askele.com>
|
||||
*
|
||||
* (c) Copyright 2012 - 2013, 2014 Askele Oy <http://askele.com>
|
||||
*
|
||||
* Implements bitwise operations with multiword bitmaps
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tdata/bitwise.h>
|
||||
|
||||
/* operation equivalent to division modulo number of power 2 */
|
||||
#define MOD_POW2(var, pow) ((var) & ((pow) - 1))
|
||||
|
||||
int init_bitmap(bitmap_t *bitmap, int nbits)
|
||||
{
|
||||
int ret = 0;
|
||||
int size = nbits >> TYPE_LONG_SHIFT;
|
||||
|
||||
if (nbits < 0)
|
||||
return -1;
|
||||
|
||||
if (size << TYPE_LONG_SHIFT != nbits)
|
||||
size++;
|
||||
|
||||
bitmap->map = (unsigned long*)malloc(size * sizeof(unsigned long));
|
||||
if (bitmap->map == NULL)
|
||||
ret = -1;
|
||||
else
|
||||
bitmap->nwords = size;
|
||||
|
||||
memset(bitmap->map, 0, size * sizeof(unsigned long));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void free_bitmap(bitmap_t *bitmap)
|
||||
{
|
||||
if (bitmap->map) {
|
||||
free(bitmap->map);
|
||||
bitmap->map = NULL;
|
||||
}
|
||||
bitmap->nwords = 0;
|
||||
}
|
||||
|
||||
|
||||
void bit_set_multi(bitmap_t *bitmap, int bitno)
|
||||
{
|
||||
int i = bitno >> TYPE_LONG_SHIFT;
|
||||
|
||||
return bit_set( bitmap->map + i, MOD_POW2(bitno, BITS_PER_LONG) );
|
||||
}
|
||||
|
||||
int bit_test_and_set_multi(bitmap_t *bitmap, int bitno)
|
||||
{
|
||||
int i = bitno >> TYPE_LONG_SHIFT;
|
||||
|
||||
return bit_test_and_set( bitmap->map + i, MOD_POW2(bitno, BITS_PER_LONG) );
|
||||
}
|
||||
|
||||
int bit_test_and_reset_multi(bitmap_t *bitmap, int bitno)
|
||||
{
|
||||
int i = bitno >> TYPE_LONG_SHIFT;
|
||||
|
||||
return bit_test_and_reset( bitmap->map + i, MOD_POW2(bitno, BITS_PER_LONG) );
|
||||
}
|
||||
|
||||
void bit_clear_multi(bitmap_t *bitmap, int bitno)
|
||||
{
|
||||
int i = bitno >> TYPE_LONG_SHIFT;
|
||||
|
||||
return bit_clear( bitmap->map + i, MOD_POW2(bitno, BITS_PER_LONG) );
|
||||
}
|
||||
|
||||
int bit_find_msf_multi(bitmap_t *bitmap, int mbit)
|
||||
{
|
||||
int i, r;
|
||||
unsigned long word;
|
||||
|
||||
if (mbit < 0)
|
||||
return -1;
|
||||
else if (mbit >= bitmap->nwords * BITS_PER_LONG)
|
||||
mbit = bitmap->nwords * BITS_PER_LONG - 1;
|
||||
|
||||
i = mbit >> TYPE_LONG_SHIFT;
|
||||
word = bitmap->map[i] & (~0UL >> ( BITS_PER_LONG - 1 - MOD_POW2(mbit, BITS_PER_LONG) ));
|
||||
r = bit_find_msf(word);
|
||||
|
||||
while ((r == -1) && (--i >= 0)) {
|
||||
if (bitmap->map[i])
|
||||
r = bit_find_msf(bitmap->map[i]);
|
||||
}
|
||||
|
||||
r = (r == -1) ? r : (i * BITS_PER_LONG + r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int bit_find_lsf_multi(bitmap_t *bitmap, int lbit)
|
||||
{
|
||||
int i, r;
|
||||
unsigned long word;
|
||||
|
||||
if (lbit >= bitmap->nwords * BITS_PER_LONG)
|
||||
return -1;
|
||||
else if (lbit < 0)
|
||||
lbit = 0;
|
||||
|
||||
i = lbit >> TYPE_LONG_SHIFT;
|
||||
word = bitmap->map[i] & (~0UL << MOD_POW2(lbit, BITS_PER_LONG));
|
||||
r = bit_find_lsf(word);
|
||||
|
||||
while ((r == -1) && (++i < bitmap->nwords)) {
|
||||
if (bitmap->map[i])
|
||||
r = bit_find_lsf(bitmap->map[i]);
|
||||
}
|
||||
|
||||
r = (r == -1) ? r : (i * BITS_PER_LONG + r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int bit_test_multi(bitmap_t *bitmap, int bitno)
|
||||
{
|
||||
int i = bitno >> TYPE_LONG_SHIFT;
|
||||
|
||||
return bit_test( bitmap->map + i, MOD_POW2(bitno, BITS_PER_LONG) );
|
||||
}
|
||||
|
||||
void bitrange_set_multi(bitmap_t *bitmap, int start_bit, int end_bit)
|
||||
{
|
||||
int i1, i2;
|
||||
unsigned long mask1, mask2, *p = bitmap->map;
|
||||
|
||||
if (start_bit > end_bit)
|
||||
return;
|
||||
|
||||
i1 = start_bit >> TYPE_LONG_SHIFT;
|
||||
mask1 = ~0UL << MOD_POW2(start_bit, BITS_PER_LONG);
|
||||
|
||||
i2 = end_bit >> TYPE_LONG_SHIFT;
|
||||
mask2 = ~0UL >> (BITS_PER_LONG - 1 - MOD_POW2(end_bit, BITS_PER_LONG));
|
||||
|
||||
if (i1 == i2)
|
||||
p[i1] |= mask1 & mask2;
|
||||
else {
|
||||
p[i1++] |= mask1;
|
||||
|
||||
if (i2 - i1 > 0)
|
||||
memset( p + i1, 0xFF, (i2 - i1) * sizeof(unsigned long) );
|
||||
|
||||
p[i2] |= mask2;
|
||||
}
|
||||
}
|
||||
|
||||
void bitrange_clear_multi(bitmap_t *bitmap, int start_bit, int end_bit)
|
||||
{
|
||||
int i1, i2;
|
||||
unsigned long mask1, mask2, *p = bitmap->map;
|
||||
|
||||
if (start_bit > end_bit)
|
||||
return;
|
||||
|
||||
i1 = start_bit >> TYPE_LONG_SHIFT;
|
||||
mask1 = ( 1UL << (start_bit & MOD_POW2(start_bit, BITS_PER_LONG)) ) - 1;
|
||||
|
||||
i2 = end_bit >> TYPE_LONG_SHIFT;
|
||||
mask2 = ~0UL << (MOD_POW2(end_bit, BITS_PER_LONG) + 1);
|
||||
|
||||
if (i1 == i2)
|
||||
p[i1] &= mask1 | mask2;
|
||||
else {
|
||||
p[i1++] &= mask1;
|
||||
|
||||
if (i2 - i1 > 0)
|
||||
memset(p + i1, 0, (i2 - i1) * sizeof(unsigned long));
|
||||
|
||||
p[i2] &= mask2;
|
||||
}
|
||||
}
|
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of
|
||||
* the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* (c) Copyright 2006,2007,2008 MString Core Team <http://mstring.jarios.org>
|
||||
* (c) Copyright 2009 Dan Kruchinin <dan.kruchinin@gmail.com>
|
||||
* (c) Copyright 2009 Alexander Vdolainen <madtirra@jarios.org> (libc adaptation)
|
||||
* (c) Copyright 2009 Dmitry Gromada <gromada@jarios.org> (locking added)
|
||||
* (c) Copyright 2013 Alexander Vdolainen <vdo@askele.com> (verios changes to make it run on linux)
|
||||
*
|
||||
* (c) Copyright 2012 - 2013, 2014 Askele Oy <http://askele.com>
|
||||
*
|
||||
* Index allocator
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <tdata/bitwise.h>
|
||||
#include <tdata/idx_allocator.h>
|
||||
|
||||
/*
|
||||
* Main idea of index allocator is quite simple:
|
||||
* There is a group of tasks that requires dynamic allocation
|
||||
* of unique non-negative integer identifiers. Where a set of such
|
||||
* integers is relatively big (thousands of numbers), index allocator
|
||||
* becomes a nifty solution.
|
||||
* The core of allocator is two bitmaps. One of them called "indices bitmap"
|
||||
* or "second level bitmap". Each bit of that bitmap corresponds to particular unique
|
||||
* index. Since second-level bitmap is a large portion of continuous memory, searching
|
||||
* of set/zero bit in it becomes relatively slow. For speeding-up search process we invented
|
||||
* a first-level bitmap. Second-level array is splitted on groups each of them contains BYTES_PER_ITEM bytes.
|
||||
* First-level(or main) bitmap establishes corresponding between particular group and its
|
||||
* state(group may have free indices or not).
|
||||
* So index allocation assumes at first searching of group index in a the first-level bitmap and only
|
||||
* then searching an index in the second level bitmap starting from a group index.
|
||||
*/
|
||||
|
||||
#define MIN_IDA_SIZE (WORDS_PER_ITEM * sizeof(ulong_t))
|
||||
#define MAX_UNLOCKED_ATTEMPTS 3
|
||||
|
||||
/* there macros defined only on new glibc (from 12-jul-2013), let's use our own */
|
||||
#ifndef is_powerof2
|
||||
#define is_powerof2(num) (((num) & ~((num) - 1)) == (num))
|
||||
#endif
|
||||
#ifndef round_up_pow2
|
||||
#define round_up_pow2(x) (!is_powerof2(x) ? (1 << (bit_find_msf(x) + 1)) : (x) )
|
||||
#endif
|
||||
|
||||
static inline size_t __get_main_bmap_size(idx_allocator_t *ida)
|
||||
{
|
||||
if (ida->ids_bmap != NULL)
|
||||
return (round_up_pow2((ida->size * sizeof(ulong_t)) / BYTES_PER_ITEM));
|
||||
|
||||
return ida->size;
|
||||
}
|
||||
|
||||
ulong_t idx_allocate(idx_allocator_t *ida)
|
||||
{
|
||||
ulong_t id = IDX_INVAL;
|
||||
long fnfi = 0;
|
||||
size_t i, main_offs = 0, main_sz;
|
||||
int natm = 0; /* attempt number */
|
||||
|
||||
main_sz = __get_main_bmap_size(ida) / sizeof(ulong_t);
|
||||
i = 0;
|
||||
|
||||
if (ida->ids_bmap != NULL) {
|
||||
for (;;) {
|
||||
while (i < main_sz) {
|
||||
fnfi = zero_bit_find_lsf(ida->main_bmap[i]);
|
||||
if (fnfi >= 0) {
|
||||
fnfi = (fnfi * WORDS_PER_ITEM) + i * WORDS_PER_ITEM * BITS_PER_LONG;
|
||||
main_offs = i;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
if ((fnfi >= 0) && (fnfi < ida->size)) {
|
||||
int res_id, j, total_sz;
|
||||
|
||||
total_sz = fnfi + WORDS_PER_ITEM;
|
||||
j = fnfi;
|
||||
while (j < total_sz) {
|
||||
res_id = zero_bit_find_lsf(ida->ids_bmap[j]);
|
||||
if (res_id < 0) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ida_lockable(ida) /*&& atomic_test_and_set_bit(ida->ids_bmap + j, res_id)*/) {
|
||||
natm++;
|
||||
if (natm == MAX_UNLOCKED_ATTEMPTS)
|
||||
ida_lock(ida);
|
||||
} else {
|
||||
bit_set(ida->ids_bmap + j, res_id);
|
||||
}
|
||||
|
||||
id = res_id + j * BITS_PER_LONG;
|
||||
if (id >= ida->max_id) {
|
||||
bit_clear(ida->ids_bmap + j, res_id);
|
||||
id = IDX_INVAL;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
bit_set(ida->main_bmap + main_offs,
|
||||
(fnfi - (main_offs * WORDS_PER_ITEM * BITS_PER_LONG)) / WORDS_PER_ITEM);
|
||||
if ((ida->main_bmap[i] & ~0UL) == ~0UL)
|
||||
i++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (i < main_sz) {
|
||||
fnfi = zero_bit_find_lsf(ida->main_bmap[i]);
|
||||
if (fnfi >= 0) {
|
||||
bit_set(ida->main_bmap + i, fnfi);
|
||||
id = fnfi + i * BITS_PER_LONG;
|
||||
if (id >= ida->max_id) {
|
||||
bit_clear(ida->main_bmap + i, fnfi);
|
||||
id = IDX_INVAL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (natm == MAX_UNLOCKED_ATTEMPTS)
|
||||
ida_unlock(ida);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void idx_reserve(idx_allocator_t *ida, ulong_t idx)
|
||||
{
|
||||
int start_id, bitno;
|
||||
ulong_t *ptr;
|
||||
|
||||
start_id = idx / BITS_PER_LONG;
|
||||
bitno = idx - start_id * BITS_PER_LONG;
|
||||
if (ida->ids_bmap != NULL)
|
||||
ptr = ida->ids_bmap + start_id;
|
||||
else
|
||||
ptr = ida->main_bmap + start_id;
|
||||
|
||||
if (bit_test_and_set(ptr, bitno)) {
|
||||
printf("[libc warning] Detected an attempt to reserve already busy index %ld "
|
||||
"[function: %s]!\n", idx, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
void idx_free(idx_allocator_t *ida, ulong_t idx)
|
||||
{
|
||||
int start_id, bitno, main_id, main_bitno;
|
||||
ulong_t *ptr;
|
||||
|
||||
start_id = idx / BITS_PER_LONG;
|
||||
bitno = idx - start_id * BITS_PER_LONG;
|
||||
if (ida->ids_bmap != NULL) {
|
||||
ptr = ida->ids_bmap + start_id;
|
||||
main_id = start_id / WORDS_PER_ITEM;
|
||||
main_bitno = start_id - main_id * WORDS_PER_ITEM;
|
||||
bit_clear(ida->main_bmap + main_id, main_bitno);
|
||||
}
|
||||
else
|
||||
ptr = ida->main_bmap + start_id;
|
||||
|
||||
if (!bit_test_and_clear(ptr, bitno)) {
|
||||
printf("[libc warning] Detected an attempt to free already fried index %ld "
|
||||
"[function: %s]!\n", idx, __FUNCTION__);
|
||||
}
|
||||
}
|
||||
|
||||
int idx_allocator_init(idx_allocator_t *ida, ulong_t idx_max, int lockable)
|
||||
{
|
||||
size_t bmap_sz;
|
||||
int err = -ENOMEM;
|
||||
|
||||
bmap_sz = (round_up_pow2(idx_max) >> 3);
|
||||
memset(ida, 0, sizeof(*ida));
|
||||
ida->size = bmap_sz / sizeof(ulong_t);
|
||||
if (ida->size >= MIN_IDA_SIZE) {
|
||||
ida->ids_bmap = malloc(bmap_sz);
|
||||
if (!ida->ids_bmap) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
memset(ida->ids_bmap, 0, bmap_sz);
|
||||
}
|
||||
else
|
||||
ida->size = (ida->size > 0) ? (ida->size * sizeof(ulong_t)) : sizeof(ulong_t);
|
||||
|
||||
ida->main_bmap = malloc(__get_main_bmap_size(ida));
|
||||
if (!ida->main_bmap) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (lockable && ida_lock_init(&ida->lock))
|
||||
goto error;
|
||||
#endif
|
||||
ida->lck = 0; /* cutty, we don't use the lockable due to the very arch specifics */
|
||||
|
||||
memset(ida->main_bmap, 0, __get_main_bmap_size(ida));
|
||||
ida->max_id = idx_max;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (ida->ids_bmap) {
|
||||
free(ida->ids_bmap);
|
||||
}
|
||||
if (ida->main_bmap) {
|
||||
free(ida->main_bmap);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void idx_allocator_destroy(idx_allocator_t *ida)
|
||||
{
|
||||
if (ida->ids_bmap != NULL)
|
||||
free(ida->ids_bmap);
|
||||
|
||||
free(ida->main_bmap);
|
||||
|
||||
if (ida_lockable(ida))
|
||||
ida_lock_destroy(&ida->lock);
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
datarootdir=@datarootdir@
|
||||
datadir=@datadir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: liblibtdata
|
||||
Description: Data structures used in a variety of Askele and Askele Ingria products (so called usrtc).
|
||||
Version: @VERSION@
|
||||
Requires:
|
||||
Libs: -L${libdir} -llibtdata
|
||||
Cflags: -I${includedir}
|
@ -0,0 +1,173 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* lslist.c
|
||||
* Copyright (C) 2006-2013, 2014 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <tdata/macro.h>
|
||||
#include <tdata/usrtc.h>
|
||||
|
||||
#define list_first_priv(L) ((L)->sentinel.next)
|
||||
#define list_last_priv(L) ((L)->sentinel.prev)
|
||||
#define list_null_priv(L) (&(L)->sentinel)
|
||||
|
||||
/*function prototypes*/
|
||||
static void list_init(usrtc_t *);
|
||||
static void list_insert(usrtc_t *,usrtc_node_t *,const void *);
|
||||
static void list_delete(usrtc_t *,usrtc_node_t *);
|
||||
static usrtc_node_t *list_lookup(usrtc_t *,const void *);
|
||||
static usrtc_node_t *list_lower_bound(usrtc_t *,const void *);
|
||||
static usrtc_node_t *list_upper_bound(usrtc_t *,const void *);
|
||||
static usrtc_node_t *list_first(usrtc_t *);
|
||||
static usrtc_node_t *list_last(usrtc_t *);
|
||||
static usrtc_node_t *list_next(usrtc_t *, usrtc_node_t *);
|
||||
static usrtc_node_t *list_prev(usrtc_t *, usrtc_node_t *);
|
||||
static void list_convert_to_list(usrtc_t *);
|
||||
static void list_convert_from_list(usrtc_t *);
|
||||
|
||||
usrtc_functions_t usrtc_list_fu = {
|
||||
list_init,
|
||||
list_insert,
|
||||
list_delete,
|
||||
list_lookup,
|
||||
list_lower_bound,
|
||||
list_upper_bound,
|
||||
list_first,
|
||||
list_last,
|
||||
list_next,
|
||||
list_prev,
|
||||
list_convert_to_list,
|
||||
list_convert_from_list,
|
||||
usrtc_lst
|
||||
};
|
||||
|
||||
static void insert_before(usrtc_t *,usrtc_node_t *,usrtc_node_t *);
|
||||
|
||||
/*implementation*/
|
||||
static void list_init(usrtc_t *us)
|
||||
{
|
||||
us->sentinel.next=&us->sentinel;
|
||||
us->sentinel.prev=&us->sentinel;
|
||||
}
|
||||
|
||||
static void list_insert(usrtc_t *us,usrtc_node_t *newnode,const void *key)
|
||||
{
|
||||
usrtc_node_t *succ;
|
||||
|
||||
newnode->key=key;
|
||||
|
||||
for(succ=list_first_priv(us);succ!=list_null_priv(us);succ=succ->next) {
|
||||
if(us->compare(succ->key,key)>0)
|
||||
break;
|
||||
}
|
||||
|
||||
insert_before(us,newnode,succ);
|
||||
}
|
||||
|
||||
static void list_delete(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
usrtc_node_t *pred=node->prev;
|
||||
usrtc_node_t *succ=node->next;
|
||||
|
||||
pred->next=succ;
|
||||
succ->prev=pred;
|
||||
/*check node count*/
|
||||
us->nodecount--;
|
||||
}
|
||||
|
||||
static usrtc_node_t *list_lookup(usrtc_t *us,const void *key)
|
||||
{
|
||||
usrtc_node_t *node;
|
||||
|
||||
for(node=list_first_priv(us);node!=list_null_priv(us);node=node->next) {
|
||||
if(us->compare(node->key,key)==0)
|
||||
return node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static usrtc_node_t *list_lower_bound(usrtc_t *us,const void *key)
|
||||
{
|
||||
usrtc_node_t *node;
|
||||
|
||||
for(node=list_first_priv(us);node!=list_null_priv(us);node=node->next) {
|
||||
if(us->compare(node->key,key) >= 0)
|
||||
return node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static usrtc_node_t *list_upper_bound(usrtc_t *us,const void *key)
|
||||
{
|
||||
usrtc_node_t *node;
|
||||
|
||||
for(node=list_first_priv(us);node!=list_null_priv(us);node=node->prev) {
|
||||
if(us->compare(node->key,key) >= 0)
|
||||
return node;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static usrtc_node_t *list_first(usrtc_t *us)
|
||||
{
|
||||
return (list_first_priv(us) == list_null_priv(us)) ? 0 : list_first_priv(us);
|
||||
}
|
||||
|
||||
static usrtc_node_t *list_last(usrtc_t *us)
|
||||
{
|
||||
return (list_last_priv(us) == list_null_priv(us)) ? 0 : list_last_priv(us);
|
||||
}
|
||||
|
||||
static usrtc_node_t *list_next(usrtc_t *us, usrtc_node_t *node)
|
||||
{
|
||||
return (node->next == list_null_priv(us)) ? 0 : node->next;
|
||||
}
|
||||
|
||||
static usrtc_node_t *list_prev(usrtc_t *us, usrtc_node_t *node)
|
||||
{
|
||||
return (node->prev == list_null_priv(us)) ? 0 : node->prev;
|
||||
}
|
||||
|
||||
static void list_convert_to_list(usrtc_t *us)
|
||||
{
|
||||
/*dummy*/
|
||||
}
|
||||
|
||||
static void list_convert_from_list(usrtc_t *us)
|
||||
{
|
||||
/*dummy*/
|
||||
}
|
||||
|
||||
/*internal function*/
|
||||
static void insert_before(usrtc_t *us,usrtc_node_t *newnode,usrtc_node_t *succ)
|
||||
{
|
||||
usrtc_node_t *pred=succ->prev;
|
||||
|
||||
newnode->prev=pred;
|
||||
newnode->next=succ;
|
||||
|
||||
pred->next=newnode;
|
||||
succ->prev=newnode;
|
||||
|
||||
/*TODO: check for maxcount*/
|
||||
us->nodecount++;
|
||||
}
|
||||
|
@ -0,0 +1,309 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* redblack.c
|
||||
* Copyright (C) 2006-2013, 2014 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <tdata/usrtc.h>
|
||||
#include <tdata/macro.h>
|
||||
#include <tdata/tree.h>
|
||||
|
||||
#define color usrtc_impldata.usrtc_rb_color
|
||||
|
||||
/*function prototypes*/
|
||||
static void redblack_init(usrtc_t *);
|
||||
static void redblack_insert(usrtc_t *, usrtc_node_t *, const void *);
|
||||
static void redblack_delete(usrtc_t *, usrtc_node_t *);
|
||||
static void redblack_convert_from_list(usrtc_t *);
|
||||
|
||||
usrtc_functions_t usrtc_redblack_fu = {
|
||||
redblack_init,
|
||||
redblack_insert,
|
||||
redblack_delete,
|
||||
usrtc_tree_lookup,
|
||||
usrtc_tree_lower_bound,
|
||||
usrtc_tree_upper_bound,
|
||||
usrtc_tree_first,
|
||||
usrtc_tree_last,
|
||||
usrtc_tree_next,
|
||||
usrtc_tree_prev,
|
||||
usrtc_tree_convert_to_list,
|
||||
redblack_convert_from_list,
|
||||
usrtc_bst
|
||||
};
|
||||
|
||||
/*implementation*/
|
||||
static void redblack_init(usrtc_t *us)
|
||||
{
|
||||
usrtc_tree_init(us);
|
||||
us->sentinel.color = usrtc_black;
|
||||
}
|
||||
|
||||
static void redblack_insert(usrtc_t *us, usrtc_node_t *node, const void *key)
|
||||
{
|
||||
usrtc_node_t *parent;
|
||||
|
||||
/* simple bt insert */
|
||||
usrtc_tree_insert(us,node,key);
|
||||
|
||||
/* implementation specific insert */
|
||||
node->color = usrtc_red;
|
||||
parent=node->parent;
|
||||
|
||||
while(parent->color==usrtc_red) {
|
||||
usrtc_node_t *grandpa=parent->parent;
|
||||
|
||||
if(parent==grandpa->left) {
|
||||
usrtc_node_t *uncle=grandpa->right;
|
||||
if(uncle->color==usrtc_red) { /*red parent->red uncle*/
|
||||
parent->color=usrtc_black;
|
||||
uncle->color=usrtc_black;
|
||||
grandpa->color=usrtc_red;
|
||||
node=grandpa;
|
||||
parent=grandpa->parent;
|
||||
} else { /*red parent->black uncle */
|
||||
if(node==parent->right) {
|
||||
usrtc_tree_rotate_left(node,parent);
|
||||
parent=node;
|
||||
if(grandpa!=parent->parent)
|
||||
return;
|
||||
}
|
||||
parent->color=usrtc_black;
|
||||
grandpa->color=usrtc_red;
|
||||
usrtc_tree_rotate_right(parent,grandpa);
|
||||
break;
|
||||
}
|
||||
} else { /*ooh,parent == parent->parent->right*/
|
||||
usrtc_node_t *uncle=grandpa->left;
|
||||
if(uncle->color==usrtc_red) {
|
||||
parent->color=usrtc_black;
|
||||
uncle->color=usrtc_black;
|
||||
grandpa->color=usrtc_red;
|
||||
node=grandpa;
|
||||
parent=grandpa->parent;
|
||||
} else {
|
||||
if(node==parent->left) {
|
||||
usrtc_tree_rotate_right(node,parent);
|
||||
parent=node;
|
||||
|
||||
if(grandpa!=parent->parent)
|
||||
return;
|
||||
}
|
||||
parent->color=usrtc_black;
|
||||
grandpa->color=usrtc_red;
|
||||
usrtc_tree_rotate_left(parent,grandpa);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tree_root_priv(us)->color=usrtc_black;
|
||||
}
|
||||
|
||||
static void redblack_delete(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
usrtc_node_t *swap;
|
||||
usrtc_node_t *child;
|
||||
usrtc_rb_color_t savecolor;
|
||||
|
||||
/*basic bt delete*/
|
||||
usrtc_tree_delete(us,node,&swap,&child);
|
||||
|
||||
/*implementation specific deletion*/
|
||||
savecolor=node->color;
|
||||
node->color=swap->color;
|
||||
swap->color=savecolor;
|
||||
|
||||
if(node->color==usrtc_black) { /*black*/
|
||||
usrtc_node_t *parent;
|
||||
usrtc_node_t *sister;
|
||||
|
||||
tree_root_priv(us)->color=usrtc_red;
|
||||
|
||||
while(child->color==usrtc_black) {
|
||||
parent=child->parent;
|
||||
if(child==parent->left) {
|
||||
sister=parent->right;
|
||||
if(sister==tree_null_priv(us))
|
||||
return;
|
||||
|
||||
if(sister->color==usrtc_red) {
|
||||
sister->color=usrtc_black;
|
||||
parent->color=usrtc_red;
|
||||
usrtc_tree_rotate_left(sister,parent);
|
||||
sister=parent->right;
|
||||
|
||||
if(sister==tree_null_priv(us))
|
||||
return;
|
||||
}
|
||||
if(sister->left->color==usrtc_black && sister->right->color==usrtc_black) {
|
||||
sister->color=usrtc_red;
|
||||
child=parent;
|
||||
} else {
|
||||
if(sister->right->color==usrtc_black) {
|
||||
if(sister->left->color!=usrtc_red)
|
||||
return;
|
||||
|
||||
sister->left->color=usrtc_black;
|
||||
sister->color=usrtc_red;
|
||||
usrtc_tree_rotate_right(sister->left,sister);
|
||||
sister=parent->right;
|
||||
|
||||
if(sister==tree_null_priv(us))
|
||||
return;
|
||||
}
|
||||
sister->color=parent->color;
|
||||
sister->right->color=usrtc_black;
|
||||
parent->color=usrtc_black;
|
||||
usrtc_tree_rotate_left(sister,parent);
|
||||
break;
|
||||
}
|
||||
} else { /*!child == child->parent->right*/
|
||||
if(child!=parent->right)
|
||||
return;
|
||||
|
||||
sister=parent->left;
|
||||
|
||||
if(sister==tree_null_priv(us))
|
||||
return;
|
||||
|
||||
if(sister->color==usrtc_red) {
|
||||
sister->color=usrtc_black;
|
||||
parent->color=usrtc_red;
|
||||
usrtc_tree_rotate_right(sister,parent);
|
||||
sister = parent->left;
|
||||
|
||||
if(sister==tree_null_priv(us))
|
||||
return;
|
||||
}
|
||||
if(sister->right->color==usrtc_black && sister->left->color==usrtc_black) {
|
||||
sister->color=usrtc_red;
|
||||
child=parent;
|
||||
} else {
|
||||
if(sister->left->color == usrtc_black) {
|
||||
if(sister->right->color!=usrtc_red)
|
||||
return;
|
||||
|
||||
sister->right->color=usrtc_black;
|
||||
sister->color=usrtc_red;
|
||||
usrtc_tree_rotate_left(sister->right, sister);
|
||||
sister=parent->left;
|
||||
|
||||
if(sister==tree_null_priv(us))
|
||||
return;
|
||||
}
|
||||
sister->color=parent->color;
|
||||
sister->left->color=usrtc_black;
|
||||
parent->color=usrtc_black;
|
||||
usrtc_tree_rotate_right(sister,parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
child->color=usrtc_black;
|
||||
tree_root_priv(us)->color=usrtc_black;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void redblack_convert_from_list(usrtc_t *us)
|
||||
{
|
||||
usrtc_node_t *tree[TREE_DEPTH_MAX] = { NULL };
|
||||
usrtc_node_t *curr;
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *next;
|
||||
usrtc_node_t *complete=NULL;
|
||||
usrtc_count_t fullcount=(usrtc_count_t)USRTC_COUNT_T_MAX;
|
||||
usrtc_count_t nodecount=us->nodecount;
|
||||
usrtc_count_t botrowcount;
|
||||
unsigned int baselevel=0;
|
||||
unsigned int level=0;
|
||||
unsigned int i;
|
||||
|
||||
if(usrtc_red!=0 && usrtc_black!=1)
|
||||
return;
|
||||
|
||||
while(fullcount>=nodecount && fullcount) /*calc*/
|
||||
fullcount >>= 1;
|
||||
|
||||
botrowcount=nodecount-fullcount;
|
||||
|
||||
for(curr=nil->next;curr!=nil;curr=next) {
|
||||
next=curr->next;
|
||||
|
||||
if(complete==NULL && botrowcount--==0) {
|
||||
baselevel=level=1;
|
||||
complete=tree[0];
|
||||
|
||||
if(complete!=NULL) {
|
||||
tree[0]=NULL;
|
||||
complete->right=nil;
|
||||
while(tree[level]!=0) {
|
||||
tree[level]->right=complete;
|
||||
complete->parent=tree[level];
|
||||
complete=tree[level];
|
||||
tree[level++]=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(complete==NULL) {
|
||||
curr->left=nil;
|
||||
curr->right=nil;
|
||||
curr->color=level%2;
|
||||
complete=curr;
|
||||
|
||||
if(level!=baselevel)
|
||||
return;
|
||||
|
||||
while(tree[level]!=NULL) {
|
||||
tree[level]->right=complete;
|
||||
complete->parent=tree[level];
|
||||
complete=tree[level];
|
||||
tree[level++]=NULL;
|
||||
}
|
||||
} else {
|
||||
curr->left=complete;
|
||||
curr->color=(level+1)%2;
|
||||
complete->parent=curr;
|
||||
tree[level]=curr;
|
||||
complete=NULL;
|
||||
level=baselevel;
|
||||
}
|
||||
}
|
||||
|
||||
if(complete==NULL)
|
||||
complete=nil;
|
||||
|
||||
for (i=0;i<TREE_DEPTH_MAX;i++) {
|
||||
if (tree[i]!=NULL) {
|
||||
tree[i]->right=complete;
|
||||
complete->parent=tree[i];
|
||||
complete=tree[i];
|
||||
}
|
||||
}
|
||||
|
||||
nil->right=nil;
|
||||
nil->left=complete;
|
||||
nil->color=usrtc_black;
|
||||
complete->parent=nil;
|
||||
complete->color=usrtc_black;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,142 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* splay.c
|
||||
* Copyright (C) 2006-2013, 2014 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#include <tdata/usrtc.h>
|
||||
#include <tdata/macro.h>
|
||||
#include <tdata/tree.h>
|
||||
|
||||
/*prototypes*/
|
||||
static void splay_insert(usrtc_t *,usrtc_node_t *,const void *);
|
||||
static void splay_delete(usrtc_t *,usrtc_node_t *);
|
||||
static usrtc_node_t *splay_lookup(usrtc_t *,const void *);
|
||||
|
||||
usrtc_functions_t usrtc_splay_fu = {
|
||||
usrtc_tree_init,
|
||||
splay_insert,
|
||||
splay_delete,
|
||||
splay_lookup,
|
||||
usrtc_tree_lower_bound,
|
||||
usrtc_tree_upper_bound,
|
||||
usrtc_tree_first,
|
||||
usrtc_tree_last,
|
||||
usrtc_tree_next,
|
||||
usrtc_tree_prev,
|
||||
usrtc_tree_convert_to_list,
|
||||
usrtc_tree_convert_from_list,
|
||||
usrtc_bst
|
||||
};
|
||||
|
||||
static void right_zig_zig(usrtc_node_t *,usrtc_node_t *,usrtc_node_t *);
|
||||
static void left_zig_zig(usrtc_node_t *,usrtc_node_t *,usrtc_node_t *);
|
||||
static void right_zig_zag(usrtc_node_t *,usrtc_node_t *,usrtc_node_t *);
|
||||
static void left_zig_zag(usrtc_node_t *,usrtc_node_t *,usrtc_node_t *);
|
||||
static void splay_node(usrtc_t *,usrtc_node_t *);
|
||||
|
||||
/*implementation*/
|
||||
|
||||
static void splay_insert(usrtc_t *us,usrtc_node_t *node,const void *key)
|
||||
{
|
||||
usrtc_tree_insert(us,node,key);
|
||||
|
||||
while(node!=tree_root_priv(us))
|
||||
splay_node(us,node);
|
||||
}
|
||||
|
||||
static void splay_delete(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
usrtc_node_t *dummy;
|
||||
usrtc_tree_delete(us,node,&dummy,&dummy);
|
||||
}
|
||||
|
||||
static usrtc_node_t *splay_lookup(usrtc_t *us,const void *key)
|
||||
{
|
||||
usrtc_node_t *node=usrtc_tree_lookup(us,key);
|
||||
|
||||
if(node)
|
||||
while(node!=tree_root_priv(us))
|
||||
splay_node(us,node);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static void right_zig_zig(usrtc_node_t *child,usrtc_node_t *parent,usrtc_node_t *grandpa)
|
||||
{
|
||||
usrtc_tree_rotate_right(parent,grandpa);
|
||||
usrtc_tree_rotate_right(child,parent);
|
||||
}
|
||||
|
||||
static void left_zig_zig(usrtc_node_t *child,usrtc_node_t *parent,usrtc_node_t *grandpa)
|
||||
{
|
||||
usrtc_tree_rotate_left(parent,grandpa);
|
||||
usrtc_tree_rotate_left(child,parent);
|
||||
}
|
||||
|
||||
static void right_zig_zag(usrtc_node_t *child,usrtc_node_t *parent,usrtc_node_t *grandpa)
|
||||
{
|
||||
usrtc_tree_rotate_right(child,parent);
|
||||
usrtc_tree_rotate_left(child,grandpa);
|
||||
}
|
||||
|
||||
static void left_zig_zag(usrtc_node_t *child,usrtc_node_t *parent,usrtc_node_t *grandpa)
|
||||
{
|
||||
usrtc_tree_rotate_left(child,parent);
|
||||
usrtc_tree_rotate_right(child,grandpa);
|
||||
}
|
||||
|
||||
static void splay_node(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
usrtc_node_t *root=tree_root_priv(us);
|
||||
usrtc_node_t *parent=node->parent;
|
||||
|
||||
if(parent->left==node) {
|
||||
if(parent==root) {
|
||||
usrtc_tree_rotate_right(node,parent);
|
||||
} else {
|
||||
usrtc_node_t *grandpa=parent->parent;
|
||||
|
||||
if(grandpa->left==parent)
|
||||
right_zig_zig(node,parent,grandpa);
|
||||
else {
|
||||
if(grandpa->right!=parent)
|
||||
return;
|
||||
|
||||
right_zig_zag(node,parent,grandpa);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(parent->right!=node)
|
||||
return;
|
||||
|
||||
if(parent==root) {
|
||||
usrtc_tree_rotate_left(node,parent);
|
||||
} else {
|
||||
usrtc_node_t *grandpa=parent->parent;
|
||||
|
||||
if(grandpa->right==parent) {
|
||||
left_zig_zig(node,parent,grandpa);
|
||||
} else {
|
||||
if(grandpa->left!=parent)
|
||||
return;
|
||||
|
||||
left_zig_zag(node,parent,grandpa);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,491 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* tree.c
|
||||
* Copyright (C) 2006-2013, 2014 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <tdata/usrtc.h>
|
||||
#include <tdata/macro.h>
|
||||
#include <tdata/tree.h>
|
||||
|
||||
/*local functions prototypes*/
|
||||
static void tree_delete(usrtc_t *, usrtc_node_t *);
|
||||
|
||||
usrtc_functions_t usrtc_tree_fu = {
|
||||
usrtc_tree_init,
|
||||
usrtc_tree_insert,
|
||||
tree_delete,
|
||||
usrtc_tree_lookup,
|
||||
usrtc_tree_lower_bound,
|
||||
usrtc_tree_upper_bound,
|
||||
usrtc_tree_first,
|
||||
usrtc_tree_last,
|
||||
usrtc_tree_next,
|
||||
usrtc_tree_prev,
|
||||
usrtc_tree_convert_to_list,
|
||||
usrtc_tree_convert_from_list,
|
||||
usrtc_bst
|
||||
};
|
||||
|
||||
/*implementation*/
|
||||
|
||||
void usrtc_tree_init(usrtc_t *us)
|
||||
{
|
||||
us->sentinel.left=&us->sentinel;
|
||||
us->sentinel.right=&us->sentinel;
|
||||
us->sentinel.parent=&us->sentinel;
|
||||
|
||||
us->sentinel.impl_specific.usrtc_dummy=0;
|
||||
us->sentinel.data=0;
|
||||
us->sentinel.key=0;
|
||||
}
|
||||
|
||||
void usrtc_tree_insert(usrtc_t *us,usrtc_node_t *node,const void *key)
|
||||
{
|
||||
usrtc_node_t *where=tree_root_priv(us);
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *parent=nil;
|
||||
long res=-1;
|
||||
|
||||
node->key=key;
|
||||
|
||||
while(where!=nil) {
|
||||
parent=where;
|
||||
res=us->compare(key,where->key);
|
||||
|
||||
if(us->dupes_allowed && !res) /*trying to put duplicate to the disabled dupe tree*/
|
||||
return;
|
||||
|
||||
if(res<0)
|
||||
where=where->left;
|
||||
else
|
||||
where=where->right;
|
||||
}
|
||||
|
||||
/*assert(where==nil);*/
|
||||
|
||||
if(res<0)
|
||||
parent->left=node;
|
||||
else
|
||||
parent->right=node;
|
||||
|
||||
node->parent=parent;
|
||||
node->left=nil;
|
||||
node->right=nil;
|
||||
|
||||
us->nodecount++;
|
||||
}
|
||||
|
||||
void usrtc_tree_delete(usrtc_t *us,usrtc_node_t *node,usrtc_node_t **pswap,usrtc_node_t **pchild)
|
||||
{
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *child;
|
||||
usrtc_node_t *delparent=node->parent;
|
||||
usrtc_node_t *next=node;
|
||||
usrtc_node_t *nextparent;
|
||||
|
||||
if(node->left!=nil && node->right!=nil) {
|
||||
next=usrtc_tree_next(us,node);
|
||||
nextparent=next->parent;
|
||||
|
||||
/*if(next!=nil && next->parent!=nil && next->parent==nil)
|
||||
return;*/
|
||||
|
||||
child=next->right;
|
||||
child->parent=nextparent;
|
||||
|
||||
if(nextparent->left==next)
|
||||
nextparent->left=child;
|
||||
else {
|
||||
//if(nextparent->right!=next)
|
||||
//return;
|
||||
nextparent->right=child;
|
||||
}
|
||||
|
||||
next->parent=delparent;
|
||||
next->left=node->left;
|
||||
next->right=node->right;
|
||||
next->left->parent=next;
|
||||
next->right->parent=next;
|
||||
|
||||
if(delparent->left==node) {
|
||||
delparent->left=next;
|
||||
} else {
|
||||
//if(delparent->right!=node)
|
||||
// return;
|
||||
delparent->right = next;
|
||||
}
|
||||
|
||||
} else {
|
||||
/*if(node==nil)
|
||||
return;
|
||||
if(node->left!=nil && node->right!=nil)
|
||||
return;*/
|
||||
|
||||
child=(node->left!=nil) ? node->left : node->right;
|
||||
|
||||
child->parent=delparent=node->parent;
|
||||
|
||||
if(node==delparent->left) {
|
||||
delparent->left=child;
|
||||
} else {
|
||||
/*if(node!=delparent->right)
|
||||
return;*/
|
||||
delparent->right=child;
|
||||
}
|
||||
}
|
||||
|
||||
node->parent=0;
|
||||
node->right=0;
|
||||
node->left=0;
|
||||
|
||||
us->nodecount--;
|
||||
|
||||
*pswap = next;
|
||||
*pchild = child;
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_tree_lookup(usrtc_t *us,const void *key)
|
||||
{
|
||||
usrtc_node_t *root=tree_root_priv(us);
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *saved;
|
||||
long res;
|
||||
|
||||
while (root!=nil) {
|
||||
res=us->compare(key,root->key);
|
||||
if(res<0)
|
||||
root=root->left;
|
||||
else if(res>0)
|
||||
root=root->right;
|
||||
else {
|
||||
if(!us->dupes_allowed)
|
||||
return root; /*no duplicates*/
|
||||
else { /*duplicate, then find left occurence*/
|
||||
do {
|
||||
saved=root;
|
||||
root=root->left;
|
||||
while(root!=nil && us->compare(key,root->key))
|
||||
root=root->right;
|
||||
} while(root!=nil);
|
||||
return saved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_tree_lower_bound(usrtc_t *us,const void *key)
|
||||
{
|
||||
usrtc_node_t *root=tree_root_priv(us);
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *tentative=NULL;
|
||||
long res;
|
||||
|
||||
while(root!=nil) {
|
||||
res=us->compare(key,root->key);
|
||||
|
||||
if(res>0) {
|
||||
root=root->right;
|
||||
} else if(res<0) {
|
||||
tentative=root;
|
||||
root=root->left;
|
||||
} else {
|
||||
if (!us->dupes_allowed)
|
||||
return root;
|
||||
else {
|
||||
tentative=root;
|
||||
root=root->left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tentative;
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_tree_upper_bound(usrtc_t *us,const void *key)
|
||||
{
|
||||
usrtc_node_t *root=tree_root_priv(us);
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *tentative=NULL;
|
||||
long res;
|
||||
|
||||
while(root!=nil) {
|
||||
res=us->compare(key,root->key);
|
||||
|
||||
if(res>0) {
|
||||
root=root->left;
|
||||
} else if(res<0) {
|
||||
tentative=root;
|
||||
root=root->right;
|
||||
} else {
|
||||
if (!us->dupes_allowed)
|
||||
return root;
|
||||
else {
|
||||
tentative=root;
|
||||
root=root->right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tentative;
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_tree_first(usrtc_t *us)
|
||||
{
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *root=tree_root_priv(us);
|
||||
usrtc_node_t *left;
|
||||
|
||||
if(root!=nil)
|
||||
while((left=root->left)!=nil)
|
||||
root=left;
|
||||
|
||||
return (root==nil) ? NULL : root;
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_tree_last(usrtc_t *us)
|
||||
{
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *root=tree_root_priv(us);
|
||||
usrtc_node_t *right;
|
||||
|
||||
if(root!=nil)
|
||||
while((right=root->right)!=nil)
|
||||
root=right;
|
||||
|
||||
return (root==nil) ? NULL : root;
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_tree_next(usrtc_t *us, usrtc_node_t *curr)
|
||||
{
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *parent;
|
||||
usrtc_node_t *left;
|
||||
|
||||
if(curr->right!=nil) {
|
||||
curr=curr->right;
|
||||
while((left=curr->left)!=nil)
|
||||
curr=left;
|
||||
return curr;
|
||||
}
|
||||
|
||||
parent=curr->parent;
|
||||
|
||||
while(parent!=nil && curr==parent->right) {
|
||||
curr=parent;
|
||||
parent=curr->parent;
|
||||
}
|
||||
|
||||
return (parent==nil) ? NULL : parent;
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_tree_prev(usrtc_t *us, usrtc_node_t *curr)
|
||||
{
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *parent;
|
||||
usrtc_node_t *right;
|
||||
|
||||
if(curr->left!=nil) {
|
||||
curr=curr->left;
|
||||
while((right=curr->right)!=nil)
|
||||
curr=right;
|
||||
return curr;
|
||||
}
|
||||
|
||||
parent=curr->parent;
|
||||
|
||||
while(parent!=nil && curr==parent->left) {
|
||||
curr=parent;
|
||||
parent=curr->parent;
|
||||
}
|
||||
|
||||
return (parent==nil) ? NULL : parent;
|
||||
}
|
||||
|
||||
/*uff, convertation between trees and lists*/
|
||||
void usrtc_tree_convert_to_list(usrtc_t *us)
|
||||
{
|
||||
usrtc_node_t *node;
|
||||
usrtc_node_t tempsentinel;
|
||||
usrtc_node_t *nil=&tempsentinel;
|
||||
usrtc_node_t *tail,*next;
|
||||
usrtc_node_t *treenil=tree_null_priv(us);
|
||||
|
||||
if(us->nodecount==0) /* no nodes */
|
||||
return;
|
||||
|
||||
tempsentinel.next=nil;
|
||||
tempsentinel.prev=nil;
|
||||
|
||||
/* two passes */
|
||||
for(tail=nil,node=usrtc_tree_first(us);node!=0;tail=node,node=next) {
|
||||
next=usrtc_tree_next(us,node);
|
||||
node->prev=tail;
|
||||
}
|
||||
|
||||
nil->prev=tail;
|
||||
|
||||
for(tail=nil,node=nil->prev;node!=nil;tail=node,node=node->prev)
|
||||
node->next=tail;
|
||||
|
||||
nil->next=tail;
|
||||
|
||||
us->sentinel.next=tempsentinel.next;
|
||||
us->sentinel.prev=tempsentinel.prev;
|
||||
us->sentinel.next->prev=treenil;
|
||||
us->sentinel.prev->next=treenil;
|
||||
}
|
||||
|
||||
void usrtc_tree_convert_from_list(usrtc_t *us)
|
||||
{
|
||||
usrtc_node_t *tree[TREE_DEPTH_MAX]={ 0 };
|
||||
usrtc_node_t *curr;
|
||||
usrtc_node_t *nil=tree_null_priv(us);
|
||||
usrtc_node_t *next;
|
||||
usrtc_node_t *complete=NULL;
|
||||
usrtc_count_t fullcount=(usrtc_count_t)USRTC_COUNT_T_MAX;
|
||||
usrtc_count_t nodecount=us->nodecount;
|
||||
usrtc_count_t botrowcount;
|
||||
int baselevel=0;
|
||||
int level=0;
|
||||
int i=0;
|
||||
|
||||
while (fullcount>=nodecount && fullcount) /* calc */
|
||||
fullcount>>=1;
|
||||
|
||||
botrowcount=nodecount-fullcount;
|
||||
|
||||
for(curr=nil->next;curr!=nil;curr=next) {
|
||||
next=curr->next;
|
||||
|
||||
if(complete==NULL && botrowcount-- ==0) {
|
||||
baselevel=level=1;
|
||||
complete=tree[0];
|
||||
|
||||
if(complete!=NULL) {
|
||||
tree[0]=0;
|
||||
complete->right=nil;
|
||||
while(tree[level]!=NULL) {
|
||||
tree[level]->right=complete;
|
||||
complete->parent=tree[level];
|
||||
complete=tree[level];
|
||||
tree[level++]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(complete==NULL) {
|
||||
curr->left=nil;
|
||||
curr->right=nil;
|
||||
complete=curr;
|
||||
|
||||
if(level!=baselevel)
|
||||
return;
|
||||
while(tree[level]!=NULL) {
|
||||
tree[level]->right=complete;
|
||||
complete->parent=tree[level];
|
||||
complete=tree[level];
|
||||
tree[level++]=0;
|
||||
}
|
||||
} else {
|
||||
curr->left=complete;
|
||||
complete->parent=curr;
|
||||
tree[level]=curr;
|
||||
complete=NULL;
|
||||
level=baselevel;
|
||||
}
|
||||
}
|
||||
|
||||
if(complete==NULL)
|
||||
complete=nil;
|
||||
|
||||
for(i=0;i<TREE_DEPTH_MAX;i++) {
|
||||
if(tree[i]!=NULL) {
|
||||
tree[i]->right=complete;
|
||||
complete->parent=tree[i];
|
||||
complete=tree[i];
|
||||
}
|
||||
}
|
||||
|
||||
nil->right=nil;
|
||||
nil->left=complete;
|
||||
complete->parent=nil;
|
||||
|
||||
}
|
||||
|
||||
void usrtc_tree_rotate_left(usrtc_node_t *child,usrtc_node_t *parent)
|
||||
{
|
||||
usrtc_node_t *leftgrandchild;
|
||||
usrtc_node_t *grandpa;
|
||||
|
||||
if(parent->right!=child)
|
||||
return;
|
||||
|
||||
child=parent->right;
|
||||
parent->right=leftgrandchild=child->left;
|
||||
leftgrandchild->parent=parent;
|
||||
|
||||
child->parent=grandpa=parent->parent;
|
||||
|
||||
if(parent==grandpa->left) {
|
||||
grandpa->left=child;
|
||||
} else {
|
||||
if(parent!=grandpa->right)
|
||||
return;
|
||||
grandpa->right=child;
|
||||
}
|
||||
|
||||
child->left=parent;
|
||||
parent->parent=child;
|
||||
}
|
||||
|
||||
void usrtc_tree_rotate_right(usrtc_node_t *child,usrtc_node_t *parent)
|
||||
{
|
||||
usrtc_node_t *rightgrandchild;
|
||||
usrtc_node_t *grandpa;
|
||||
|
||||
if(parent->left!=child)
|
||||
return;
|
||||
|
||||
parent->left=rightgrandchild=child->right;
|
||||
rightgrandchild->parent=parent;
|
||||
|
||||
child->parent=grandpa=parent->parent;
|
||||
|
||||
if(parent==grandpa->right) {
|
||||
grandpa->right=child;
|
||||
} else {
|
||||
if(parent!=grandpa->left)
|
||||
return;
|
||||
grandpa->left=child;
|
||||
}
|
||||
|
||||
child->right=parent;
|
||||
parent->parent=child;
|
||||
}
|
||||
|
||||
/* local functions */
|
||||
static void tree_delete(usrtc_t *us, usrtc_node_t *node)
|
||||
{
|
||||
usrtc_node_t *dummy;
|
||||
|
||||
usrtc_tree_delete(us, node, &dummy, &dummy);
|
||||
}
|
||||
|
@ -0,0 +1,243 @@
|
||||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
|
||||
/*
|
||||
* usrtc.c
|
||||
* Copyright (C) 2006-2013, 2014 Askele inc. <http://askele.com>
|
||||
*
|
||||
* libtdata is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libtdata is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.";
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <tdata/usrtc.h>
|
||||
#include <tdata/macro.h>
|
||||
|
||||
/* so, if you want to add your implementation of the data
|
||||
* structure please add this here, like the following.
|
||||
*/
|
||||
|
||||
#define MAX_IMPL 4
|
||||
|
||||
extern usrtc_functions_t usrtc_list_fu;
|
||||
extern usrtc_functions_t usrtc_tree_fu;
|
||||
extern usrtc_functions_t usrtc_redblack_fu;
|
||||
extern usrtc_functions_t usrtc_splay_fu;
|
||||
extern usrtc_functions_t usrtc_avl_fu;
|
||||
|
||||
static usrtc_functions_t *impl_table[] = {
|
||||
&usrtc_list_fu,&usrtc_tree_fu,
|
||||
&usrtc_redblack_fu,&usrtc_splay_fu,
|
||||
&usrtc_avl_fu };
|
||||
|
||||
static usrtc_node_t *default_node_alloc(void *context)
|
||||
{
|
||||
return malloc(sizeof *default_node_alloc(context));
|
||||
}
|
||||
|
||||
static void default_node_free(void *context,usrtc_node_t *node)
|
||||
{
|
||||
free(node);
|
||||
}
|
||||
|
||||
void usrtc_init(usrtc_t *us,int impl,usrtc_count_t maxcount,usrtc_compare_t compare)
|
||||
{
|
||||
if(!us)
|
||||
return;
|
||||
if(impl>MAX_IMPL)
|
||||
return;
|
||||
|
||||
us->nodecount=0;
|
||||
us->maxcount=maxcount;
|
||||
us->dupes_allowed=0;
|
||||
us->compare=compare;
|
||||
us->node_alloc=default_node_alloc;
|
||||
us->node_free=default_node_free;
|
||||
us->context=0;
|
||||
us->futable=impl_table[impl];
|
||||
us->futable->usrtc_init(us);
|
||||
}
|
||||
|
||||
usrtc_t *usrtc_create(int impl,usrtc_count_t maxcount,usrtc_compare_t compare)
|
||||
{
|
||||
usrtc_t *newrtc=(usrtc_t*)malloc(sizeof *newrtc);
|
||||
|
||||
if(newrtc)
|
||||
usrtc_init(newrtc,impl,maxcount,compare);
|
||||
|
||||
return newrtc;
|
||||
}
|
||||
|
||||
void usrtc_destroy(usrtc_t *us)
|
||||
{
|
||||
/*assert(usrtc_isempty(us));*/
|
||||
if(!us)
|
||||
return;
|
||||
|
||||
free(us);
|
||||
}
|
||||
|
||||
void usrtc_convert_to(usrtc_t *us,int impl)
|
||||
{
|
||||
if(impl_table[impl]==us->futable)
|
||||
return;
|
||||
|
||||
if(us->futable->usrtc_type==usrtc_bst && (impl==USRTC_BST || impl==USRTC_SPLAY)) {
|
||||
us->futable=impl_table[impl];
|
||||
return;
|
||||
}
|
||||
|
||||
us->futable->usrtc_convert_to_list(us);
|
||||
us->futable=impl_table[impl];
|
||||
|
||||
if(impl_table[impl]->usrtc_type==usrtc_lst)
|
||||
return;
|
||||
|
||||
us->futable->usrtc_convert_from_list(us);
|
||||
}
|
||||
|
||||
usrtc_count_t usrtc_count(usrtc_t *us)
|
||||
{
|
||||
return us->nodecount;
|
||||
}
|
||||
|
||||
int usrtc_isempty(usrtc_t *us)
|
||||
{
|
||||
return us->nodecount == 0;
|
||||
}
|
||||
|
||||
int usrtc_isfull(usrtc_t *us)
|
||||
{
|
||||
return us->nodecount == us->maxcount;
|
||||
}
|
||||
|
||||
int usrtc_alloc_insert(usrtc_t *us,const void *key,void *data)
|
||||
{
|
||||
usrtc_node_t *newnode=us->node_alloc(us->context);
|
||||
|
||||
if(newnode!=NULL) {
|
||||
newnode->data=data;
|
||||
us->futable->usrtc_insert(us,newnode,key);
|
||||
}
|
||||
|
||||
return newnode!=NULL;
|
||||
}
|
||||
|
||||
void usrtc_delete_free(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
us->futable->usrtc_delete(us,node);
|
||||
us->node_free(us->context,node);
|
||||
}
|
||||
|
||||
void usrtc_set_allocator(usrtc_t *us,usrtc_node_alloc_t alloc,usrtc_node_free_t n_free,void *context)
|
||||
{
|
||||
us->node_alloc=alloc;
|
||||
us->node_free=n_free;
|
||||
us->context=context;
|
||||
}
|
||||
|
||||
void usrtc_allow_dupes(usrtc_t *us)
|
||||
{
|
||||
/*assert(us->nodecount == 0);*/
|
||||
if(!us->nodecount)
|
||||
return;
|
||||
|
||||
us->dupes_allowed=1;
|
||||
}
|
||||
|
||||
void usrtc_node_init(usrtc_node_t *node,void *data)
|
||||
{
|
||||
node->data=data;
|
||||
node->impl_specific.usrtc_dummy=0;
|
||||
node->left=NULL;
|
||||
node->right=NULL;
|
||||
node->parent=NULL;
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_node_create(void *data)
|
||||
{
|
||||
usrtc_node_t *newnode=(usrtc_node_t*)malloc(sizeof *newnode);
|
||||
|
||||
if(newnode!=NULL)
|
||||
newnode->data=data;
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
void usrtc_node_destroy(usrtc_node_t *node)
|
||||
{
|
||||
free(node);
|
||||
}
|
||||
|
||||
void *usrtc_node_getdata(usrtc_node_t *node)
|
||||
{
|
||||
return node->data;
|
||||
}
|
||||
|
||||
void usrtc_node_setdata(usrtc_node_t *node,void *data)
|
||||
{
|
||||
node->data=data;
|
||||
}
|
||||
|
||||
const void *usrtc_node_getkey(usrtc_node_t *node)
|
||||
{
|
||||
return node->key;
|
||||
}
|
||||
|
||||
void usrtc_insert(usrtc_t *us,usrtc_node_t *node,const void *key)
|
||||
{
|
||||
us->futable->usrtc_insert(us,node,key);
|
||||
}
|
||||
|
||||
void usrtc_delete(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
us->futable->usrtc_delete(us,node);
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_lookup(usrtc_t *us,const void *key)
|
||||
{
|
||||
return us->futable->usrtc_lookup(us,key);
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_lower_bound(usrtc_t *us,const void *key)
|
||||
{
|
||||
return us->futable->usrtc_lower_bound(us,key);
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_upper_bound(usrtc_t *us,const void *key)
|
||||
{
|
||||
return us->futable->usrtc_upper_bound(us,key);
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_first(usrtc_t *us)
|
||||
{
|
||||
return us->futable->usrtc_first(us);
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_last(usrtc_t *us)
|
||||
{
|
||||
return us->futable->usrtc_last(us);
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_next(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
return us->futable->usrtc_next(us,node);
|
||||
}
|
||||
|
||||
usrtc_node_t *usrtc_prev(usrtc_t *us,usrtc_node_t *node)
|
||||
{
|
||||
return us->futable->usrtc_prev(us,node);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,2 @@
|
||||
# please keep this list sorted alphabetically
|
||||
#
|
@ -0,0 +1,3 @@
|
||||
# List of source files containing translatable strings.
|
||||
|
||||
|
Loading…
Reference in New Issue