include Judy into our source tree (#13362)
Timotej S committed
Jul 22, 2022 at 16:55 UTC
014c9f3259264f54d939958449477504dff6133e
54 files changed
+26708
-239
.gitignore
+4
@@ -228,3 +228,7 @@ Session.*.vim
228
229
# Jupyter notebook checkpoints
230
.ipynb_checkpoints
231
+
232
+# Judy stuff
233
+JudyLTables.c
234
+judyltablesgen
.travis.yml
+1
-1
@@ -17,7 +17,7 @@ before_install:
17
# Install dependencies for all, once
18
#
19
install:
20
- - sudo apt-get install -y libuv1-dev liblz4-dev libjudy-dev libcap2-bin zlib1g-dev uuid-dev fakeroot libipmimonitoring-dev libmnl-dev libnetfilter-acct-dev gnupg python3-pip
20
+ - sudo apt-get install -y libuv1-dev liblz4-dev libcap2-bin zlib1g-dev uuid-dev fakeroot libipmimonitoring-dev libmnl-dev libnetfilter-acct-dev gnupg python3-pip
21
- sudo pip3 install git-semver==0.3.2 # 11/Sep/2019: git-semver tip was broken, so we had to force last good run of it
22
- source tests/installer/slack.sh
23
- export NOTIF_CHANNEL="automation-beta"
CMakeLists.txt
+83
-14
@@ -102,20 +102,7 @@ set(NETDATA_COMMON_INCLUDE_DIRS ${NETDATA_COMMON_INCLUDE_DIRS} ${LIBLZ4_INCLUDE_
102
# -----------------------------------------------------------------------------
103
# Judy General purpose dynamic array
104
105
-# pkgconfig not working in Ubuntu, why? upstream package broken?
106
-#pkg_check_modules(JUDY REQUIRED Judy)
107
-#set(NETDATA_COMMON_CFLAGS ${NETDATA_COMMON_CFLAGS} ${JUDY_CFLAGS_OTHER})
108
-#set(NETDATA_COMMON_LIBRARIES ${NETDATA_COMMON_LIBRARIES} ${JUDY_LIBRARIES})
109
-#set(NETDATA_COMMON_INCLUDE_DIRS ${NETDATA_COMMON_INCLUDE_DIRS} ${JUDY_INCLUDE_DIRS})
110
-set(NETDATA_COMMON_LIBRARIES ${NETDATA_COMMON_LIBRARIES} "-lJudy")
111
-set(CMAKE_REQUIRED_LIBRARIES "Judy")
112
-include(CheckSymbolExists)
113
-check_symbol_exists("JudyLLast" "Judy.h" HAVE_JUDY)
114
-IF(HAVE_JUDY)
115
- message(STATUS "Judy library found")
116
-ELSE()
117
- message( FATAL_ERROR "libJudy required but not found. Try installing 'libjudy-dev' or 'Judy-devel'." )
118
-ENDIF()
105
+set(NETDATA_COMMON_LIBRARIES ${NETDATA_COMMON_LIBRARIES} judy)
106
107
# -----------------------------------------------------------------------------
108
# OpenSSL Cryptography and SSL/TLS Toolkit
@@ -362,6 +349,88 @@ ELSE()
349
set(ENABLE_ML False)
350
ENDIF()
351
352
+set(LIBJUDY_SOURCES
353
+ libnetdata/libjudy/src/Judy.h
354
+ libnetdata/libjudy/src/JudyCommon/JudyMalloc.c
355
+ libnetdata/libjudy/src/JudyCommon/JudyPrivate.h
356
+ libnetdata/libjudy/src/JudyCommon/JudyPrivate1L.h
357
+ libnetdata/libjudy/src/JudyCommon/JudyPrivateBranch.h
358
+ libnetdata/libjudy/src/JudyL/JudyL.h
359
+ libnetdata/libjudy/src/JudyL/JudyLByCount.c
360
+ libnetdata/libjudy/src/JudyL/JudyLCascade.c
361
+ libnetdata/libjudy/src/JudyL/JudyLCount.c
362
+ libnetdata/libjudy/src/JudyL/JudyLCreateBranch.c
363
+ libnetdata/libjudy/src/JudyL/JudyLDecascade.c
364
+ libnetdata/libjudy/src/JudyL/JudyLDel.c
365
+ libnetdata/libjudy/src/JudyL/JudyLFirst.c
366
+ libnetdata/libjudy/src/JudyL/JudyLFreeArray.c
367
+ libnetdata/libjudy/src/JudyL/j__udyLGet.c
368
+ libnetdata/libjudy/src/JudyL/JudyLGet.c
369
+ libnetdata/libjudy/src/JudyL/JudyLInsArray.c
370
+ libnetdata/libjudy/src/JudyL/JudyLIns.c
371
+ libnetdata/libjudy/src/JudyL/JudyLInsertBranch.c
372
+ libnetdata/libjudy/src/JudyL/JudyLMallocIF.c
373
+ libnetdata/libjudy/src/JudyL/JudyLMemActive.c
374
+ libnetdata/libjudy/src/JudyL/JudyLMemUsed.c
375
+ libnetdata/libjudy/src/JudyL/JudyLNext.c
376
+ libnetdata/libjudy/src/JudyL/JudyLNextEmpty.c
377
+ libnetdata/libjudy/src/JudyL/JudyLPrev.c
378
+ libnetdata/libjudy/src/JudyL/JudyLPrevEmpty.c
379
+ JudyLTables.c
380
+ libnetdata/libjudy/src/JudyHS/JudyHS.c)
381
+
382
+ADD_LIBRARY(judy STATIC
383
+ ${LIBJUDY_SOURCES})
384
+
385
+ADD_EXECUTABLE(judyltablesgen
386
+ libnetdata/libjudy/src/JudyL/JudyLTablesGen.c)
387
+
388
+target_include_directories(judyltablesgen PUBLIC
389
+ libnetdata/libjudy/src
390
+ libnetdata/libjudy/src/JudyCommon)
391
+
392
+target_compile_options(judyltablesgen PUBLIC
393
+ -Wno-format
394
+ -Wno-format-security)
395
+
396
+include_directories(BEFORE ${CMAKE_SOURCE_DIR}/libnetdata/libjudy/src)
397
+
398
+target_compile_definitions(judyltablesgen PUBLIC
399
+ JU_64BIT
400
+ JUDYL)
401
+
402
+add_custom_command(
403
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/JudyLTables.c
404
+ COMMAND judyltablesgen
405
+ DEPENDS judyltablesgen
406
+ )
407
+
408
+target_include_directories(judy PUBLIC
409
+ libnetdata/libjudy/src
410
+ libnetdata/libjudy/src/JudyCommon)
411
+
412
+target_compile_definitions(judy PUBLIC
413
+ JU_64BIT
414
+ JUDYL)
415
+
416
+target_compile_options(judy PUBLIC
417
+ -Wno-sign-compare
418
+ -Wno-implicit-fallthrough)
419
+
420
+set(LIBJUDY_PREV_FILES
421
+ libnetdata/libjudy/src/JudyL/JudyLPrev.c
422
+ libnetdata/libjudy/src/JudyL/JudyLPrevEmpty.c)
423
+
424
+set(LIBJUDY_NEXT_FILES
425
+ libnetdata/libjudy/src/JudyL/JudyLNext.c
426
+ libnetdata/libjudy/src/JudyL/JudyLNextEmpty.c)
427
+
428
+set_source_files_properties(${LIBJUDY_PREV_FILES} PROPERTIES COMPILE_OPTIONS "-DJUDYPREV")
429
+set_source_files_properties(${LIBJUDY_NEXT_FILES} PROPERTIES COMPILE_OPTIONS "-DJUDYNEXT")
430
+set_source_files_properties(libnetdata/libjudy/src/JudyL/j__udyLGet.c PROPERTIES COMPILE_OPTIONS "-DJUDYGETINLINE")
431
+set_source_files_properties(libnetdata/libjudy/src/JudyL/JudyLByCount.c PROPERTIES COMPILE_OPTIONS "-DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB")
432
+set_source_files_properties(JudyLTables.c PROPERTIES COMPILE_OPTIONS "-I${CMAKE_SOURCE_DIR}/libnetdata/libjudy/src/JudyL")
433
+
434
# -----------------------------------------------------------------------------
435
# netdata files
436
Makefile.am
+63
-3
@@ -61,7 +61,6 @@ dist_noinst_DATA = \
61
netdata.spec \
62
packaging/bundle-ebpf.sh \
63
packaging/bundle-ebpf-co-re.sh \
64
- packaging/bundle-judy.sh \
64
packaging/bundle-libbpf.sh \
65
packaging/check-kernel-config.sh \
66
packaging/ebpf.checksums \
@@ -75,8 +74,6 @@ dist_noinst_DATA = \
74
packaging/installer/UPDATE.md \
75
packaging/jsonc.checksums \
76
packaging/jsonc.version \
78
- packaging/judy.checksums \
79
- packaging/judy.version \
77
packaging/libbpf.checksums \
78
packaging/libbpf.version \
79
packaging/protobuf.checksums \
@@ -480,6 +477,64 @@ database/sqlite/sqlite3.$(OBJEXT) : CFLAGS += -Wno-cast-function-type
477
database/KolmogorovSmirnovDist.$(OBJEXT) : CFLAGS += -Wno-maybe-uninitialized
478
479
if ENABLE_DBENGINE
480
+ noinst_LIBRARIES = libjudy.a
481
+
482
+ libjudy_a_SOURCES = libnetdata/libjudy/src/Judy.h \
483
+ libnetdata/libjudy/src/JudyCommon/JudyMalloc.c \
484
+ libnetdata/libjudy/src/JudyCommon/JudyPrivate.h \
485
+ libnetdata/libjudy/src/JudyCommon/JudyPrivate1L.h \
486
+ libnetdata/libjudy/src/JudyCommon/JudyPrivateBranch.h \
487
+ libnetdata/libjudy/src/JudyL/JudyL.h \
488
+ libnetdata/libjudy/src/JudyL/JudyLByCount.c \
489
+ libnetdata/libjudy/src/JudyL/JudyLCascade.c \
490
+ libnetdata/libjudy/src/JudyL/JudyLCount.c \
491
+ libnetdata/libjudy/src/JudyL/JudyLCreateBranch.c \
492
+ libnetdata/libjudy/src/JudyL/JudyLDecascade.c \
493
+ libnetdata/libjudy/src/JudyL/JudyLDel.c \
494
+ libnetdata/libjudy/src/JudyL/JudyLFirst.c \
495
+ libnetdata/libjudy/src/JudyL/JudyLFreeArray.c \
496
+ libnetdata/libjudy/src/JudyL/j__udyLGet.c \
497
+ libnetdata/libjudy/src/JudyL/JudyLGet.c \
498
+ libnetdata/libjudy/src/JudyL/JudyLInsArray.c \
499
+ libnetdata/libjudy/src/JudyL/JudyLIns.c \
500
+ libnetdata/libjudy/src/JudyL/JudyLInsertBranch.c \
501
+ libnetdata/libjudy/src/JudyL/JudyLMallocIF.c \
502
+ libnetdata/libjudy/src/JudyL/JudyLMemActive.c \
503
+ libnetdata/libjudy/src/JudyL/JudyLMemUsed.c \
504
+ libnetdata/libjudy/src/JudyL/JudyLNext.c \
505
+ libnetdata/libjudy/src/JudyL/JudyLNextEmpty.c \
506
+ libnetdata/libjudy/src/JudyL/JudyLPrev.c \
507
+ libnetdata/libjudy/src/JudyL/JudyLPrevEmpty.c \
508
+ libnetdata/libjudy/src/JudyHS/JudyHS.c \
509
+ $(NULL)
510
+
511
+ nodist_libjudy_a_SOURCES = JudyLTables.c
512
+
513
+ BUILT_SOURCES += JudyLTables.c
514
+
515
+ CLEANFILES += JudyLTables.c
516
+
517
+ libjudy_a_CFLAGS = $(LIBJUDY_CFLAGS) -DJUDYL -I$(abs_top_srcdir)/libnetdata/libjudy/src -I$(abs_top_srcdir)/libnetdata/libjudy/src/JudyCommon -Wno-sign-compare -Wno-implicit-fallthrough
518
+
519
+ libnetdata/libjudy/src/JudyL/libjudy_a-JudyLPrev.$(OBJEXT) : CFLAGS += -DJUDYPREV
520
+ libnetdata/libjudy/src/JudyL/libjudy_a-JudyLPrevEmpty.$(OBJEXT) : CFLAGS += -DJUDYPREV
521
+ libnetdata/libjudy/src/JudyL/libjudy_a-JudyLNext.$(OBJEXT) : CFLAGS += -DJUDYNEXT
522
+ libnetdata/libjudy/src/JudyL/libjudy_a-JudyLNextEmpty.$(OBJEXT) : CFLAGS += -DJUDYNEXT
523
+ libnetdata/libjudy/src/JudyL/libjudy_a-JudyLByCount.$(OBJEXT) : CFLAGS += -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB
524
+ libnetdata/libjudy/src/JudyL/libjudy_a-j__udyLGet.$(OBJEXT) : CFLAGS += -DJUDYGETINLINE
525
+
526
+ noinst_PROGRAMS = judyltablesgen
527
+
528
+ judyltablesgen_SOURCES = libnetdata/libjudy/src/JudyL/JudyLTablesGen.c
529
+ judyltablesgen_CFLAGS = $(LIBJUDY_CFLAGS) -DJUDYL -I$(abs_top_srcdir)/libnetdata/libjudy/src -I$(abs_top_srcdir)/libnetdata/libjudy/src/JudyCommon -Wno-sign-compare -Wno-implicit-fallthrough
530
+
531
+ judyltablesgen$(EXEEXT) : CFLAGS += -Wno-format -Wno-format-security
532
+
533
+JudyLTables.c: $(abs_top_srcdir)/libnetdata/libjudy/src/JudyL/JudyLTablesGen.c $(builddir)/judyltablesgen$(EXEEXT)
534
+ $(builddir)/judyltablesgen$(EXEEXT)
535
+
536
+ libjudy_a-JudyLTables.$(OBJEXT) : CFLAGS += -I$(abs_top_srcdir)/libnetdata/libjudy/src/JudyL
537
+
538
RRD_PLUGIN_FILES += \
539
database/engine/rrdengine.c \
540
database/engine/rrdengine.h \
@@ -925,6 +980,11 @@ NETDATA_COMMON_LIBS = \
980
$(OPTIONAL_ATOMIC_LIBS) \
981
$(NULL)
982
983
+if ENABLE_DBENGINE
984
+ NETDATA_COMMON_LIBS += libjudy.a \
985
+ $(NULL)
986
+endif
987
+
988
if LINK_STATIC_JSONC
989
NETDATA_COMMON_LIBS += $(abs_top_srcdir)/externaldeps/jsonc/libjson-c.a
990
endif
configure.ac
+16
-41
@@ -42,6 +42,7 @@ AC_PROG_CXX
42
AC_PROG_INSTALL
43
PKG_PROG_PKG_CONFIG
44
AC_USE_SYSTEM_EXTENSIONS
45
+AC_PROG_RANLIB
46
47
# -----------------------------------------------------------------------------
48
# configurable options
@@ -468,45 +469,22 @@ OPTIONAL_JSONC_LIBS="${JSONC_LIBS}"
469
test "${enable_dbengine}" = "yes" -a -z "${LZ4_LIBS}" && \
470
AC_MSG_ERROR([liblz4 required but not found. Try installing 'liblz4-dev' or 'lz4-devel'.])
471
471
-
472
-AC_ARG_WITH([bundled-libJudy],
473
- [AS_HELP_STRING([--with-bundled-libJudy],[Use the bundled version of Judy library (default is system-library)])],
474
- [
475
- AC_MSG_CHECKING(for libJudy in $withval)
476
- if test -f "externaldeps/libJudy/libJudy.a" -a -f "externaldeps/libJudy/Judy.h"; then
477
- LIBS_BACKUP="${LIBS}"
478
- LIBS="externaldeps/libJudy/libJudy.a"
479
- AC_LINK_IFELSE([AC_LANG_SOURCE([[#include "externaldeps/libJudy/Judy.h"
480
- int main (int argc, char **argv) {
481
- Pvoid_t PJLArray = (Pvoid_t) NULL;
482
- Word_t * PValue;
483
- Word_t Index;
484
- JLI(PValue, PJLArray, Index);
485
- }]])],
486
- [HAVE_libJudy_a="yes"],
487
- [HAVE_libJudy_a="no"])
488
- LIBS="${LIBS_BACKUP}"
489
- JUDY_LIBS="\$(abs_top_srcdir)/externaldeps/libJudy/libJudy.a"
490
- JUDY_CFLAGS="-I \$(abs_top_srcdir)/externaldeps/libJudy"
491
- AC_MSG_RESULT([$HAVE_libJudy_a])
492
- else
493
- libjudy_dir=""
494
- HAVE_libJudy_a="no"
495
- AC_MSG_RESULT([$HAVE_libJudy_a])
496
- fi
497
- ],
498
- [HAVE_libJudy_a="no"])
499
-
500
-if test "${HAVE_libJudy_a}" = "no"; then
501
- AC_CHECK_LIB(
502
- [Judy],
503
- [JudyLIns],
504
- [JUDY_LIBS="-lJudy"]
505
- )
472
+AC_C_BIGENDIAN([],
473
+ [LIBJUDY_CFLAGS="-DJU_LITTLE_ENDIAN"],
474
+ [AC_MSG_ERROR([Could not find out system endiannnes])])
475
+
476
+AC_CHECK_SIZEOF(void *)
477
+if test "$ac_cv_sizeof_void_p" = 8; then
478
+ AC_MSG_RESULT(Detected 64-bit Build Environment)
479
+ LIBJUDY_CFLAGS="$LIBJUDY_CFLAGS -DJU_64BIT"
480
+else
481
+ AC_MSG_RESULT(Detected 32-bit Build Environment)
482
+ LIBJUDY_CFLAGS="$LIBJUDY_CFLAGS -UJU_64BIT"
483
fi
484
508
-test "${enable_dbengine}" = "yes" -a -z "${JUDY_LIBS}" && \
509
- AC_MSG_ERROR([libJudy required but not found. Try installing 'libjudy-dev' or 'Judy-devel'.])
485
+AC_SUBST([LIBJUDY_CFLAGS])
486
+
487
+JUDY_CFLAGS="-I \$(abs_top_srcdir)/libnetdata/libjudy/src"
488
489
test "${enable_https}" = "yes" -a -z "${SSL_LIBS}" && \
490
AC_MSG_ERROR([OpenSSL required for HTTPS but not found. Try installing 'libssl-dev' or 'openssl-devel'.])
@@ -515,13 +493,12 @@ test "${enable_dbengine}" = "yes" -a -z "${SSL_LIBS}" && \
493
AC_MSG_ERROR([OpenSSL required for DBENGINE but not found. Try installing 'libssl-dev' or 'openssl-devel'.])
494
495
AC_MSG_CHECKING([if netdata dbengine should be used])
518
-if test "${enable_dbengine}" != "no" -a "${UV_LIBS}" -a "${LZ4_LIBS}" -a "${JUDY_LIBS}" -a "${SSL_LIBS}"; then
496
+if test "${enable_dbengine}" != "no" -a "${UV_LIBS}" -a "${LZ4_LIBS}" -a "${SSL_LIBS}"; then
497
enable_dbengine="yes"
498
AC_DEFINE([ENABLE_DBENGINE], [1], [netdata dbengine usability])
499
OPTIONAL_LZ4_CFLAGS="${LZ4_CFLAGS}"
500
OPTIONAL_LZ4_LIBS="${LZ4_LIBS}"
501
OPTIONAL_JUDY_CFLAGS="${JUDY_CFLAGS}"
524
- OPTIONAL_JUDY_LIBS="${JUDY_LIBS}"
502
OPTIONAL_SSL_CFLAGS="${SSL_CFLAGS}"
503
OPTIONAL_SSL_LIBS="${SSL_LIBS}"
504
else
@@ -1600,8 +1577,6 @@ AC_SUBST([OPTIONAL_MATH_CFLAGS])
1577
AC_SUBST([OPTIONAL_MATH_LIBS])
1578
AC_SUBST([OPTIONAL_UV_LIBS])
1579
AC_SUBST([OPTIONAL_LZ4_LIBS])
1603
-AC_SUBST([OPTIONAL_JUDY_CFLAGS])
1604
-AC_SUBST([OPTIONAL_JUDY_LIBS])
1580
AC_SUBST([OPTIONAL_SSL_LIBS])
1581
AC_SUBST([OPTIONAL_JSONC_LIBS])
1582
AC_SUBST([OPTIONAL_NFACCT_CFLAGS])
contrib/debian/control
-1
@@ -7,7 +7,6 @@ Build-Depends: debhelper (>= 9.20160709),
7
libelf-dev,
8
libuv1-dev,
9
liblz4-dev,
10
- libjudy-dev,
10
libssl-dev,
11
libmnl-dev,
12
libjson-c-dev,
contrib/debian/control.xenial
-1
@@ -8,7 +8,6 @@ Build-Depends: debhelper (>= 9),
8
libelf-dev,
9
libuv1-dev,
10
liblz4-dev,
11
- libjudy-dev,
11
libssl-dev,
12
libmnl-dev,
13
libjson-c-dev,
libnetdata/libjudy/src/Judy.h
new
+622
@@ -0,0 +1,622 @@
1
+#ifndef _JUDY_INCLUDED
2
+#define _JUDY_INCLUDED
3
+// _________________
4
+//
5
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
6
+//
7
+// This program is free software; you can redistribute it and/or modify it
8
+// under the term of the GNU Lesser General Public License as published by the
9
+// Free Software Foundation; either version 2 of the License, or (at your
10
+// option) any later version.
11
+//
12
+// This program is distributed in the hope that it will be useful, but WITHOUT
13
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
+// for more details.
16
+//
17
+// You should have received a copy of the GNU Lesser General Public License
18
+// along with this program; if not, write to the Free Software Foundation,
19
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+// _________________
21
+
22
+// @(#) $Revision: 4.52 $ $Source: /judy/src/Judy.h $
23
+//
24
+// HEADER FILE FOR EXPORTED FEATURES IN JUDY LIBRARY, libJudy.*
25
+//
26
+// See the manual entries for details.
27
+//
28
+// Note: This header file uses old-style comments on #-directive lines and
29
+// avoids "()" on macro names in comments for compatibility with older cc -Aa
30
+// and some tools on some platforms.
31
+
32
+
33
+// PLATFORM-SPECIFIC
34
+
35
+#ifdef JU_WIN /* =============================================== */
36
+
37
+typedef __int8 int8_t;
38
+typedef __int16 int16_t;
39
+typedef __int32 int32_t;
40
+typedef __int64 int64_t;
41
+
42
+typedef unsigned __int8 uint8_t;
43
+typedef unsigned __int16 uint16_t;
44
+typedef unsigned __int32 uint32_t;
45
+typedef unsigned __int64 uint64_t;
46
+
47
+#else /* ================ ! JU_WIN ============================= */
48
+
49
+// ISO C99: 7.8 Format conversion of integer types <inttypes.h>
50
+#include <inttypes.h> /* if this FAILS, try #include <stdint.h> */
51
+
52
+// ISO C99: 7.18 Integer types uint*_t
53
+//#include <stdint.h>
54
+
55
+#endif /* ================ ! JU_WIN ============================= */
56
+
57
+// ISO C99 Standard: 7.20 General utilities
58
+#include <stdlib.h>
59
+
60
+// ISO C99 Standard: 7.10/5.2.4.2.1 Sizes of integer types
61
+#include <limits.h>
62
+
63
+#ifdef __cplusplus /* support use by C++ code */
64
+extern "C" {
65
+#endif
66
+
67
+
68
+// ****************************************************************************
69
+// DECLARE SOME BASE TYPES IN CASE THEY ARE MISSING:
70
+//
71
+// These base types include "const" where appropriate, but only where of
72
+// interest to the caller. For example, a caller cares that a variable passed
73
+// by reference will not be modified, such as, "const void * Pindex", but not
74
+// that the called function internally does not modify the pointer itself, such
75
+// as, "void * const Pindex".
76
+//
77
+// Note that its OK to pass a Pvoid_t to a Pcvoid_t; the latter is the same,
78
+// only constant. Callers need to do this so they can also pass & Pvoid_t to
79
+// PPvoid_t (non-constant).
80
+
81
+#ifndef _PCVOID_T
82
+#define _PCVOID_T
83
+typedef const void * Pcvoid_t;
84
+#endif
85
+
86
+#ifndef _PVOID_T
87
+#define _PVOID_T
88
+typedef void * Pvoid_t;
89
+typedef void ** PPvoid_t;
90
+#endif
91
+
92
+#ifndef _WORD_T
93
+#define _WORD_T
94
+typedef unsigned long Word_t, * PWord_t; // expect 32-bit or 64-bit words.
95
+#endif
96
+
97
+#ifndef NULL
98
+#define NULL 0
99
+#endif
100
+
101
+
102
+// ****************************************************************************
103
+// SUPPORT FOR ERROR HANDLING:
104
+//
105
+// Judy error numbers:
106
+//
107
+// Note: These are an enum so theres a related typedef, but the numbers are
108
+// spelled out so you can map a number back to its name.
109
+
110
+typedef enum // uint8_t -- but C does not support this type of enum.
111
+{
112
+
113
+// Note: JU_ERRNO_NONE and JU_ERRNO_FULL are not real errors. They specify
114
+// conditions which are otherwise impossible return values from 32-bit
115
+// Judy1Count, which has 2^32 + 1 valid returns (0..2^32) plus one error
116
+// return. These pseudo-errors support the return values that cannot otherwise
117
+// be unambiguously represented in a 32-bit word, and will never occur on a
118
+// 64-bit system.
119
+
120
+ JU_ERRNO_NONE = 0,
121
+ JU_ERRNO_FULL = 1,
122
+ JU_ERRNO_NFMAX = JU_ERRNO_FULL,
123
+
124
+// JU_ERRNO_NOMEM comes from malloc(3C) when Judy cannot obtain needed memory.
125
+// The system errno value is also set to ENOMEM. This error can be recoverable
126
+// if the calling application frees other memory.
127
+//
128
+// TBD: Currently there is no guarantee the Judy array has no memory leaks
129
+// upon JU_ERRNO_NOMEM.
130
+
131
+ JU_ERRNO_NOMEM = 2,
132
+
133
+// Problems with parameters from the calling program:
134
+//
135
+// JU_ERRNO_NULLPPARRAY means PPArray was null; perhaps PArray was passed where
136
+// &PArray was intended. Similarly, JU_ERRNO_NULLPINDEX means PIndex was null;
137
+// perhaps &Index was intended. Also, JU_ERRNO_NONNULLPARRAY,
138
+// JU_ERRNO_NULLPVALUE, and JU_ERRNO_UNSORTED, all added later (hence with
139
+// higher numbers), mean: A non-null array was passed in where a null pointer
140
+// was required; PValue was null; and unsorted indexes were detected.
141
+
142
+ JU_ERRNO_NULLPPARRAY = 3, // see above.
143
+ JU_ERRNO_NONNULLPARRAY = 10, // see above.
144
+ JU_ERRNO_NULLPINDEX = 4, // see above.
145
+ JU_ERRNO_NULLPVALUE = 11, // see above.
146
+ JU_ERRNO_NOTJUDY1 = 5, // PArray is not to a Judy1 array.
147
+ JU_ERRNO_NOTJUDYL = 6, // PArray is not to a JudyL array.
148
+ JU_ERRNO_NOTJUDYSL = 7, // PArray is not to a JudySL array.
149
+ JU_ERRNO_UNSORTED = 12, // see above.
150
+
151
+// Errors below this point are not recoverable; further tries to access the
152
+// Judy array might result in EFAULT and a core dump:
153
+//
154
+// JU_ERRNO_OVERRUN occurs when Judy detects, upon reallocation, that a block
155
+// of memory in its own freelist was modified since being freed.
156
+
157
+ JU_ERRNO_OVERRUN = 8,
158
+
159
+// JU_ERRNO_CORRUPT occurs when Judy detects an impossible value in a Judy data
160
+// structure:
161
+//
162
+// Note: The Judy data structure contains some redundant elements that support
163
+// this type of checking.
164
+
165
+ JU_ERRNO_CORRUPT = 9
166
+
167
+// Warning: At least some C or C++ compilers do not tolerate a trailing comma
168
+// above here. At least we know of one case, in aCC; see JAGad58928.
169
+
170
+} JU_Errno_t;
171
+
172
+
173
+// Judy errno structure:
174
+//
175
+// WARNING: For compatibility with possible future changes, the fields of this
176
+// struct should not be referenced directly. Instead use the macros supplied
177
+// below.
178
+
179
+// This structure should be declared on the stack in a threaded process.
180
+
181
+typedef struct J_UDY_ERROR_STRUCT
182
+{
183
+ JU_Errno_t je_Errno; // one of the enums above.
184
+ int je_ErrID; // often an internal source line number.
185
+ Word_t je_reserved[4]; // for future backward compatibility.
186
+
187
+} JError_t, * PJError_t;
188
+
189
+
190
+// Related macros:
191
+//
192
+// Fields from error struct:
193
+
194
+#define JU_ERRNO(PJError) ((PJError)->je_Errno)
195
+#define JU_ERRID(PJError) ((PJError)->je_ErrID)
196
+
197
+// For checking return values from various Judy functions:
198
+//
199
+// Note: Define JERR as -1, not as the seemingly more portable (Word_t)
200
+// (~0UL), to avoid a compiler "overflow in implicit constant conversion"
201
+// warning.
202
+
203
+#define JERR (-1) /* functions returning int or Word_t */
204
+#define PJERR ((Pvoid_t) (~0UL)) /* mainly for use here, see below */
205
+#define PPJERR ((PPvoid_t) (~0UL)) /* functions that return PPvoid_t */
206
+
207
+// Convenience macro for when detailed error information (PJError_t) is not
208
+// desired by the caller; a purposely short name:
209
+
210
+#define PJE0 ((PJError_t) NULL)
211
+
212
+
213
+// ****************************************************************************
214
+// JUDY FUNCTIONS:
215
+//
216
+// P_JE is a shorthand for use below:
217
+
218
+#define P_JE PJError_t PJError
219
+
220
+// ****************************************************************************
221
+// JUDY1 FUNCTIONS:
222
+
223
+extern int Judy1Test( Pcvoid_t PArray, Word_t Index, P_JE);
224
+extern int Judy1Set( PPvoid_t PPArray, Word_t Index, P_JE);
225
+extern int Judy1SetArray( PPvoid_t PPArray, Word_t Count,
226
+ const Word_t * const PIndex,
227
+ P_JE);
228
+extern int Judy1Unset( PPvoid_t PPArray, Word_t Index, P_JE);
229
+extern Word_t Judy1Count( Pcvoid_t PArray, Word_t Index1,
230
+ Word_t Index2, P_JE);
231
+extern int Judy1ByCount( Pcvoid_t PArray, Word_t Count,
232
+ Word_t * PIndex, P_JE);
233
+extern Word_t Judy1FreeArray( PPvoid_t PPArray, P_JE);
234
+extern Word_t Judy1MemUsed( Pcvoid_t PArray);
235
+extern Word_t Judy1MemActive( Pcvoid_t PArray);
236
+extern int Judy1First( Pcvoid_t PArray, Word_t * PIndex, P_JE);
237
+extern int Judy1Next( Pcvoid_t PArray, Word_t * PIndex, P_JE);
238
+extern int Judy1Last( Pcvoid_t PArray, Word_t * PIndex, P_JE);
239
+extern int Judy1Prev( Pcvoid_t PArray, Word_t * PIndex, P_JE);
240
+extern int Judy1FirstEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
241
+extern int Judy1NextEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
242
+extern int Judy1LastEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
243
+extern int Judy1PrevEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
244
+
245
+extern PPvoid_t JudyLGet( Pcvoid_t PArray, Word_t Index, P_JE);
246
+extern PPvoid_t JudyLIns( PPvoid_t PPArray, Word_t Index, P_JE);
247
+extern int JudyLInsArray( PPvoid_t PPArray, Word_t Count,
248
+ const Word_t * const PIndex,
249
+ const Word_t * const PValue,
250
+
251
+// ****************************************************************************
252
+// JUDYL FUNCTIONS:
253
+ P_JE);
254
+extern int JudyLDel( PPvoid_t PPArray, Word_t Index, P_JE);
255
+extern Word_t JudyLCount( Pcvoid_t PArray, Word_t Index1,
256
+ Word_t Index2, P_JE);
257
+extern PPvoid_t JudyLByCount( Pcvoid_t PArray, Word_t Count,
258
+ Word_t * PIndex, P_JE);
259
+extern Word_t JudyLFreeArray( PPvoid_t PPArray, P_JE);
260
+extern Word_t JudyLMemUsed( Pcvoid_t PArray);
261
+extern Word_t JudyLMemActive( Pcvoid_t PArray);
262
+extern PPvoid_t JudyLFirst( Pcvoid_t PArray, Word_t * PIndex, P_JE);
263
+extern PPvoid_t JudyLNext( Pcvoid_t PArray, Word_t * PIndex, P_JE);
264
+extern PPvoid_t JudyLLast( Pcvoid_t PArray, Word_t * PIndex, P_JE);
265
+extern PPvoid_t JudyLPrev( Pcvoid_t PArray, Word_t * PIndex, P_JE);
266
+extern int JudyLFirstEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
267
+extern int JudyLNextEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
268
+extern int JudyLLastEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
269
+extern int JudyLPrevEmpty( Pcvoid_t PArray, Word_t * PIndex, P_JE);
270
+
271
+// ****************************************************************************
272
+// JUDYSL FUNCTIONS:
273
+
274
+extern PPvoid_t JudySLGet( Pcvoid_t, const uint8_t * Index, P_JE);
275
+extern PPvoid_t JudySLIns( PPvoid_t, const uint8_t * Index, P_JE);
276
+extern int JudySLDel( PPvoid_t, const uint8_t * Index, P_JE);
277
+extern Word_t JudySLFreeArray( PPvoid_t, P_JE);
278
+extern PPvoid_t JudySLFirst( Pcvoid_t, uint8_t * Index, P_JE);
279
+extern PPvoid_t JudySLNext( Pcvoid_t, uint8_t * Index, P_JE);
280
+extern PPvoid_t JudySLLast( Pcvoid_t, uint8_t * Index, P_JE);
281
+extern PPvoid_t JudySLPrev( Pcvoid_t, uint8_t * Index, P_JE);
282
+
283
+// ****************************************************************************
284
+// JUDYHSL FUNCTIONS:
285
+
286
+extern PPvoid_t JudyHSGet( Pcvoid_t, void *, Word_t);
287
+extern PPvoid_t JudyHSIns( PPvoid_t, void *, Word_t, P_JE);
288
+extern int JudyHSDel( PPvoid_t, void *, Word_t, P_JE);
289
+extern Word_t JudyHSFreeArray( PPvoid_t, P_JE);
290
+
291
+extern const char *Judy1MallocSizes;
292
+extern const char *JudyLMallocSizes;
293
+
294
+// ****************************************************************************
295
+// JUDY memory interface to malloc() FUNCTIONS:
296
+
297
+extern Word_t JudyMalloc(Word_t); // words reqd => words allocd.
298
+extern Word_t JudyMallocVirtual(Word_t); // words reqd => words allocd.
299
+extern void JudyFree(Pvoid_t, Word_t); // free, size in words.
300
+extern void JudyFreeVirtual(Pvoid_t, Word_t); // free, size in words.
301
+
302
+#define JLAP_INVALID 0x1 /* flag to mark pointer "not a Judy array" */
303
+
304
+// ****************************************************************************
305
+// MACRO EQUIVALENTS FOR JUDY FUNCTIONS:
306
+//
307
+// The following macros, such as J1T, are shorthands for calling Judy functions
308
+// with parameter address-of and detailed error checking included. Since they
309
+// are macros, the error checking code is replicated each time the macro is
310
+// used, but it runs fast in the normal case of no error.
311
+//
312
+// If the caller does not like the way the default JUDYERROR macro handles
313
+// errors (such as an exit(1) call when out of memory), they may define their
314
+// own before the "#include <Judy.h>". A routine such as HandleJudyError
315
+// could do checking on specific error numbers and print a different message
316
+// dependent on the error. The following is one example:
317
+//
318
+// Note: the back-slashes are removed because some compilers will not accept
319
+// them in comments.
320
+//
321
+// void HandleJudyError(uint8_t *, int, uint8_t *, int, int);
322
+// #define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID)
323
+// {
324
+// HandleJudyError(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID);
325
+// }
326
+//
327
+// The routine HandleJudyError could do checking on specific error numbers and
328
+// print a different message dependent on the error.
329
+//
330
+// The macro receives five parameters that are:
331
+//
332
+// 1. CallerFile: Source filename where a Judy call returned a serious error.
333
+// 2. CallerLine: Line number in that source file.
334
+// 3. JudyFunc: Name of Judy function reporting the error.
335
+// 4. JudyErrno: One of the JU_ERRNO* values enumerated above.
336
+// 5. JudyErrID: The je_ErrID field described above.
337
+
338
+#ifndef JUDYERROR_NOTEST
339
+#ifndef JUDYERROR /* supply a default error macro */
340
+#include <stdio.h>
341
+
342
+#define JUDYERROR(CallerFile, CallerLine, JudyFunc, JudyErrno, JudyErrID) \
343
+ { \
344
+ (void) fprintf(stderr, "File '%s', line %d: %s(), " \
345
+ "JU_ERRNO_* == %d, ID == %d\n", \
346
+ CallerFile, CallerLine, \
347
+ JudyFunc, JudyErrno, JudyErrID); \
348
+ exit(1); \
349
+ }
350
+
351
+#endif /* JUDYERROR */
352
+#endif /* JUDYERROR_NOTEST */
353
+
354
+// If the JUDYERROR macro is not desired at all, then the following eliminates
355
+// it. However, the return code from each Judy function (that is, the first
356
+// parameter of each macro) must be checked by the caller to assure that an
357
+// error did not occur.
358
+//
359
+// Example:
360
+//
361
+// #define JUDYERROR_NOTEST 1
362
+// #include <Judy.h>
363
+//
364
+// or use this cc option at compile time:
365
+//
366
+// cc -DJUDYERROR_NOTEST ...
367
+//
368
+// Example code:
369
+//
370
+// J1S(Rc, PArray, Index);
371
+// if (Rc == JERR) goto ...error
372
+//
373
+// or:
374
+//
375
+// JLI(PValue, PArray, Index);
376
+// if (PValue == PJERR) goto ...error
377
+
378
+
379
+// Internal shorthand macros for writing the J1S, etc. macros:
380
+
381
+#ifdef JUDYERROR_NOTEST /* ============================================ */
382
+
383
+// "Judy Set Error":
384
+
385
+#define J_SE(FuncName,Errno) ((void) 0)
386
+
387
+// Note: In each J_*() case below, the digit is the number of key parameters
388
+// to the Judy*() call. Just assign the Func result to the callers Rc value
389
+// without a cast because none is required, and this keeps the API simpler.
390
+// However, a family of different J_*() macros is needed to support the
391
+// different numbers of key parameters (0,1,2) and the Func return type.
392
+//
393
+// In the names below, "I" = integer result; "P" = pointer result. Note, the
394
+// Funcs for J_*P() return PPvoid_t, but cast this to a Pvoid_t for flexible,
395
+// error-free assignment, and then compare to PJERR.
396
+
397
+#define J_0I(Rc,PArray,Func,FuncName) \
398
+ { (Rc) = Func(PArray, PJE0); }
399
+
400
+#define J_1I(Rc,PArray,Index,Func,FuncName) \
401
+ { (Rc) = Func(PArray, Index, PJE0); }
402
+
403
+#define J_1P(PV,PArray,Index,Func,FuncName) \
404
+ { (PV) = (Pvoid_t) Func(PArray, Index, PJE0); }
405
+
406
+#define J_2I(Rc,PArray,Index,Arg2,Func,FuncName) \
407
+ { (Rc) = Func(PArray, Index, Arg2, PJE0); }
408
+
409
+#define J_2C(Rc,PArray,Index1,Index2,Func,FuncName) \
410
+ { (Rc) = Func(PArray, Index1, Index2, PJE0); }
411
+
412
+#define J_2P(PV,PArray,Index,Arg2,Func,FuncName) \
413
+ { (PV) = (Pvoid_t) Func(PArray, Index, Arg2, PJE0); }
414
+
415
+// Variations for Judy*Set/InsArray functions:
416
+
417
+#define J_2AI(Rc,PArray,Count,PIndex,Func,FuncName) \
418
+ { (Rc) = Func(PArray, Count, PIndex, PJE0); }
419
+#define J_3AI(Rc,PArray,Count,PIndex,PValue,Func,FuncName) \
420
+ { (Rc) = Func(PArray, Count, PIndex, PValue, PJE0); }
421
+
422
+#else /* ================ ! JUDYERROR_NOTEST ============================= */
423
+
424
+#define J_E(FuncName,PJE) \
425
+ JUDYERROR(__FILE__, __LINE__, FuncName, JU_ERRNO(PJE), JU_ERRID(PJE))
426
+
427
+#define J_SE(FuncName,Errno) \
428
+ { \
429
+ JError_t J_Error; \
430
+ JU_ERRNO(&J_Error) = (Errno); \
431
+ JU_ERRID(&J_Error) = __LINE__; \
432
+ J_E(FuncName, &J_Error); \
433
+ }
434
+
435
+// Note: In each J_*() case below, the digit is the number of key parameters
436
+// to the Judy*() call. Just assign the Func result to the callers Rc value
437
+// without a cast because none is required, and this keeps the API simpler.
438
+// However, a family of different J_*() macros is needed to support the
439
+// different numbers of key parameters (0,1,2) and the Func return type.
440
+//
441
+// In the names below, "I" = integer result; "P" = pointer result. Note, the
442
+// Funcs for J_*P() return PPvoid_t, but cast this to a Pvoid_t for flexible,
443
+// error-free assignment, and then compare to PJERR.
444
+
445
+#define J_0I(Rc,PArray,Func,FuncName) \
446
+ { \
447
+ JError_t J_Error; \
448
+ if (((Rc) = Func(PArray, &J_Error)) == JERR) \
449
+ J_E(FuncName, &J_Error); \
450
+ }
451
+
452
+#define J_1I(Rc,PArray,Index,Func,FuncName) \
453
+ { \
454
+ JError_t J_Error; \
455
+ if (((Rc) = Func(PArray, Index, &J_Error)) == JERR) \
456
+ J_E(FuncName, &J_Error); \
457
+ }
458
+
459
+#define J_1P(Rc,PArray,Index,Func,FuncName) \
460
+ { \
461
+ JError_t J_Error; \
462
+ if (((Rc) = (Pvoid_t) Func(PArray, Index, &J_Error)) == PJERR) \
463
+ J_E(FuncName, &J_Error); \
464
+ }
465
+
466
+#define J_2I(Rc,PArray,Index,Arg2,Func,FuncName) \
467
+ { \
468
+ JError_t J_Error; \
469
+ if (((Rc) = Func(PArray, Index, Arg2, &J_Error)) == JERR) \
470
+ J_E(FuncName, &J_Error); \
471
+ }
472
+
473
+// Variation for Judy*Count functions, which return 0, not JERR, for error (and
474
+// also for other non-error cases):
475
+//
476
+// Note: JU_ERRNO_NFMAX should only apply to 32-bit Judy1, but this header
477
+// file lacks the necessary ifdefs to make it go away otherwise, so always
478
+// check against it.
479
+
480
+#define J_2C(Rc,PArray,Index1,Index2,Func,FuncName) \
481
+ { \
482
+ JError_t J_Error; \
483
+ if ((((Rc) = Func(PArray, Index1, Index2, &J_Error)) == 0) \
484
+ && (JU_ERRNO(&J_Error) > JU_ERRNO_NFMAX)) \
485
+ { \
486
+ J_E(FuncName, &J_Error); \
487
+ } \
488
+ }
489
+
490
+#define J_2P(PV,PArray,Index,Arg2,Func,FuncName) \
491
+ { \
492
+ JError_t J_Error; \
493
+ if (((PV) = (Pvoid_t) Func(PArray, Index, Arg2, &J_Error)) \
494
+ == PJERR) J_E(FuncName, &J_Error); \
495
+ }
496
+
497
+// Variations for Judy*Set/InsArray functions:
498
+
499
+#define J_2AI(Rc,PArray,Count,PIndex,Func,FuncName) \
500
+ { \
501
+ JError_t J_Error; \
502
+ if (((Rc) = Func(PArray, Count, PIndex, &J_Error)) == JERR) \
503
+ J_E(FuncName, &J_Error); \
504
+ }
505
+
506
+#define J_3AI(Rc,PArray,Count,PIndex,PValue,Func,FuncName) \
507
+ { \
508
+ JError_t J_Error; \
509
+ if (((Rc) = Func(PArray, Count, PIndex, PValue, &J_Error)) \
510
+ == JERR) J_E(FuncName, &J_Error); \
511
+ }
512
+
513
+#endif /* ================ ! JUDYERROR_NOTEST ============================= */
514
+
515
+// Some of the macros are special cases that use inlined shortcuts for speed
516
+// with root-level leaves:
517
+
518
+// This is a slower version with current processors, but in the future...
519
+
520
+#define J1T(Rc,PArray,Index) \
521
+ (Rc) = Judy1Test((Pvoid_t)(PArray), Index, PJE0)
522
+
523
+#define J1S( Rc, PArray, Index) \
524
+ J_1I(Rc, (&(PArray)), Index, Judy1Set, "Judy1Set")
525
+#define J1SA(Rc, PArray, Count, PIndex) \
526
+ J_2AI(Rc,(&(PArray)), Count, PIndex, Judy1SetArray, "Judy1SetArray")
527
+#define J1U( Rc, PArray, Index) \
528
+ J_1I(Rc, (&(PArray)), Index, Judy1Unset, "Judy1Unset")
529
+#define J1F( Rc, PArray, Index) \
530
+ J_1I(Rc, PArray, &(Index), Judy1First, "Judy1First")
531
+#define J1N( Rc, PArray, Index) \
532
+ J_1I(Rc, PArray, &(Index), Judy1Next, "Judy1Next")
533
+#define J1L( Rc, PArray, Index) \
534
+ J_1I(Rc, PArray, &(Index), Judy1Last, "Judy1Last")
535
+#define J1P( Rc, PArray, Index) \
536
+ J_1I(Rc, PArray, &(Index), Judy1Prev, "Judy1Prev")
537
+#define J1FE(Rc, PArray, Index) \
538
+ J_1I(Rc, PArray, &(Index), Judy1FirstEmpty, "Judy1FirstEmpty")
539
+#define J1NE(Rc, PArray, Index) \
540
+ J_1I(Rc, PArray, &(Index), Judy1NextEmpty, "Judy1NextEmpty")
541
+#define J1LE(Rc, PArray, Index) \
542
+ J_1I(Rc, PArray, &(Index), Judy1LastEmpty, "Judy1LastEmpty")
543
+#define J1PE(Rc, PArray, Index) \
544
+ J_1I(Rc, PArray, &(Index), Judy1PrevEmpty, "Judy1PrevEmpty")
545
+#define J1C( Rc, PArray, Index1, Index2) \
546
+ J_2C(Rc, PArray, Index1, Index2, Judy1Count, "Judy1Count")
547
+#define J1BC(Rc, PArray, Count, Index) \
548
+ J_2I(Rc, PArray, Count, &(Index), Judy1ByCount, "Judy1ByCount")
549
+#define J1FA(Rc, PArray) \
550
+ J_0I(Rc, (&(PArray)), Judy1FreeArray, "Judy1FreeArray")
551
+#define J1MU(Rc, PArray) \
552
+ (Rc) = Judy1MemUsed(PArray)
553
+
554
+#define JLG(PV,PArray,Index) \
555
+ (PV) = (Pvoid_t)JudyLGet((Pvoid_t)PArray, Index, PJE0)
556
+
557
+#define JLI( PV, PArray, Index) \
558
+ J_1P(PV, (&(PArray)), Index, JudyLIns, "JudyLIns")
559
+
560
+#define JLIA(Rc, PArray, Count, PIndex, PValue) \
561
+ J_3AI(Rc,(&(PArray)), Count, PIndex, PValue, JudyLInsArray, \
562
+ "JudyLInsArray")
563
+#define JLD( Rc, PArray, Index) \
564
+ J_1I(Rc, (&(PArray)), Index, JudyLDel, "JudyLDel")
565
+
566
+#define JLF( PV, PArray, Index) \
567
+ J_1P(PV, PArray, &(Index), JudyLFirst, "JudyLFirst")
568
+
569
+#define JLN( PV, PArray, Index) \
570
+ J_1P(PV, PArray, &(Index), JudyLNext, "JudyLNext")
571
+
572
+#define JLL( PV, PArray, Index) \
573
+ J_1P(PV, PArray, &(Index), JudyLLast, "JudyLLast")
574
+#define JLP( PV, PArray, Index) \
575
+ J_1P(PV, PArray, &(Index), JudyLPrev, "JudyLPrev")
576
+#define JLFE(Rc, PArray, Index) \
577
+ J_1I(Rc, PArray, &(Index), JudyLFirstEmpty, "JudyLFirstEmpty")
578
+#define JLNE(Rc, PArray, Index) \
579
+ J_1I(Rc, PArray, &(Index), JudyLNextEmpty, "JudyLNextEmpty")
580
+#define JLLE(Rc, PArray, Index) \
581
+ J_1I(Rc, PArray, &(Index), JudyLLastEmpty, "JudyLLastEmpty")
582
+#define JLPE(Rc, PArray, Index) \
583
+ J_1I(Rc, PArray, &(Index), JudyLPrevEmpty, "JudyLPrevEmpty")
584
+#define JLC( Rc, PArray, Index1, Index2) \
585
+ J_2C(Rc, PArray, Index1, Index2, JudyLCount, "JudyLCount")
586
+#define JLBC(PV, PArray, Count, Index) \
587
+ J_2P(PV, PArray, Count, &(Index), JudyLByCount, "JudyLByCount")
588
+#define JLFA(Rc, PArray) \
589
+ J_0I(Rc, (&(PArray)), JudyLFreeArray, "JudyLFreeArray")
590
+#define JLMU(Rc, PArray) \
591
+ (Rc) = JudyLMemUsed(PArray)
592
+
593
+#define JHSI(PV, PArray, PIndex, Count) \
594
+ J_2P(PV, (&(PArray)), PIndex, Count, JudyHSIns, "JudyHSIns")
595
+#define JHSG(PV, PArray, PIndex, Count) \
596
+ (PV) = (Pvoid_t) JudyHSGet(PArray, PIndex, Count)
597
+#define JHSD(Rc, PArray, PIndex, Count) \
598
+ J_2I(Rc, (&(PArray)), PIndex, Count, JudyHSDel, "JudyHSDel")
599
+#define JHSFA(Rc, PArray) \
600
+ J_0I(Rc, (&(PArray)), JudyHSFreeArray, "JudyHSFreeArray")
601
+
602
+#define JSLG( PV, PArray, Index) \
603
+ J_1P( PV, PArray, Index, JudySLGet, "JudySLGet")
604
+#define JSLI( PV, PArray, Index) \
605
+ J_1P( PV, (&(PArray)), Index, JudySLIns, "JudySLIns")
606
+#define JSLD( Rc, PArray, Index) \
607
+ J_1I( Rc, (&(PArray)), Index, JudySLDel, "JudySLDel")
608
+#define JSLF( PV, PArray, Index) \
609
+ J_1P( PV, PArray, Index, JudySLFirst, "JudySLFirst")
610
+#define JSLN( PV, PArray, Index) \
611
+ J_1P( PV, PArray, Index, JudySLNext, "JudySLNext")
612
+#define JSLL( PV, PArray, Index) \
613
+ J_1P( PV, PArray, Index, JudySLLast, "JudySLLast")
614
+#define JSLP( PV, PArray, Index) \
615
+ J_1P( PV, PArray, Index, JudySLPrev, "JudySLPrev")
616
+#define JSLFA(Rc, PArray) \
617
+ J_0I( Rc, (&(PArray)), JudySLFreeArray, "JudySLFreeArray")
618
+
619
+#ifdef __cplusplus
620
+}
621
+#endif
622
+#endif /* ! _JUDY_INCLUDED */
libnetdata/libjudy/src/JudyCommon/JudyMalloc.c
new
+87
@@ -0,0 +1,87 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.33 $ $Source: /judy/src/JudyCommon/JudyMalloc.c $
19
+// ************************************************************************ //
20
+// JUDY - Memory Allocater //
21
+// -by- //
22
+// Douglas L. Baskins //
23
+// Hewlett Packard //
24
+// Fort Collins, Co //
25
+// (970) 229-2027 //
26
+// //
27
+// ************************************************************************ //
28
+
29
+// JUDY INCLUDE FILES
30
+#include "Judy.h"
31
+
32
+// ****************************************************************************
33
+// J U D Y M A L L O C
34
+//
35
+// Allocate RAM. This is the single location in Judy code that calls
36
+// malloc(3C). Note: JPM accounting occurs at a higher level.
37
+
38
+Word_t JudyMalloc(
39
+ Word_t Words)
40
+{
41
+ Word_t Addr;
42
+
43
+ Addr = (Word_t) malloc(Words * sizeof(Word_t));
44
+ return(Addr);
45
+
46
+} // JudyMalloc()
47
+
48
+
49
+// ****************************************************************************
50
+// J U D Y F R E E
51
+
52
+void JudyFree(
53
+ void * PWord,
54
+ Word_t Words)
55
+{
56
+ (void) Words;
57
+ free(PWord);
58
+
59
+} // JudyFree()
60
+
61
+
62
+// ****************************************************************************
63
+// J U D Y M A L L O C
64
+//
65
+// Higher-level "wrapper" for allocating objects that need not be in RAM,
66
+// although at this time they are in fact only in RAM. Later we hope that some
67
+// entire subtrees (at a JPM or branch) can be "virtual", so their allocations
68
+// and frees should go through this level.
69
+
70
+Word_t JudyMallocVirtual(
71
+ Word_t Words)
72
+{
73
+ return(JudyMalloc(Words));
74
+
75
+} // JudyMallocVirtual()
76
+
77
+
78
+// ****************************************************************************
79
+// J U D Y F R E E
80
+
81
+void JudyFreeVirtual(
82
+ void * PWord,
83
+ Word_t Words)
84
+{
85
+ JudyFree(PWord, Words);
86
+
87
+} // JudyFreeVirtual()
libnetdata/libjudy/src/JudyCommon/JudyPrivate.h
new
+1613
@@ -0,0 +1,1613 @@
1
+#ifndef _JUDYPRIVATE_INCLUDED
2
+#define _JUDYPRIVATE_INCLUDED
3
+// _________________
4
+//
5
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
6
+//
7
+// This program is free software; you can redistribute it and/or modify it
8
+// under the term of the GNU Lesser General Public License as published by the
9
+// Free Software Foundation; either version 2 of the License, or (at your
10
+// option) any later version.
11
+//
12
+// This program is distributed in the hope that it will be useful, but WITHOUT
13
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
+// for more details.
16
+//
17
+// You should have received a copy of the GNU Lesser General Public License
18
+// along with this program; if not, write to the Free Software Foundation,
19
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+// _________________
21
+
22
+// @(#) $Revision: 4.77 $ $Source: /judy/src/JudyCommon/JudyPrivate.h $
23
+//
24
+// Header file for all Judy sources, for global but private (non-exported)
25
+// declarations.
26
+
27
+#include "Judy.h"
28
+
29
+// ****************************************************************************
30
+// A VERY BRIEF EXPLANATION OF A JUDY ARRAY
31
+//
32
+// A Judy array is, effectively, a digital tree (or Trie) with 256 element
33
+// branches (nodes), and with "compression tricks" applied to low-population
34
+// branches or leaves to save a lot of memory at the cost of relatively little
35
+// CPU time or cache fills.
36
+//
37
+// In the actual implementation, a Judy array is level-less, and traversing the
38
+// "tree" actually means following the states in a state machine (SM) as
39
+// directed by the Index. A Judy array is referred to here as an "SM", rather
40
+// than as a "tree"; having "states", rather than "levels".
41
+//
42
+// Each branch or leaf in the SM decodes a portion ("digit") of the original
43
+// Index; with 256-way branches there are 8 bits per digit. There are 3 kinds
44
+// of branches, called: Linear, Bitmap and Uncompressed, of which the first 2
45
+// are compressed to contain no NULL entries.
46
+//
47
+// An Uncompressed branch has a 1.0 cache line fill cost to decode 8 bits of
48
+// (digit, part of an Index), but it might contain many NULL entries, and is
49
+// therefore inefficient with memory if lightly populated.
50
+//
51
+// A Linear branch has a ~1.75 cache line fill cost when at maximum population.
52
+// A Bitmap branch has ~2.0 cache line fills. Linear and Bitmap branches are
53
+// converted to Uncompressed branches when the additional memory can be
54
+// amortized with larger populations. Higher-state branches have higher
55
+// priority to be converted.
56
+//
57
+// Linear branches can hold 28 elements (based on detailed analysis) -- thus 28
58
+// expanses. A Linear branch is converted to a Bitmap branch when the 29th
59
+// expanse is required.
60
+//
61
+// A Bitmap branch could hold 256 expanses, but is forced to convert to an
62
+// Uncompressed branch when 185 expanses are required. Hopefully, it is
63
+// converted before that because of population growth (again, based on detailed
64
+// analysis and heuristics in the code).
65
+//
66
+// A path through the SM terminates to a leaf when the Index (or key)
67
+// population in the expanse below a pointer will fit into 1 or 2 cache lines
68
+// (~31..255 Indexes). A maximum-population Leaf has ~1.5 cache line fill
69
+// cost.
70
+//
71
+// Leaves are sorted arrays of Indexes, where the Index Sizes (IS) are: 0, 1,
72
+// 8, 16, 24, 32, [40, 48, 56, 64] bits. The IS depends on the "density"
73
+// (population/expanse) of the values in the Leaf. Zero bits are possible if
74
+// population == expanse in the SM (that is, a full small expanse).
75
+//
76
+// Elements of a branches are called Judy Pointers (JPs). Each JP object
77
+// points to the next object in the SM, plus, a JP can decode an additional
78
+// 2[6] bytes of an Index, but at the cost of "narrowing" the expanse
79
+// represented by the next object in the SM. A "narrow" JP (one which has
80
+// decode bytes/digits) is a way of skipping states in the SM.
81
+//
82
+// Although counterintuitive, we think a Judy SM is optimal when the Leaves are
83
+// stored at MINIMUM compression (narrowing, or use of Decode bytes). If more
84
+// aggressive compression was used, decompression of a leaf be required to
85
+// insert an index. Additional compression would save a little memory but not
86
+// help performance significantly.
87
+
88
+
89
+#ifdef A_PICTURE_IS_WORTH_1000_WORDS
90
+*******************************************************************************
91
+
92
+JUDY 32-BIT STATE MACHINE (SM) EXAMPLE, FOR INDEX = 0x02040103
93
+
94
+The Index used in this example is purposely chosen to allow small, simple
95
+examples below; each 1-byte "digit" from the Index has a small numeric value
96
+that fits in one column. In the drawing below:
97
+
98
+ JRP == Judy Root Pointer;
99
+
100
+ C == 1 byte of a 1..3 byte Population (count of Indexes) below this
101
+ pointer. Since this is shared with the Decode field, the combined
102
+ sizes must be 3[7], that is, 1 word less 1 byte for the JP Type.
103
+
104
+ The 1-byte field jp_Type is represented as:
105
+
106
+ 1..3 == Number of bytes in the population (Pop0) word of the Branch or Leaf
107
+ below the pointer (note: 1..7 on 64-bit); indicates:
108
+ - number of bytes in Decode field == 3 - this number;
109
+ - number of bytes remaining to decode.
110
+ Note: The maximum is 3, not 4, because the 1st byte of the Index is
111
+ always decoded digitally in the top branch.
112
+ -B- == JP points to a Branch (there are many kinds of Branches).
113
+ -L- == JP points to a Leaf (there are many kinds of Leaves).
114
+
115
+ (2) == Digit of Index decoded by position offset in branch (really
116
+ 0..0xff).
117
+
118
+ 4* == Digit of Index necessary for decoding a "narrow" pointer, in a
119
+ Decode field; replaces 1 missing branch (really 0..0xff).
120
+
121
+ 4+ == Digit of Index NOT necessary for decoding a "narrow" pointer, but
122
+ used for fast traversal of the SM by Judy1Test() and JudyLGet()
123
+ (see the code) (really 0..0xff).
124
+
125
+ 0 == Byte in a JPs Pop0 field that is always ignored, because a leaf
126
+ can never contain more than 256 Indexes (Pop0 <= 255).
127
+
128
+ +----- == A Branch or Leaf; drawn open-ended to remind you that it could
129
+ | have up to 256 columns.
130
+ +-----
131
+
132
+ |
133
+ | == Pointer to next Branch or Leaf.
134
+ V
135
+
136
+ |
137
+ O == A state is skipped by using a "narrow" pointer.
138
+ |
139
+
140
+ < 1 > == Digit (Index) shown as an example is not necessarily in the
141
+ position shown; is sorted in order with neighbor Indexes.
142
+ (Really 0..0xff.)
143
+
144
+Note that this example shows every possibly topology to reach a leaf in a
145
+32-bit Judy SM, although this is a very subtle point!
146
+
147
+ STATE or`
148
+ LEVEL
149
+ +---+ +---+ +---+ +---+ +---+ +---+ +---+ +---+
150
+ |RJP| |RJP| |RJP| |RJP| |RJP| |RJP| |RJP| |RJP|
151
+ L---+ B---+ B---+ B---+ B---+ B---+ B---+ B---+
152
+ | | | | | | | |
153
+ | | | | | | | |
154
+ V V (2) V (2) V (2) V (2) V (2) V (2) V (2)
155
+ +------ +------ +------ +------ +------ +------ +------ +------
156
+Four |< 2 > | 0 | 4* | C | 4* | 4* | C | C
157
+byte |< 4 > | 0 | 0 | C | 1* | C | C | C 4
158
+Index|< 1 > | C | C | C | C | C | C | C
159
+Leaf |< 3 > | 3 | 2 | 3 | 1 | 2 | 3 | 3
160
+ +------ +--L--- +--L--- +--B--- +--L--- +--B--- +--B--- +--B---
161
+ | | | | | | |
162
+ / | / | | / /
163
+ / | / | | / /
164
+ | | | | | | |
165
+ V | V (4) | | V (4) V (4)
166
+ +------ | +------ | | +------ +------
167
+ Three |< 4 > | | 4+ | | | 4+ | 4+
168
+ byte Index|< 1 > O | 0 O O | 1* | C 3
169
+ Leaf |< 3 > | | C | | | C | C
170
+ +------ | | 2 | | | 1 | 2
171
+ / +----L- | | +----L- +----B-
172
+ / | | | | |
173
+ | / | / / /
174
+ | / | / / /
175
+ | / | | / /
176
+ | / | | / /
177
+ | | | | | |
178
+ V V | V(1) | V(1)
179
+ +------ +------ | +------ | +------
180
+ Two byte |< 1 > |< 1 > | | 4+ | | 4+
181
+ Index Leaf |< 3 > |< 3 > O | 1+ O | 1+ 2
182
+ +------ +------ / | C | | C
183
+ / | 1 | | 1
184
+ | +-L---- | +-L----
185
+ | | | |
186
+ | / | /
187
+ | | | |
188
+ V V V V
189
+ +------ +------ +------ +------
190
+ One byte Index Leaf |< 3 > |< 3 > |< 3 > |< 3 > 1
191
+ +------ +------ +------ +------
192
+
193
+
194
+#endif // A_PICTURE_IS_WORTH_1000_WORDS
195
+
196
+
197
+// ****************************************************************************
198
+// MISCELLANEOUS GLOBALS:
199
+//
200
+// PLATFORM-SPECIFIC CONVENIENCE MACROS:
201
+//
202
+// These are derived from context (set by cc or in system header files) or
203
+// based on JU_<PLATFORM> macros from make_includes/platform.*.mk. We decided
204
+// on 011018 that any macro reliably derivable from context (cc or headers) for
205
+// ALL platforms supported by Judy is based on that derivation, but ANY
206
+// exception means to stop using the external macro completely and derive from
207
+// JU_<PLATFORM> instead.
208
+
209
+// Other miscellaneous stuff:
210
+
211
+#ifndef _BOOL_T
212
+#define _BOOL_T
213
+typedef int bool_t;
214
+#endif
215
+
216
+#define FUNCTION // null; easy to find functions.
217
+
218
+#ifndef TRUE
219
+#define TRUE 1
220
+#endif
221
+
222
+#ifndef FALSE
223
+#define FALSE 0
224
+#endif
225
+
226
+#ifdef TRACE // turn on all other tracing in the code:
227
+#define TRACEJP 1 // JP traversals in JudyIns.c and JudyDel.c.
228
+#define TRACEJPR 1 // JP traversals in retrieval code, JudyGet.c.
229
+#define TRACECF 1 // cache fills in JudyGet.c.
230
+#define TRACEMI 1 // malloc calls in JudyMallocIF.c.
231
+#define TRACEMF 1 // malloc calls at a lower level in JudyMalloc.c.
232
+#endif
233
+
234
+
235
+// SUPPORT FOR DEBUG-ONLY CODE:
236
+//
237
+// By convention, use -DDEBUG to enable both debug-only code AND assertions in
238
+// the Judy sources.
239
+//
240
+// Invert the sense of assertions, so they are off unless explicitly requested,
241
+// in a uniform way.
242
+//
243
+// Note: It is NOT appropriate to put this in Judy.h; it would mess up
244
+// application code.
245
+
246
+#ifndef DEBUG
247
+#define NDEBUG 1 // must be 1 for "#if".
248
+#endif
249
+
250
+// Shorthand notations to avoid #ifdefs for single-line conditional statements:
251
+//
252
+// Warning: These cannot be used around compiler directives, such as
253
+// "#include", nor in the case where Code contains a comma other than nested
254
+// within parentheses or quotes.
255
+
256
+#ifndef DEBUG
257
+#define DBGCODE(Code) // null.
258
+#else
259
+#define DBGCODE(Code) Code
260
+#endif
261
+
262
+#ifdef JUDY1
263
+#define JUDY1CODE(Code) Code
264
+#define JUDYLCODE(Code) // null.
265
+#endif
266
+
267
+#ifdef JUDYL
268
+#define JUDYLCODE(Code) Code
269
+#define JUDY1CODE(Code) // null.
270
+#endif
271
+
272
+#include <assert.h>
273
+
274
+// ****************************************************************************
275
+// FUNDAMENTAL CONSTANTS FOR MACHINE
276
+// ****************************************************************************
277
+
278
+// Machine (CPU) cache line size:
279
+//
280
+// NOTE: A leaf size of 2 cache lines maximum is the target (optimal) for
281
+// Judy. Its hard to obtain a machines cache line size at compile time, but
282
+// if the machine has an unexpected cache line size, its not devastating if
283
+// the following constants end up causing leaves that are 1 cache line in size,
284
+// or even 4 cache lines in size. The assumed 32-bit system has 16-word =
285
+// 64-byte cache lines, and the assumed 64-bit system has 16-word = 128-byte
286
+// cache lines.
287
+
288
+#ifdef JU_64BIT
289
+#define cJU_BYTESPERCL 128 // cache line size in bytes.
290
+#else
291
+#define cJU_BYTESPERCL 64 // cache line size in bytes.
292
+#endif
293
+
294
+// Bits Per Byte:
295
+
296
+#define cJU_BITSPERBYTE 0x8
297
+
298
+// Bytes Per Word and Bits Per Word, latter assuming sizeof(byte) is 8 bits:
299
+//
300
+// Expect 32 [64] bits per word.
301
+
302
+#define cJU_BYTESPERWORD (sizeof(Word_t))
303
+#define cJU_BITSPERWORD (sizeof(Word_t) * cJU_BITSPERBYTE)
304
+
305
+#define JU_BYTESTOWORDS(BYTES) \
306
+ (((BYTES) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD)
307
+
308
+// A word that is all-ones, normally equal to -1UL, but safer with ~0:
309
+
310
+#define cJU_ALLONES (~0UL)
311
+
312
+// Note, these are forward references, but thats OK:
313
+
314
+#define cJU_FULLBITMAPB ((BITMAPB_t) cJU_ALLONES)
315
+#define cJU_FULLBITMAPL ((BITMAPL_t) cJU_ALLONES)
316
+
317
+
318
+// ****************************************************************************
319
+// MISCELLANEOUS JUDY-SPECIFIC DECLARATIONS
320
+// ****************************************************************************
321
+
322
+// ROOT STATE:
323
+//
324
+// State at the start of the Judy SM, based on 1 byte decoded per state; equal
325
+// to the number of bytes per Index to decode.
326
+
327
+#define cJU_ROOTSTATE (sizeof(Word_t))
328
+
329
+
330
+// SUBEXPANSES PER STATE:
331
+//
332
+// Number of subexpanses per state traversed, which is the number of JPs in a
333
+// branch (actual or theoretical) and the number of bits in a bitmap.
334
+
335
+#define cJU_SUBEXPPERSTATE 256
336
+
337
+
338
+// LEAF AND VALUE POINTERS:
339
+//
340
+// Some other basic object types are in declared in JudyPrivateBranch.h
341
+// (Pjbl_t, Pjbb_t, Pjbu_t, Pjp_t) or are Judy1/L-specific (Pjlb_t). The
342
+// few remaining types are declared below.
343
+//
344
+// Note: Leaf pointers are cast to different-sized objects depending on the
345
+// leafs level, but are at least addresses (not just numbers), so use void *
346
+// (Pvoid_t), not PWord_t or Word_t for them, except use Pjlw_t for whole-word
347
+// (top-level, root-level) leaves. Value areas, however, are always whole
348
+// words.
349
+//
350
+// Furthermore, use Pjll_t only for generic leaf pointers (for various size
351
+// LeafLs). Use Pjlw_t for LeafWs. Use Pleaf (with type uint8_t *, uint16_t
352
+// *, etc) when the leaf index size is known.
353
+
354
+typedef PWord_t Pjlw_t; // pointer to root-level leaf (whole-word indexes).
355
+typedef Pvoid_t Pjll_t; // pointer to lower-level linear leaf.
356
+
357
+#ifdef JUDYL
358
+typedef PWord_t Pjv_t; // pointer to JudyL value area.
359
+#endif
360
+
361
+
362
+// POINTER PREPARATION MACROS:
363
+//
364
+// These macros are used to strip malloc-namespace-type bits from a pointer +
365
+// malloc-type word (which references any Judy mallocd object that might be
366
+// obtained from other than a direct call of malloc()), prior to dereferencing
367
+// the pointer as an address. The malloc-type bits allow Judy mallocd objects
368
+// to come from different "malloc() namespaces".
369
+//
370
+// (root pointer) (JRP, see above)
371
+// jp.jp_Addr generic pointer to next-level node, except when used
372
+// as a JudyL Immed01 value area
373
+// JU_JBB_PJP macro hides jbbs_Pjp (pointer to JP subarray)
374
+// JL_JLB_PVALUE macro hides jLlbs_PValue (pointer to value subarray)
375
+//
376
+// When setting one of these fields or passing an address to j__udyFree*(), the
377
+// "raw" memory address is used; otherwise the memory address must be passed
378
+// through one of the macros below before its dereferenced.
379
+//
380
+// Note: After much study, the typecasts below appear in the macros rather
381
+// than at the point of use, which is both simpler and allows the compiler to
382
+// do type-checking.
383
+
384
+
385
+#define P_JLW( ADDR) ((Pjlw_t) (ADDR)) // root leaf.
386
+#define P_JPM( ADDR) ((Pjpm_t) (ADDR)) // root JPM.
387
+#define P_JBL( ADDR) ((Pjbl_t) (ADDR)) // BranchL.
388
+#define P_JBB( ADDR) ((Pjbb_t) (ADDR)) // BranchB.
389
+#define P_JBU( ADDR) ((Pjbu_t) (ADDR)) // BranchU.
390
+#define P_JLL( ADDR) ((Pjll_t) (ADDR)) // LeafL.
391
+#define P_JLB( ADDR) ((Pjlb_t) (ADDR)) // LeafB1.
392
+#define P_JP( ADDR) ((Pjp_t) (ADDR)) // JP.
393
+
394
+#ifdef JUDYL
395
+#define P_JV( ADDR) ((Pjv_t) (ADDR)) // &value.
396
+#endif
397
+
398
+
399
+// LEAST BYTES:
400
+//
401
+// Mask for least bytes of a word, and a macro to perform this mask on an
402
+// Index.
403
+//
404
+// Note: This macro has been problematic in the past to get right and to make
405
+// portable. Its not OK on all systems to shift by the full word size. This
406
+// macro should allow shifting by 1..N bytes, where N is the word size, but
407
+// should produce a compiler warning if the macro is called with Bytes == 0.
408
+//
409
+// Warning: JU_LEASTBYTESMASK() is not a constant macro unless Bytes is a
410
+// constant; otherwise it is a variable shift, which is expensive on some
411
+// processors.
412
+
413
+#define JU_LEASTBYTESMASK(BYTES) \
414
+ ((0x100UL << (cJU_BITSPERBYTE * ((BYTES) - 1))) - 1)
415
+
416
+#define JU_LEASTBYTES(INDEX,BYTES) ((INDEX) & JU_LEASTBYTESMASK(BYTES))
417
+
418
+
419
+// BITS IN EACH BITMAP SUBEXPANSE FOR BITMAP BRANCH AND LEAF:
420
+//
421
+// The bits per bitmap subexpanse times the number of subexpanses equals a
422
+// constant (cJU_SUBEXPPERSTATE). You can also think of this as a compile-time
423
+// choice of "aspect ratio" for bitmap branches and leaves (which can be set
424
+// independently for each).
425
+//
426
+// A default aspect ratio is hardwired here if not overridden at compile time,
427
+// such as by "EXTCCOPTS=-DBITMAP_BRANCH16x16 make".
428
+
429
+#if (! (defined(BITMAP_BRANCH8x32) || defined(BITMAP_BRANCH16x16) || defined(BITMAP_BRANCH32x8)))
430
+#define BITMAP_BRANCH32x8 1 // 32 bits per subexpanse, 8 subexpanses.
431
+#endif
432
+
433
+#ifdef BITMAP_BRANCH8x32
434
+#define BITMAPB_t uint8_t
435
+#endif
436
+
437
+#ifdef BITMAP_BRANCH16x16
438
+#define BITMAPB_t uint16_t
439
+#endif
440
+
441
+#ifdef BITMAP_BRANCH32x8
442
+#define BITMAPB_t uint32_t
443
+#endif
444
+
445
+// Note: For bitmap leaves, BITMAP_LEAF64x4 is only valid for 64 bit:
446
+//
447
+// Note: Choice of aspect ratio mostly matters for JudyL bitmap leaves. For
448
+// Judy1 the choice doesnt matter much -- the code generated for different
449
+// BITMAP_LEAF* values choices varies, but correctness and performance are the
450
+// same.
451
+
452
+#ifndef JU_64BIT
453
+
454
+#if (! (defined(BITMAP_LEAF8x32) || defined(BITMAP_LEAF16x16) || defined(BITMAP_LEAF32x8)))
455
+#define BITMAP_LEAF32x8 // 32 bits per subexpanse, 8 subexpanses.
456
+#endif
457
+
458
+#else // 32BIT
459
+
460
+#if (! (defined(BITMAP_LEAF8x32) || defined(BITMAP_LEAF16x16) || defined(BITMAP_LEAF32x8) || defined(BITMAP_LEAF64x4)))
461
+#define BITMAP_LEAF64x4 // 64 bits per subexpanse, 4 subexpanses.
462
+
463
+#endif
464
+#endif // JU_64BIT
465
+
466
+#ifdef BITMAP_LEAF8x32
467
+#define BITMAPL_t uint8_t
468
+#endif
469
+
470
+#ifdef BITMAP_LEAF16x16
471
+#define BITMAPL_t uint16_t
472
+#endif
473
+
474
+#ifdef BITMAP_LEAF32x8
475
+#define BITMAPL_t uint32_t
476
+#endif
477
+
478
+#ifdef BITMAP_LEAF64x4
479
+#define BITMAPL_t uint64_t
480
+#endif
481
+
482
+
483
+// EXPORTED DATA AND FUNCTIONS:
484
+
485
+#ifdef JUDY1
486
+extern const uint8_t j__1_BranchBJPPopToWords[];
487
+#endif
488
+
489
+#ifdef JUDYL
490
+extern const uint8_t j__L_BranchBJPPopToWords[];
491
+#endif
492
+
493
+// Fast LeafL search routine used for inlined code:
494
+
495
+#if (! defined(SEARCH_BINARY)) || (! defined(SEARCH_LINEAR))
496
+// default a binary search leaf method
497
+#define SEARCH_BINARY 1
498
+//#define SEARCH_LINEAR 1
499
+#endif
500
+
501
+#ifdef SEARCH_LINEAR
502
+
503
+#define SEARCHLEAFNATIVE(LEAFTYPE,ADDR,POP1,INDEX) \
504
+ LEAFTYPE *P_leaf = (LEAFTYPE *)(ADDR); \
505
+ LEAFTYPE I_ndex = (INDEX); /* with masking */ \
506
+ if (I_ndex > P_leaf[(POP1) - 1]) return(~(POP1)); \
507
+ while(I_ndex > *P_leaf) P_leaf++; \
508
+ if (I_ndex == *P_leaf) return(P_leaf - (LEAFTYPE *)(ADDR)); \
509
+ return(~(P_leaf - (LEAFTYPE *)(ADDR)));
510
+
511
+
512
+#define SEARCHLEAFNONNAT(ADDR,POP1,INDEX,LFBTS,COPYINDEX) \
513
+{ \
514
+ uint8_t *P_leaf, *P_leafEnd; \
515
+ Word_t i_ndex; \
516
+ Word_t I_ndex = JU_LEASTBYTES((INDEX), (LFBTS)); \
517
+ Word_t p_op1; \
518
+ \
519
+ P_leaf = (uint8_t *)(ADDR); \
520
+ P_leafEnd = P_leaf + ((POP1) * (LFBTS)); \
521
+ \
522
+ do { \
523
+ JU_COPY3_PINDEX_TO_LONG(i_ndex, P_leaf); \
524
+ if (I_ndex <= i_ndex) break; \
525
+ P_leaf += (LFBTS); \
526
+ } while (P_leaf < P_leafEnd); \
527
+ \
528
+ p_op1 = (P_leaf - (uint8_t *) (ADDR)) / (LFBTS); \
529
+ if (I_ndex == i_ndex) return(p_op1); \
530
+ return(~p_op1); \
531
+}
532
+#endif // SEARCH_LINEAR
533
+
534
+#ifdef SEARCH_BINARY
535
+
536
+#define SEARCHLEAFNATIVE(LEAFTYPE,ADDR,POP1,INDEX) \
537
+ LEAFTYPE *P_leaf = (LEAFTYPE *)(ADDR); \
538
+ LEAFTYPE I_ndex = (LEAFTYPE)INDEX; /* truncate hi bits */ \
539
+ Word_t l_ow = cJU_ALLONES; \
540
+ Word_t m_id; \
541
+ Word_t h_igh = POP1; \
542
+ \
543
+ while ((h_igh - l_ow) > 1UL) \
544
+ { \
545
+ m_id = (h_igh + l_ow) / 2; \
546
+ if (P_leaf[m_id] > I_ndex) \
547
+ h_igh = m_id; \
548
+ else \
549
+ l_ow = m_id; \
550
+ } \
551
+ if (l_ow == cJU_ALLONES || P_leaf[l_ow] != I_ndex) \
552
+ return(~h_igh); \
553
+ return(l_ow)
554
+
555
+
556
+#define SEARCHLEAFNONNAT(ADDR,POP1,INDEX,LFBTS,COPYINDEX) \
557
+ uint8_t *P_leaf = (uint8_t *)(ADDR); \
558
+ Word_t l_ow = cJU_ALLONES; \
559
+ Word_t m_id; \
560
+ Word_t h_igh = POP1; \
561
+ Word_t I_ndex = JU_LEASTBYTES((INDEX), (LFBTS)); \
562
+ Word_t i_ndex; \
563
+ \
564
+ I_ndex = JU_LEASTBYTES((INDEX), (LFBTS)); \
565
+ \
566
+ while ((h_igh - l_ow) > 1UL) \
567
+ { \
568
+ m_id = (h_igh + l_ow) / 2; \
569
+ COPYINDEX(i_ndex, &P_leaf[m_id * (LFBTS)]); \
570
+ if (i_ndex > I_ndex) \
571
+ h_igh = m_id; \
572
+ else \
573
+ l_ow = m_id; \
574
+ } \
575
+ if (l_ow == cJU_ALLONES) return(~h_igh); \
576
+ \
577
+ COPYINDEX(i_ndex, &P_leaf[l_ow * (LFBTS)]); \
578
+ if (i_ndex != I_ndex) return(~h_igh); \
579
+ return(l_ow)
580
+
581
+#endif // SEARCH_BINARY
582
+
583
+// Fast way to count bits set in 8..32[64]-bit int:
584
+//
585
+// For performance, j__udyCountBits*() are written to take advantage of
586
+// platform-specific features where available.
587
+//
588
+
589
+#ifdef JU_NOINLINE
590
+
591
+extern BITMAPB_t j__udyCountBitsB(BITMAPB_t word);
592
+extern BITMAPL_t j__udyCountBitsL(BITMAPL_t word);
593
+
594
+// Compiler supports inline
595
+
596
+#elif defined(JU_HPUX_IPF)
597
+
598
+#define j__udyCountBitsB(WORD) _Asm_popcnt(WORD)
599
+#define j__udyCountBitsL(WORD) _Asm_popcnt(WORD)
600
+
601
+#elif defined(JU_LINUX_IPF)
602
+
603
+static inline BITMAPB_t j__udyCountBitsB(BITMAPB_t word)
604
+{
605
+ BITMAPB_t result;
606
+ __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (word));
607
+ return(result);
608
+}
609
+
610
+static inline BITMAPL_t j__udyCountBitsL(BITMAPL_t word)
611
+{
612
+ BITMAPL_t result;
613
+ __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (word));
614
+ return(result);
615
+}
616
+
617
+
618
+#else // No instructions available, use inline code
619
+
620
+// ****************************************************************************
621
+// __ J U D Y C O U N T B I T S B
622
+//
623
+// Return the number of bits set in "Word", for a bitmap branch.
624
+//
625
+// Note: Bitmap branches have maximum bitmap size = 32 bits.
626
+
627
+#ifdef JU_WIN
628
+static __inline BITMAPB_t j__udyCountBitsB(BITMAPB_t word)
629
+#else
630
+static inline BITMAPB_t j__udyCountBitsB(BITMAPB_t word)
631
+#endif
632
+{
633
+ word = (word & 0x55555555) + ((word & 0xAAAAAAAA) >> 1);
634
+ word = (word & 0x33333333) + ((word & 0xCCCCCCCC) >> 2);
635
+ word = (word & 0x0F0F0F0F) + ((word & 0xF0F0F0F0) >> 4); // >= 8 bits.
636
+#if defined(BITMAP_BRANCH16x16) || defined(BITMAP_BRANCH32x8)
637
+ word = (word & 0x00FF00FF) + ((word & 0xFF00FF00) >> 8); // >= 16 bits.
638
+#endif
639
+
640
+#ifdef BITMAP_BRANCH32x8
641
+ word = (word & 0x0000FFFF) + ((word & 0xFFFF0000) >> 16); // >= 32 bits.
642
+#endif
643
+ return(word);
644
+
645
+} // j__udyCountBitsB()
646
+
647
+
648
+// ****************************************************************************
649
+// __ J U D Y C O U N T B I T S L
650
+//
651
+// Return the number of bits set in "Word", for a bitmap leaf.
652
+//
653
+// Note: Bitmap branches have maximum bitmap size = 32 bits.
654
+
655
+// Note: Need both 32-bit and 64-bit versions of j__udyCountBitsL() because
656
+// bitmap leaves can have 64-bit bitmaps.
657
+
658
+#ifdef JU_WIN
659
+static __inline BITMAPL_t j__udyCountBitsL(BITMAPL_t word)
660
+#else
661
+static inline BITMAPL_t j__udyCountBitsL(BITMAPL_t word)
662
+#endif
663
+{
664
+#ifndef JU_64BIT
665
+
666
+ word = (word & 0x55555555) + ((word & 0xAAAAAAAA) >> 1);
667
+ word = (word & 0x33333333) + ((word & 0xCCCCCCCC) >> 2);
668
+ word = (word & 0x0F0F0F0F) + ((word & 0xF0F0F0F0) >> 4); // >= 8 bits.
669
+#if defined(BITMAP_LEAF16x16) || defined(BITMAP_LEAF32x8)
670
+ word = (word & 0x00FF00FF) + ((word & 0xFF00FF00) >> 8); // >= 16 bits.
671
+#endif
672
+#ifdef BITMAP_LEAF32x8
673
+ word = (word & 0x0000FFFF) + ((word & 0xFFFF0000) >> 16); // >= 32 bits.
674
+#endif
675
+
676
+#else // JU_64BIT
677
+
678
+ word = (word & 0x5555555555555555) + ((word & 0xAAAAAAAAAAAAAAAA) >> 1);
679
+ word = (word & 0x3333333333333333) + ((word & 0xCCCCCCCCCCCCCCCC) >> 2);
680
+ word = (word & 0x0F0F0F0F0F0F0F0F) + ((word & 0xF0F0F0F0F0F0F0F0) >> 4);
681
+#if defined(BITMAP_LEAF16x16) || defined(BITMAP_LEAF32x8) || defined(BITMAP_LEAF64x4)
682
+ word = (word & 0x00FF00FF00FF00FF) + ((word & 0xFF00FF00FF00FF00) >> 8);
683
+#endif
684
+#if defined(BITMAP_LEAF32x8) || defined(BITMAP_LEAF64x4)
685
+ word = (word & 0x0000FFFF0000FFFF) + ((word & 0xFFFF0000FFFF0000) >>16);
686
+#endif
687
+#ifdef BITMAP_LEAF64x4
688
+ word = (word & 0x00000000FFFFFFFF) + ((word & 0xFFFFFFFF00000000) >>32);
689
+#endif
690
+#endif // JU_64BIT
691
+
692
+ return(word);
693
+
694
+} // j__udyCountBitsL()
695
+
696
+#endif // Compiler supports inline
697
+
698
+// GET POP0:
699
+//
700
+// Get from jp_DcdPopO the Pop0 for various JP Types.
701
+//
702
+// Notes:
703
+//
704
+// - Different macros require different parameters...
705
+//
706
+// - There are no simple macros for cJU_BRANCH* Types because their
707
+// populations must be added up and dont reside in an already-calculated
708
+// place. (TBD: This is no longer true, now its in the JPM.)
709
+//
710
+// - cJU_JPIMM_POP0() is not defined because it would be redundant because the
711
+// Pop1 is already encoded in each enum name.
712
+//
713
+// - A linear or bitmap leaf Pop0 cannot exceed cJU_SUBEXPPERSTATE - 1 (Pop0 =
714
+// 0..255), so use a simpler, faster macro for it than for other JP Types.
715
+//
716
+// - Avoid any complex calculations that would slow down the compiled code.
717
+// Assume these macros are only called for the appropriate JP Types.
718
+// Unfortunately theres no way to trigger an assertion here if the JP type
719
+// is incorrect for the macro, because these are merely expressions, not
720
+// statements.
721
+
722
+#define JU_LEAFW_POP0(JRP) (*P_JLW(JRP))
723
+#define cJU_JPFULLPOPU1_POP0 (cJU_SUBEXPPERSTATE - 1)
724
+
725
+// GET JP Type:
726
+// Since bit fields greater than 32 bits are not supported in some compilers
727
+// the jp_DcdPopO field is expanded to include the jp_Type in the high 8 bits
728
+// of the Word_t.
729
+// First the read macro:
730
+
731
+#define JU_JPTYPE(PJP) ((PJP)->jp_Type)
732
+
733
+#define JU_JPLEAF_POP0(PJP) ((PJP)->jp_DcdP0[sizeof(Word_t) - 2])
734
+
735
+#ifdef JU_64BIT
736
+
737
+#define JU_JPDCDPOP0(PJP) \
738
+ ((Word_t)(PJP)->jp_DcdP0[0] << 48 | \
739
+ (Word_t)(PJP)->jp_DcdP0[1] << 40 | \
740
+ (Word_t)(PJP)->jp_DcdP0[2] << 32 | \
741
+ (Word_t)(PJP)->jp_DcdP0[3] << 24 | \
742
+ (Word_t)(PJP)->jp_DcdP0[4] << 16 | \
743
+ (Word_t)(PJP)->jp_DcdP0[5] << 8 | \
744
+ (Word_t)(PJP)->jp_DcdP0[6])
745
+
746
+
747
+#define JU_JPSETADT(PJP,ADDR,DCDPOP0,TYPE) \
748
+{ \
749
+ (PJP)->jp_Addr = (ADDR); \
750
+ (PJP)->jp_DcdP0[0] = (uint8_t)((Word_t)(DCDPOP0) >> 48); \
751
+ (PJP)->jp_DcdP0[1] = (uint8_t)((Word_t)(DCDPOP0) >> 40); \
752
+ (PJP)->jp_DcdP0[2] = (uint8_t)((Word_t)(DCDPOP0) >> 32); \
753
+ (PJP)->jp_DcdP0[3] = (uint8_t)((Word_t)(DCDPOP0) >> 24); \
754
+ (PJP)->jp_DcdP0[4] = (uint8_t)((Word_t)(DCDPOP0) >> 16); \
755
+ (PJP)->jp_DcdP0[5] = (uint8_t)((Word_t)(DCDPOP0) >> 8); \
756
+ (PJP)->jp_DcdP0[6] = (uint8_t)((Word_t)(DCDPOP0)); \
757
+ (PJP)->jp_Type = (TYPE); \
758
+}
759
+
760
+#else // 32 Bit
761
+
762
+#define JU_JPDCDPOP0(PJP) \
763
+ ((Word_t)(PJP)->jp_DcdP0[0] << 16 | \
764
+ (Word_t)(PJP)->jp_DcdP0[1] << 8 | \
765
+ (Word_t)(PJP)->jp_DcdP0[2])
766
+
767
+
768
+#define JU_JPSETADT(PJP,ADDR,DCDPOP0,TYPE) \
769
+{ \
770
+ (PJP)->jp_Addr = (ADDR); \
771
+ (PJP)->jp_DcdP0[0] = (uint8_t)((Word_t)(DCDPOP0) >> 16); \
772
+ (PJP)->jp_DcdP0[1] = (uint8_t)((Word_t)(DCDPOP0) >> 8); \
773
+ (PJP)->jp_DcdP0[2] = (uint8_t)((Word_t)(DCDPOP0)); \
774
+ (PJP)->jp_Type = (TYPE); \
775
+}
776
+
777
+#endif // 32 Bit
778
+
779
+// NUMBER OF BITS IN A BRANCH OR LEAF BITMAP AND SUBEXPANSE:
780
+//
781
+// Note: cJU_BITSPERBITMAP must be the same as the number of JPs in a branch.
782
+
783
+#define cJU_BITSPERBITMAP cJU_SUBEXPPERSTATE
784
+
785
+// Bitmaps are accessed in units of "subexpanses":
786
+
787
+#define cJU_BITSPERSUBEXPB (sizeof(BITMAPB_t) * cJU_BITSPERBYTE)
788
+#define cJU_NUMSUBEXPB (cJU_BITSPERBITMAP / cJU_BITSPERSUBEXPB)
789
+
790
+#define cJU_BITSPERSUBEXPL (sizeof(BITMAPL_t) * cJU_BITSPERBYTE)
791
+#define cJU_NUMSUBEXPL (cJU_BITSPERBITMAP / cJU_BITSPERSUBEXPL)
792
+
793
+
794
+// MASK FOR A SPECIFIED BIT IN A BITMAP:
795
+//
796
+// Warning: If BitNum is a variable, this results in a variable shift that is
797
+// expensive, at least on some processors. Use with caution.
798
+//
799
+// Warning: BitNum must be less than cJU_BITSPERWORD, that is, 0 ..
800
+// cJU_BITSPERWORD - 1, to avoid a truncated shift on some machines.
801
+//
802
+// TBD: Perhaps use an array[32] of masks instead of calculating them.
803
+
804
+#define JU_BITPOSMASKB(BITNUM) (1L << ((BITNUM) % cJU_BITSPERSUBEXPB))
805
+#define JU_BITPOSMASKL(BITNUM) (1L << ((BITNUM) % cJU_BITSPERSUBEXPL))
806
+
807
+
808
+// TEST/SET/CLEAR A BIT IN A BITMAP LEAF:
809
+//
810
+// Test if a byte-sized Digit (portion of Index) has a corresponding bit set in
811
+// a bitmap, or set a byte-sized Digits bit into a bitmap, by looking up the
812
+// correct subexpanse and then checking/setting the correct bit.
813
+//
814
+// Note: Mask higher bits, if any, for the convenience of the user of this
815
+// macro, in case they pass a full Index, not just a digit. If the caller has
816
+// a true 8-bit digit, make it of type uint8_t and the compiler should skip the
817
+// unnecessary mask step.
818
+
819
+#define JU_SUBEXPL(DIGIT) (((DIGIT) / cJU_BITSPERSUBEXPL) & (cJU_NUMSUBEXPL-1))
820
+
821
+#define JU_BITMAPTESTL(PJLB, INDEX) \
822
+ (JU_JLB_BITMAP(PJLB, JU_SUBEXPL(INDEX)) & JU_BITPOSMASKL(INDEX))
823
+
824
+#define JU_BITMAPSETL(PJLB, INDEX) \
825
+ (JU_JLB_BITMAP(PJLB, JU_SUBEXPL(INDEX)) |= JU_BITPOSMASKL(INDEX))
826
+
827
+#define JU_BITMAPCLEARL(PJLB, INDEX) \
828
+ (JU_JLB_BITMAP(PJLB, JU_SUBEXPL(INDEX)) ^= JU_BITPOSMASKL(INDEX))
829
+
830
+
831
+// MAP BITMAP BIT OFFSET TO DIGIT:
832
+//
833
+// Given a digit variable to set, a bitmap branch or leaf subexpanse (base 0),
834
+// the bitmap (BITMAP*_t) for that subexpanse, and an offset (Nth set bit in
835
+// the bitmap, base 0), compute the digit (also base 0) corresponding to the
836
+// subexpanse and offset by counting all bits in the bitmap until offset+1 set
837
+// bits are seen. Avoid expensive variable shifts. Offset should be less than
838
+// the number of set bits in the bitmap; assert this.
839
+//
840
+// If theres a better way to do this, I dont know what it is.
841
+
842
+#define JU_BITMAPDIGITB(DIGIT,SUBEXP,BITMAP,OFFSET) \
843
+ { \
844
+ BITMAPB_t bitmap = (BITMAP); int remain = (OFFSET); \
845
+ (DIGIT) = (SUBEXP) * cJU_BITSPERSUBEXPB; \
846
+ \
847
+ while ((remain -= (bitmap & 1)) >= 0) \
848
+ { \
849
+ bitmap >>= 1; ++(DIGIT); \
850
+ assert((DIGIT) < ((SUBEXP) + 1) * cJU_BITSPERSUBEXPB); \
851
+ } \
852
+ }
853
+
854
+#define JU_BITMAPDIGITL(DIGIT,SUBEXP,BITMAP,OFFSET) \
855
+ { \
856
+ BITMAPL_t bitmap = (BITMAP); int remain = (OFFSET); \
857
+ (DIGIT) = (SUBEXP) * cJU_BITSPERSUBEXPL; \
858
+ \
859
+ while ((remain -= (bitmap & 1)) >= 0) \
860
+ { \
861
+ bitmap >>= 1; ++(DIGIT); \
862
+ assert((DIGIT) < ((SUBEXP) + 1) * cJU_BITSPERSUBEXPL); \
863
+ } \
864
+ }
865
+
866
+
867
+// MASKS FOR PORTIONS OF 32-BIT WORDS:
868
+//
869
+// These are useful for bitmap subexpanses.
870
+//
871
+// "LOWER"/"HIGHER" means bits representing lower/higher-valued Indexes. The
872
+// exact order of bits in the word is explicit here but is hidden from the
873
+// caller.
874
+//
875
+// "EXC" means exclusive of the specified bit; "INC" means inclusive.
876
+//
877
+// In each case, BitPos is either "JU_BITPOSMASK*(BitNum)", or a variable saved
878
+// from an earlier call of that macro; either way, it must be a 32-bit word
879
+// with a single bit set. In the first case, assume the compiler is smart
880
+// enough to optimize out common subexpressions.
881
+//
882
+// The expressions depend on unsigned decimal math that should be universal.
883
+
884
+#define JU_MASKLOWEREXC( BITPOS) ((BITPOS) - 1)
885
+#define JU_MASKLOWERINC( BITPOS) (JU_MASKLOWEREXC(BITPOS) | (BITPOS))
886
+#define JU_MASKHIGHERINC(BITPOS) (-(BITPOS))
887
+#define JU_MASKHIGHEREXC(BITPOS) (JU_MASKHIGHERINC(BITPOS) ^ (BITPOS))
888
+
889
+
890
+// ****************************************************************************
891
+// SUPPORT FOR NATIVE INDEX SIZES
892
+// ****************************************************************************
893
+//
894
+// Copy a series of generic objects (uint8_t, uint16_t, uint32_t, Word_t) from
895
+// one place to another.
896
+
897
+#define JU_COPYMEM(PDST,PSRC,POP1) \
898
+ { \
899
+ Word_t i_ndex = 0; \
900
+ assert((POP1) > 0); \
901
+ do { (PDST)[i_ndex] = (PSRC)[i_ndex]; } \
902
+ while (++i_ndex < (POP1)); \
903
+ }
904
+
905
+
906
+// ****************************************************************************
907
+// SUPPORT FOR NON-NATIVE INDEX SIZES
908
+// ****************************************************************************
909
+//
910
+// Copy a 3-byte Index pointed by a uint8_t * to a Word_t:
911
+//
912
+#define JU_COPY3_PINDEX_TO_LONG(DESTLONG,PINDEX) \
913
+ DESTLONG = (Word_t)(PINDEX)[0] << 16; \
914
+ DESTLONG += (Word_t)(PINDEX)[1] << 8; \
915
+ DESTLONG += (Word_t)(PINDEX)[2]
916
+
917
+// Copy a Word_t to a 3-byte Index pointed at by a uint8_t *:
918
+
919
+#define JU_COPY3_LONG_TO_PINDEX(PINDEX,SOURCELONG) \
920
+ (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 16); \
921
+ (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 8); \
922
+ (PINDEX)[2] = (uint8_t)((SOURCELONG))
923
+
924
+#ifdef JU_64BIT
925
+
926
+// Copy a 5-byte Index pointed by a uint8_t * to a Word_t:
927
+//
928
+#define JU_COPY5_PINDEX_TO_LONG(DESTLONG,PINDEX) \
929
+ DESTLONG = (Word_t)(PINDEX)[0] << 32; \
930
+ DESTLONG += (Word_t)(PINDEX)[1] << 24; \
931
+ DESTLONG += (Word_t)(PINDEX)[2] << 16; \
932
+ DESTLONG += (Word_t)(PINDEX)[3] << 8; \
933
+ DESTLONG += (Word_t)(PINDEX)[4]
934
+
935
+// Copy a Word_t to a 5-byte Index pointed at by a uint8_t *:
936
+
937
+#define JU_COPY5_LONG_TO_PINDEX(PINDEX,SOURCELONG) \
938
+ (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 32); \
939
+ (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 24); \
940
+ (PINDEX)[2] = (uint8_t)((SOURCELONG) >> 16); \
941
+ (PINDEX)[3] = (uint8_t)((SOURCELONG) >> 8); \
942
+ (PINDEX)[4] = (uint8_t)((SOURCELONG))
943
+
944
+// Copy a 6-byte Index pointed by a uint8_t * to a Word_t:
945
+//
946
+#define JU_COPY6_PINDEX_TO_LONG(DESTLONG,PINDEX) \
947
+ DESTLONG = (Word_t)(PINDEX)[0] << 40; \
948
+ DESTLONG += (Word_t)(PINDEX)[1] << 32; \
949
+ DESTLONG += (Word_t)(PINDEX)[2] << 24; \
950
+ DESTLONG += (Word_t)(PINDEX)[3] << 16; \
951
+ DESTLONG += (Word_t)(PINDEX)[4] << 8; \
952
+ DESTLONG += (Word_t)(PINDEX)[5]
953
+
954
+// Copy a Word_t to a 6-byte Index pointed at by a uint8_t *:
955
+
956
+#define JU_COPY6_LONG_TO_PINDEX(PINDEX,SOURCELONG) \
957
+ (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 40); \
958
+ (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 32); \
959
+ (PINDEX)[2] = (uint8_t)((SOURCELONG) >> 24); \
960
+ (PINDEX)[3] = (uint8_t)((SOURCELONG) >> 16); \
961
+ (PINDEX)[4] = (uint8_t)((SOURCELONG) >> 8); \
962
+ (PINDEX)[5] = (uint8_t)((SOURCELONG))
963
+
964
+// Copy a 7-byte Index pointed by a uint8_t * to a Word_t:
965
+//
966
+#define JU_COPY7_PINDEX_TO_LONG(DESTLONG,PINDEX) \
967
+ DESTLONG = (Word_t)(PINDEX)[0] << 48; \
968
+ DESTLONG += (Word_t)(PINDEX)[1] << 40; \
969
+ DESTLONG += (Word_t)(PINDEX)[2] << 32; \
970
+ DESTLONG += (Word_t)(PINDEX)[3] << 24; \
971
+ DESTLONG += (Word_t)(PINDEX)[4] << 16; \
972
+ DESTLONG += (Word_t)(PINDEX)[5] << 8; \
973
+ DESTLONG += (Word_t)(PINDEX)[6]
974
+
975
+// Copy a Word_t to a 7-byte Index pointed at by a uint8_t *:
976
+
977
+#define JU_COPY7_LONG_TO_PINDEX(PINDEX,SOURCELONG) \
978
+ (PINDEX)[0] = (uint8_t)((SOURCELONG) >> 48); \
979
+ (PINDEX)[1] = (uint8_t)((SOURCELONG) >> 40); \
980
+ (PINDEX)[2] = (uint8_t)((SOURCELONG) >> 32); \
981
+ (PINDEX)[3] = (uint8_t)((SOURCELONG) >> 24); \
982
+ (PINDEX)[4] = (uint8_t)((SOURCELONG) >> 16); \
983
+ (PINDEX)[5] = (uint8_t)((SOURCELONG) >> 8); \
984
+ (PINDEX)[6] = (uint8_t)((SOURCELONG))
985
+
986
+#endif // JU_64BIT
987
+
988
+// ****************************************************************************
989
+// COMMON CODE FRAGMENTS (MACROS)
990
+// ****************************************************************************
991
+//
992
+// These code chunks are shared between various source files.
993
+
994
+
995
+// SET (REPLACE) ONE DIGIT IN AN INDEX:
996
+//
997
+// To avoid endian issues, use masking and ORing, which operates in a
998
+// big-endian register, rather than treating the Index as an array of bytes,
999
+// though that would be simpler, but would operate in endian-specific memory.
1000
+//
1001
+// TBD: This contains two variable shifts, is that bad?
1002
+
1003
+#define JU_SETDIGIT(INDEX,DIGIT,STATE) \
1004
+ (INDEX) = ((INDEX) & (~cJU_MASKATSTATE(STATE))) \
1005
+ | (((Word_t) (DIGIT)) \
1006
+ << (((STATE) - 1) * cJU_BITSPERBYTE))
1007
+
1008
+// Fast version for single LSB:
1009
+
1010
+#define JU_SETDIGIT1(INDEX,DIGIT) (INDEX) = ((INDEX) & ~0xff) | (DIGIT)
1011
+
1012
+
1013
+// SET (REPLACE) "N" LEAST DIGITS IN AN INDEX:
1014
+
1015
+#define JU_SETDIGITS(INDEX,INDEX2,cSTATE) \
1016
+ (INDEX) = ((INDEX ) & (~JU_LEASTBYTESMASK(cSTATE))) \
1017
+ | ((INDEX2) & ( JU_LEASTBYTESMASK(cSTATE)))
1018
+
1019
+// COPY DECODE BYTES FROM JP TO INDEX:
1020
+//
1021
+// Modify Index digit(s) to match the bytes in jp_DcdPopO in case one or more
1022
+// branches are skipped and the digits are significant. Its probably faster
1023
+// to just do this unconditionally than to check if its necessary.
1024
+//
1025
+// To avoid endian issues, use masking and ORing, which operates in a
1026
+// big-endian register, rather than treating the Index as an array of bytes,
1027
+// though that would be simpler, but would operate in endian-specific memory.
1028
+//
1029
+// WARNING: Must not call JU_LEASTBYTESMASK (via cJU_DCDMASK) with Bytes =
1030
+// cJU_ROOTSTATE or a bad mask is generated, but there are no Dcd bytes to copy
1031
+// in this case anyway. In fact there are no Dcd bytes unless State <
1032
+// cJU_ROOTSTATE - 1, so dont call this macro except in those cases.
1033
+//
1034
+// TBD: It would be nice to validate jp_DcdPopO against known digits to ensure
1035
+// no corruption, but this is non-trivial.
1036
+
1037
+#define JU_SETDCD(INDEX,PJP,cSTATE) \
1038
+ (INDEX) = ((INDEX) & ~cJU_DCDMASK(cSTATE)) \
1039
+ | (JU_JPDCDPOP0(PJP) & cJU_DCDMASK(cSTATE))
1040
+
1041
+// INSERT/DELETE AN INDEX IN-PLACE IN MEMORY:
1042
+//
1043
+// Given a pointer to an array of "even" (native), same-sized objects
1044
+// (indexes), the current population of the array, an offset in the array, and
1045
+// a new Index to insert, "shift up" the array elements (Indexes) above the
1046
+// insertion point and insert the new Index. Assume there is sufficient memory
1047
+// to do this.
1048
+//
1049
+// In these macros, "i_offset" is an index offset, and "b_off" is a byte
1050
+// offset for odd Index sizes.
1051
+//
1052
+// Note: Endian issues only arise fro insertion, not deletion, and even for
1053
+// insertion, they are transparent when native (even) objects are used, and
1054
+// handled explicitly for odd (non-native) Index sizes.
1055
+//
1056
+// Note: The following macros are tricky enough that there is some test code
1057
+// for them appended to this file.
1058
+
1059
+#define JU_INSERTINPLACE(PARRAY,POP1,OFFSET,INDEX) \
1060
+ assert((long) (POP1) > 0); \
1061
+ assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \
1062
+ { \
1063
+ Word_t i_offset = (POP1); \
1064
+ \
1065
+ while (i_offset-- > (OFFSET)) \
1066
+ (PARRAY)[i_offset + 1] = (PARRAY)[i_offset]; \
1067
+ \
1068
+ (PARRAY)[OFFSET] = (INDEX); \
1069
+ }
1070
+
1071
+
1072
+// Variation for non-native Indexes, where cIS = Index Size
1073
+// and PByte must point to a uint8_t (byte); shift byte-by-byte:
1074
+//
1075
+
1076
+#define JU_INSERTINPLACE3(PBYTE,POP1,OFFSET,INDEX) \
1077
+{ \
1078
+ Word_t i_off = POP1; \
1079
+ \
1080
+ while (i_off-- > (OFFSET)) \
1081
+ { \
1082
+ Word_t i_dx = i_off * 3; \
1083
+ (PBYTE)[i_dx + 0 + 3] = (PBYTE)[i_dx + 0]; \
1084
+ (PBYTE)[i_dx + 1 + 3] = (PBYTE)[i_dx + 1]; \
1085
+ (PBYTE)[i_dx + 2 + 3] = (PBYTE)[i_dx + 2]; \
1086
+ } \
1087
+ JU_COPY3_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 3]), INDEX); \
1088
+}
1089
+
1090
+#ifdef JU_64BIT
1091
+
1092
+#define JU_INSERTINPLACE5(PBYTE,POP1,OFFSET,INDEX) \
1093
+{ \
1094
+ Word_t i_off = POP1; \
1095
+ \
1096
+ while (i_off-- > (OFFSET)) \
1097
+ { \
1098
+ Word_t i_dx = i_off * 5; \
1099
+ (PBYTE)[i_dx + 0 + 5] = (PBYTE)[i_dx + 0]; \
1100
+ (PBYTE)[i_dx + 1 + 5] = (PBYTE)[i_dx + 1]; \
1101
+ (PBYTE)[i_dx + 2 + 5] = (PBYTE)[i_dx + 2]; \
1102
+ (PBYTE)[i_dx + 3 + 5] = (PBYTE)[i_dx + 3]; \
1103
+ (PBYTE)[i_dx + 4 + 5] = (PBYTE)[i_dx + 4]; \
1104
+ } \
1105
+ JU_COPY5_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 5]), INDEX); \
1106
+}
1107
+
1108
+#define JU_INSERTINPLACE6(PBYTE,POP1,OFFSET,INDEX) \
1109
+{ \
1110
+ Word_t i_off = POP1; \
1111
+ \
1112
+ while (i_off-- > (OFFSET)) \
1113
+ { \
1114
+ Word_t i_dx = i_off * 6; \
1115
+ (PBYTE)[i_dx + 0 + 6] = (PBYTE)[i_dx + 0]; \
1116
+ (PBYTE)[i_dx + 1 + 6] = (PBYTE)[i_dx + 1]; \
1117
+ (PBYTE)[i_dx + 2 + 6] = (PBYTE)[i_dx + 2]; \
1118
+ (PBYTE)[i_dx + 3 + 6] = (PBYTE)[i_dx + 3]; \
1119
+ (PBYTE)[i_dx + 4 + 6] = (PBYTE)[i_dx + 4]; \
1120
+ (PBYTE)[i_dx + 5 + 6] = (PBYTE)[i_dx + 5]; \
1121
+ } \
1122
+ JU_COPY6_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 6]), INDEX); \
1123
+}
1124
+
1125
+#define JU_INSERTINPLACE7(PBYTE,POP1,OFFSET,INDEX) \
1126
+{ \
1127
+ Word_t i_off = POP1; \
1128
+ \
1129
+ while (i_off-- > (OFFSET)) \
1130
+ { \
1131
+ Word_t i_dx = i_off * 7; \
1132
+ (PBYTE)[i_dx + 0 + 7] = (PBYTE)[i_dx + 0]; \
1133
+ (PBYTE)[i_dx + 1 + 7] = (PBYTE)[i_dx + 1]; \
1134
+ (PBYTE)[i_dx + 2 + 7] = (PBYTE)[i_dx + 2]; \
1135
+ (PBYTE)[i_dx + 3 + 7] = (PBYTE)[i_dx + 3]; \
1136
+ (PBYTE)[i_dx + 4 + 7] = (PBYTE)[i_dx + 4]; \
1137
+ (PBYTE)[i_dx + 5 + 7] = (PBYTE)[i_dx + 5]; \
1138
+ (PBYTE)[i_dx + 6 + 7] = (PBYTE)[i_dx + 6]; \
1139
+ } \
1140
+ JU_COPY7_LONG_TO_PINDEX(&((PBYTE)[(OFFSET) * 7]), INDEX); \
1141
+}
1142
+#endif // JU_64BIT
1143
+
1144
+// Counterparts to the above for deleting an Index:
1145
+//
1146
+// "Shift down" the array elements starting at the Index to be deleted.
1147
+
1148
+#define JU_DELETEINPLACE(PARRAY,POP1,OFFSET,IGNORE) \
1149
+ assert((long) (POP1) > 0); \
1150
+ assert((Word_t) (OFFSET) < (Word_t) (POP1)); \
1151
+ { \
1152
+ Word_t i_offset = (OFFSET); \
1153
+ \
1154
+ while (++i_offset < (POP1)) \
1155
+ (PARRAY)[i_offset - 1] = (PARRAY)[i_offset]; \
1156
+ }
1157
+
1158
+// Variation for odd-byte-sized (non-native) Indexes, where cIS = Index Size
1159
+// and PByte must point to a uint8_t (byte); copy byte-by-byte:
1160
+//
1161
+// Note: If cIS == 1, JU_DELETEINPLACE_ODD == JU_DELETEINPLACE.
1162
+//
1163
+// Note: There are no endian issues here because bytes are just shifted as-is,
1164
+// not converted to/from an Index.
1165
+
1166
+#define JU_DELETEINPLACE_ODD(PBYTE,POP1,OFFSET,cIS) \
1167
+ assert((long) (POP1) > 0); \
1168
+ assert((Word_t) (OFFSET) < (Word_t) (POP1)); \
1169
+ { \
1170
+ Word_t b_off = (((OFFSET) + 1) * (cIS)) - 1; \
1171
+ \
1172
+ while (++b_off < ((POP1) * (cIS))) \
1173
+ (PBYTE)[b_off - (cIS)] = (PBYTE)[b_off]; \
1174
+ }
1175
+
1176
+
1177
+// INSERT/DELETE AN INDEX WHILE COPYING OTHERS:
1178
+//
1179
+// Copy PSource[] to PDest[], where PSource[] has Pop1 elements (Indexes),
1180
+// inserting Index at PDest[Offset]. Unlike JU_*INPLACE*() above, these macros
1181
+// are used when moving Indexes from one memory object to another.
1182
+
1183
+#define JU_INSERTCOPY(PDEST,PSOURCE,POP1,OFFSET,INDEX) \
1184
+ assert((long) (POP1) > 0); \
1185
+ assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \
1186
+ { \
1187
+ Word_t i_offset; \
1188
+ \
1189
+ for (i_offset = 0; i_offset < (OFFSET); ++i_offset) \
1190
+ (PDEST)[i_offset] = (PSOURCE)[i_offset]; \
1191
+ \
1192
+ (PDEST)[i_offset] = (INDEX); \
1193
+ \
1194
+ for (/* null */; i_offset < (POP1); ++i_offset) \
1195
+ (PDEST)[i_offset + 1] = (PSOURCE)[i_offset]; \
1196
+ }
1197
+
1198
+#define JU_INSERTCOPY3(PDEST,PSOURCE,POP1,OFFSET,INDEX) \
1199
+assert((long) (POP1) > 0); \
1200
+assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \
1201
+{ \
1202
+ Word_t o_ff; \
1203
+ \
1204
+ for (o_ff = 0; o_ff < (OFFSET); o_ff++) \
1205
+ { \
1206
+ Word_t i_dx = o_ff * 3; \
1207
+ (PDEST)[i_dx + 0] = (PSOURCE)[i_dx + 0]; \
1208
+ (PDEST)[i_dx + 1] = (PSOURCE)[i_dx + 1]; \
1209
+ (PDEST)[i_dx + 2] = (PSOURCE)[i_dx + 2]; \
1210
+ } \
1211
+ JU_COPY3_LONG_TO_PINDEX(&((PDEST)[(OFFSET) * 3]), INDEX); \
1212
+ \
1213
+ for (/* null */; o_ff < (POP1); o_ff++) \
1214
+ { \
1215
+ Word_t i_dx = o_ff * 3; \
1216
+ (PDEST)[i_dx + 0 + 3] = (PSOURCE)[i_dx + 0]; \
1217
+ (PDEST)[i_dx + 1 + 3] = (PSOURCE)[i_dx + 1]; \
1218
+ (PDEST)[i_dx + 2 + 3] = (PSOURCE)[i_dx + 2]; \
1219
+ } \
1220
+}
1221
+
1222
+#ifdef JU_64BIT
1223
+
1224
+#define JU_INSERTCOPY5(PDEST,PSOURCE,POP1,OFFSET,INDEX) \
1225
+assert((long) (POP1) > 0); \
1226
+assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \
1227
+{ \
1228
+ Word_t o_ff; \
1229
+ \
1230
+ for (o_ff = 0; o_ff < (OFFSET); o_ff++) \
1231
+ { \
1232
+ Word_t i_dx = o_ff * 5; \
1233
+ (PDEST)[i_dx + 0] = (PSOURCE)[i_dx + 0]; \
1234
+ (PDEST)[i_dx + 1] = (PSOURCE)[i_dx + 1]; \
1235
+ (PDEST)[i_dx + 2] = (PSOURCE)[i_dx + 2]; \
1236
+ (PDEST)[i_dx + 3] = (PSOURCE)[i_dx + 3]; \
1237
+ (PDEST)[i_dx + 4] = (PSOURCE)[i_dx + 4]; \
1238
+ } \
1239
+ JU_COPY5_LONG_TO_PINDEX(&((PDEST)[(OFFSET) * 5]), INDEX); \
1240
+ \
1241
+ for (/* null */; o_ff < (POP1); o_ff++) \
1242
+ { \
1243
+ Word_t i_dx = o_ff * 5; \
1244
+ (PDEST)[i_dx + 0 + 5] = (PSOURCE)[i_dx + 0]; \
1245
+ (PDEST)[i_dx + 1 + 5] = (PSOURCE)[i_dx + 1]; \
1246
+ (PDEST)[i_dx + 2 + 5] = (PSOURCE)[i_dx + 2]; \
1247
+ (PDEST)[i_dx + 3 + 5] = (PSOURCE)[i_dx + 3]; \
1248
+ (PDEST)[i_dx + 4 + 5] = (PSOURCE)[i_dx + 4]; \
1249
+ } \
1250
+}
1251
+
1252
+#define JU_INSERTCOPY6(PDEST,PSOURCE,POP1,OFFSET,INDEX) \
1253
+assert((long) (POP1) > 0); \
1254
+assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \
1255
+{ \
1256
+ Word_t o_ff; \
1257
+ \
1258
+ for (o_ff = 0; o_ff < (OFFSET); o_ff++) \
1259
+ { \
1260
+ Word_t i_dx = o_ff * 6; \
1261
+ (PDEST)[i_dx + 0] = (PSOURCE)[i_dx + 0]; \
1262
+ (PDEST)[i_dx + 1] = (PSOURCE)[i_dx + 1]; \
1263
+ (PDEST)[i_dx + 2] = (PSOURCE)[i_dx + 2]; \
1264
+ (PDEST)[i_dx + 3] = (PSOURCE)[i_dx + 3]; \
1265
+ (PDEST)[i_dx + 4] = (PSOURCE)[i_dx + 4]; \
1266
+ (PDEST)[i_dx + 5] = (PSOURCE)[i_dx + 5]; \
1267
+ } \
1268
+ JU_COPY6_LONG_TO_PINDEX(&((PDEST)[(OFFSET) * 6]), INDEX); \
1269
+ \
1270
+ for (/* null */; o_ff < (POP1); o_ff++) \
1271
+ { \
1272
+ Word_t i_dx = o_ff * 6; \
1273
+ (PDEST)[i_dx + 0 + 6] = (PSOURCE)[i_dx + 0]; \
1274
+ (PDEST)[i_dx + 1 + 6] = (PSOURCE)[i_dx + 1]; \
1275
+ (PDEST)[i_dx + 2 + 6] = (PSOURCE)[i_dx + 2]; \
1276
+ (PDEST)[i_dx + 3 + 6] = (PSOURCE)[i_dx + 3]; \
1277
+ (PDEST)[i_dx + 4 + 6] = (PSOURCE)[i_dx + 4]; \
1278
+ (PDEST)[i_dx + 5 + 6] = (PSOURCE)[i_dx + 5]; \
1279
+ } \
1280
+}
1281
+
1282
+#define JU_INSERTCOPY7(PDEST,PSOURCE,POP1,OFFSET,INDEX) \
1283
+assert((long) (POP1) > 0); \
1284
+assert((Word_t) (OFFSET) <= (Word_t) (POP1)); \
1285
+{ \
1286
+ Word_t o_ff; \
1287
+ \
1288
+ for (o_ff = 0; o_ff < (OFFSET); o_ff++) \
1289
+ { \
1290
+ Word_t i_dx = o_ff * 7; \
1291
+ (PDEST)[i_dx + 0] = (PSOURCE)[i_dx + 0]; \
1292
+ (PDEST)[i_dx + 1] = (PSOURCE)[i_dx + 1]; \
1293
+ (PDEST)[i_dx + 2] = (PSOURCE)[i_dx + 2]; \
1294
+ (PDEST)[i_dx + 3] = (PSOURCE)[i_dx + 3]; \
1295
+ (PDEST)[i_dx + 4] = (PSOURCE)[i_dx + 4]; \
1296
+ (PDEST)[i_dx + 5] = (PSOURCE)[i_dx + 5]; \
1297
+ (PDEST)[i_dx + 6] = (PSOURCE)[i_dx + 6]; \
1298
+ } \
1299
+ JU_COPY7_LONG_TO_PINDEX(&((PDEST)[(OFFSET) * 7]), INDEX); \
1300
+ \
1301
+ for (/* null */; o_ff < (POP1); o_ff++) \
1302
+ { \
1303
+ Word_t i_dx = o_ff * 7; \
1304
+ (PDEST)[i_dx + 0 + 7] = (PSOURCE)[i_dx + 0]; \
1305
+ (PDEST)[i_dx + 1 + 7] = (PSOURCE)[i_dx + 1]; \
1306
+ (PDEST)[i_dx + 2 + 7] = (PSOURCE)[i_dx + 2]; \
1307
+ (PDEST)[i_dx + 3 + 7] = (PSOURCE)[i_dx + 3]; \
1308
+ (PDEST)[i_dx + 4 + 7] = (PSOURCE)[i_dx + 4]; \
1309
+ (PDEST)[i_dx + 5 + 7] = (PSOURCE)[i_dx + 5]; \
1310
+ (PDEST)[i_dx + 6 + 7] = (PSOURCE)[i_dx + 6]; \
1311
+ } \
1312
+}
1313
+
1314
+#endif // JU_64BIT
1315
+
1316
+// Counterparts to the above for deleting an Index:
1317
+
1318
+#define JU_DELETECOPY(PDEST,PSOURCE,POP1,OFFSET,IGNORE) \
1319
+ assert((long) (POP1) > 0); \
1320
+ assert((Word_t) (OFFSET) < (Word_t) (POP1)); \
1321
+ { \
1322
+ Word_t i_offset; \
1323
+ \
1324
+ for (i_offset = 0; i_offset < (OFFSET); ++i_offset) \
1325
+ (PDEST)[i_offset] = (PSOURCE)[i_offset]; \
1326
+ \
1327
+ for (++i_offset; i_offset < (POP1); ++i_offset) \
1328
+ (PDEST)[i_offset - 1] = (PSOURCE)[i_offset]; \
1329
+ }
1330
+
1331
+// Variation for odd-byte-sized (non-native) Indexes, where cIS = Index Size;
1332
+// copy byte-by-byte:
1333
+//
1334
+// Note: There are no endian issues here because bytes are just shifted as-is,
1335
+// not converted to/from an Index.
1336
+//
1337
+// Note: If cIS == 1, JU_DELETECOPY_ODD == JU_DELETECOPY, at least in concept.
1338
+
1339
+#define JU_DELETECOPY_ODD(PDEST,PSOURCE,POP1,OFFSET,cIS) \
1340
+ assert((long) (POP1) > 0); \
1341
+ assert((Word_t) (OFFSET) < (Word_t) (POP1)); \
1342
+ { \
1343
+ uint8_t *_Pdest = (uint8_t *) (PDEST); \
1344
+ uint8_t *_Psource = (uint8_t *) (PSOURCE); \
1345
+ Word_t b_off; \
1346
+ \
1347
+ for (b_off = 0; b_off < ((OFFSET) * (cIS)); ++b_off) \
1348
+ *_Pdest++ = *_Psource++; \
1349
+ \
1350
+ _Psource += (cIS); \
1351
+ \
1352
+ for (b_off += (cIS); b_off < ((POP1) * (cIS)); ++b_off) \
1353
+ *_Pdest++ = *_Psource++; \
1354
+ }
1355
+
1356
+
1357
+// GENERIC RETURN CODE HANDLING FOR JUDY1 (NO VALUE AREAS) AND JUDYL (VALUE
1358
+// AREAS):
1359
+//
1360
+// This common code hides Judy1 versus JudyL details of how to return various
1361
+// conditions, including a pointer to a value area for JudyL.
1362
+//
1363
+// First, define an internal variation of JERR called JERRI (I = int) to make
1364
+// lint happy. We accidentally shipped to 11.11 OEUR with all functions that
1365
+// return int or Word_t using JERR, which is type Word_t, for errors. Lint
1366
+// complains about this for functions that return int. So, internally use
1367
+// JERRI for error returns from the int functions. Experiments show that
1368
+// callers which compare int Foo() to (Word_t) JERR (~0UL) are OK, since JERRI
1369
+// sign-extends to match JERR.
1370
+
1371
+#define JERRI ((int) ~0) // see above.
1372
+
1373
+#ifdef JUDY1
1374
+
1375
+#define JU_RET_FOUND return(1)
1376
+#define JU_RET_NOTFOUND return(0)
1377
+
1378
+// For Judy1, these all "fall through" to simply JU_RET_FOUND, since there is no
1379
+// value area pointer to return:
1380
+
1381
+#define JU_RET_FOUND_LEAFW(PJLW,POP1,OFFSET) JU_RET_FOUND
1382
+
1383
+#define JU_RET_FOUND_JPM(Pjpm) JU_RET_FOUND
1384
+#define JU_RET_FOUND_PVALUE(Pjv,OFFSET) JU_RET_FOUND
1385
+#ifndef JU_64BIT
1386
+#define JU_RET_FOUND_LEAF1(Pjll,POP1,OFFSET) JU_RET_FOUND
1387
+#endif
1388
+#define JU_RET_FOUND_LEAF2(Pjll,POP1,OFFSET) JU_RET_FOUND
1389
+#define JU_RET_FOUND_LEAF3(Pjll,POP1,OFFSET) JU_RET_FOUND
1390
+#ifdef JU_64BIT
1391
+#define JU_RET_FOUND_LEAF4(Pjll,POP1,OFFSET) JU_RET_FOUND
1392
+#define JU_RET_FOUND_LEAF5(Pjll,POP1,OFFSET) JU_RET_FOUND
1393
+#define JU_RET_FOUND_LEAF6(Pjll,POP1,OFFSET) JU_RET_FOUND
1394
+#define JU_RET_FOUND_LEAF7(Pjll,POP1,OFFSET) JU_RET_FOUND
1395
+#endif
1396
+#define JU_RET_FOUND_IMM_01(Pjp) JU_RET_FOUND
1397
+#define JU_RET_FOUND_IMM(Pjp,OFFSET) JU_RET_FOUND
1398
+
1399
+// Note: No JudyL equivalent:
1400
+
1401
+#define JU_RET_FOUND_FULLPOPU1 JU_RET_FOUND
1402
+#define JU_RET_FOUND_LEAF_B1(PJLB,SUBEXP,OFFSET) JU_RET_FOUND
1403
+
1404
+#else // JUDYL
1405
+
1406
+// JU_RET_FOUND // see below; must NOT be defined for JudyL.
1407
+#define JU_RET_NOTFOUND return((PPvoid_t) NULL)
1408
+
1409
+// For JudyL, the location of the value area depends on the JP type and other
1410
+// factors:
1411
+//
1412
+// TBD: The value areas should be accessed via data structures, here and in
1413
+// Dougs code, not by hard-coded address calculations.
1414
+//
1415
+// This is useful in insert/delete code when the value area is returned from
1416
+// lower levels in the JPM:
1417
+
1418
+#define JU_RET_FOUND_JPM(Pjpm) return((PPvoid_t) ((Pjpm)->jpm_PValue))
1419
+
1420
+// This is useful in insert/delete code when the value area location is already
1421
+// computed:
1422
+
1423
+#define JU_RET_FOUND_PVALUE(Pjv,OFFSET) return((PPvoid_t) ((Pjv) + OFFSET))
1424
+
1425
+#define JU_RET_FOUND_LEAFW(PJLW,POP1,OFFSET) \
1426
+ return((PPvoid_t) (JL_LEAFWVALUEAREA(PJLW, POP1) + (OFFSET)))
1427
+
1428
+#define JU_RET_FOUND_LEAF1(Pjll,POP1,OFFSET) \
1429
+ return((PPvoid_t) (JL_LEAF1VALUEAREA(Pjll, POP1) + (OFFSET)))
1430
+#define JU_RET_FOUND_LEAF2(Pjll,POP1,OFFSET) \
1431
+ return((PPvoid_t) (JL_LEAF2VALUEAREA(Pjll, POP1) + (OFFSET)))
1432
+#define JU_RET_FOUND_LEAF3(Pjll,POP1,OFFSET) \
1433
+ return((PPvoid_t) (JL_LEAF3VALUEAREA(Pjll, POP1) + (OFFSET)))
1434
+#ifdef JU_64BIT
1435
+#define JU_RET_FOUND_LEAF4(Pjll,POP1,OFFSET) \
1436
+ return((PPvoid_t) (JL_LEAF4VALUEAREA(Pjll, POP1) + (OFFSET)))
1437
+#define JU_RET_FOUND_LEAF5(Pjll,POP1,OFFSET) \
1438
+ return((PPvoid_t) (JL_LEAF5VALUEAREA(Pjll, POP1) + (OFFSET)))
1439
+#define JU_RET_FOUND_LEAF6(Pjll,POP1,OFFSET) \
1440
+ return((PPvoid_t) (JL_LEAF6VALUEAREA(Pjll, POP1) + (OFFSET)))
1441
+#define JU_RET_FOUND_LEAF7(Pjll,POP1,OFFSET) \
1442
+ return((PPvoid_t) (JL_LEAF7VALUEAREA(Pjll, POP1) + (OFFSET)))
1443
+#endif
1444
+
1445
+// Note: Here jp_Addr is a value area itself and not an address, so P_JV() is
1446
+// not needed:
1447
+
1448
+#define JU_RET_FOUND_IMM_01(PJP) return((PPvoid_t) (&((PJP)->jp_Addr)))
1449
+
1450
+// Note: Here jp_Addr is a pointer to a separately-mallocd value area, so
1451
+// P_JV() is required; likewise for JL_JLB_PVALUE:
1452
+
1453
+#define JU_RET_FOUND_IMM(PJP,OFFSET) \
1454
+ return((PPvoid_t) (P_JV((PJP)->jp_Addr) + (OFFSET)))
1455
+
1456
+#define JU_RET_FOUND_LEAF_B1(PJLB,SUBEXP,OFFSET) \
1457
+ return((PPvoid_t) (P_JV(JL_JLB_PVALUE(PJLB, SUBEXP)) + (OFFSET)))
1458
+
1459
+#endif // JUDYL
1460
+
1461
+
1462
+// GENERIC ERROR HANDLING:
1463
+//
1464
+// This is complicated by variations in the needs of the callers of these
1465
+// macros. Only use JU_SET_ERRNO() for PJError, because it can be null; use
1466
+// JU_SET_ERRNO_NONNULL() for Pjpm, which is never null, and also in other
1467
+// cases where the pointer is known not to be null (to save dead branches).
1468
+//
1469
+// Note: Most cases of JU_ERRNO_OVERRUN or JU_ERRNO_CORRUPT should result in
1470
+// an assertion failure in debug code, so they are more likely to be caught, so
1471
+// do that here in each macro.
1472
+
1473
+#define JU_SET_ERRNO(PJError, JErrno) \
1474
+ { \
1475
+ assert((JErrno) != JU_ERRNO_OVERRUN); \
1476
+ assert((JErrno) != JU_ERRNO_CORRUPT); \
1477
+ \
1478
+ if (PJError != (PJError_t) NULL) \
1479
+ { \
1480
+ JU_ERRNO(PJError) = (JErrno); \
1481
+ JU_ERRID(PJError) = __LINE__; \
1482
+ } \
1483
+ }
1484
+
1485
+// Variation for callers who know already that PJError is non-null; and, it can
1486
+// also be Pjpm (both PJError_t and Pjpm_t have je_* fields), so only assert it
1487
+// for null, not cast to any specific pointer type:
1488
+
1489
+#define JU_SET_ERRNO_NONNULL(PJError, JErrno) \
1490
+ { \
1491
+ assert((JErrno) != JU_ERRNO_OVERRUN); \
1492
+ assert((JErrno) != JU_ERRNO_CORRUPT); \
1493
+ assert(PJError); \
1494
+ \
1495
+ JU_ERRNO(PJError) = (JErrno); \
1496
+ JU_ERRID(PJError) = __LINE__; \
1497
+ }
1498
+
1499
+// Variation to copy error info from a (required) JPM to an (optional)
1500
+// PJError_t:
1501
+//
1502
+// Note: The assertions above about JU_ERRNO_OVERRUN and JU_ERRNO_CORRUPT
1503
+// should have already popped, so they are not needed here.
1504
+
1505
+#define JU_COPY_ERRNO(PJError, Pjpm) \
1506
+ { \
1507
+ if (PJError) \
1508
+ { \
1509
+ JU_ERRNO(PJError) = (uint8_t)JU_ERRNO(Pjpm); \
1510
+ JU_ERRID(PJError) = JU_ERRID(Pjpm); \
1511
+ } \
1512
+ }
1513
+
1514
+// For JErrno parameter to previous macros upon return from Judy*Alloc*():
1515
+//
1516
+// The memory allocator returns an address of 0 for out of memory,
1517
+// 1..sizeof(Word_t)-1 for corruption (an invalid pointer), otherwise a valid
1518
+// pointer.
1519
+
1520
+#define JU_ALLOC_ERRNO(ADDR) \
1521
+ (((void *) (ADDR) != (void *) NULL) ? JU_ERRNO_OVERRUN : JU_ERRNO_NOMEM)
1522
+
1523
+#define JU_CHECKALLOC(Type,Ptr,Retval) \
1524
+ if ((Ptr) < (Type) sizeof(Word_t)) \
1525
+ { \
1526
+ JU_SET_ERRNO(PJError, JU_ALLOC_ERRNO(Ptr)); \
1527
+ return(Retval); \
1528
+ }
1529
+
1530
+// Leaf search routines
1531
+
1532
+#ifdef JU_NOINLINE
1533
+
1534
+int j__udySearchLeaf1(Pjll_t Pjll, Word_t LeafPop1, Word_t Index);
1535
+int j__udySearchLeaf2(Pjll_t Pjll, Word_t LeafPop1, Word_t Index);
1536
+int j__udySearchLeaf3(Pjll_t Pjll, Word_t LeafPop1, Word_t Index);
1537
+
1538
+#ifdef JU_64BIT
1539
+
1540
+int j__udySearchLeaf4(Pjll_t Pjll, Word_t LeafPop1, Word_t Index);
1541
+int j__udySearchLeaf5(Pjll_t Pjll, Word_t LeafPop1, Word_t Index);
1542
+int j__udySearchLeaf6(Pjll_t Pjll, Word_t LeafPop1, Word_t Index);
1543
+int j__udySearchLeaf7(Pjll_t Pjll, Word_t LeafPop1, Word_t Index);
1544
+
1545
+#endif // JU_64BIT
1546
+
1547
+int j__udySearchLeafW(Pjlw_t Pjlw, Word_t LeafPop1, Word_t Index);
1548
+
1549
+#else // complier support for inline
1550
+
1551
+#ifdef JU_WIN
1552
+static __inline int j__udySearchLeaf1(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1553
+#else
1554
+static inline int j__udySearchLeaf1(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1555
+#endif
1556
+{ SEARCHLEAFNATIVE(uint8_t, Pjll, LeafPop1, Index); }
1557
+
1558
+#ifdef JU_WIN
1559
+static __inline int j__udySearchLeaf2(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1560
+#else
1561
+static inline int j__udySearchLeaf2(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1562
+#endif
1563
+{ SEARCHLEAFNATIVE(uint16_t, Pjll, LeafPop1, Index); }
1564
+
1565
+#ifdef JU_WIN
1566
+static __inline int j__udySearchLeaf3(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1567
+#else
1568
+static inline int j__udySearchLeaf3(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1569
+#endif
1570
+{ SEARCHLEAFNONNAT(Pjll, LeafPop1, Index, 3, JU_COPY3_PINDEX_TO_LONG); }
1571
+
1572
+#ifdef JU_64BIT
1573
+
1574
+#ifdef JU_WIN
1575
+static __inline int j__udySearchLeaf4(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1576
+#else
1577
+static inline int j__udySearchLeaf4(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1578
+#endif
1579
+{ SEARCHLEAFNATIVE(uint32_t, Pjll, LeafPop1, Index); }
1580
+
1581
+#ifdef JU_WIN
1582
+static __inline int j__udySearchLeaf5(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1583
+#else
1584
+static inline int j__udySearchLeaf5(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1585
+#endif
1586
+{ SEARCHLEAFNONNAT(Pjll, LeafPop1, Index, 5, JU_COPY5_PINDEX_TO_LONG); }
1587
+
1588
+#ifdef JU_WIN
1589
+static __inline int j__udySearchLeaf6(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1590
+#else
1591
+static inline int j__udySearchLeaf6(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1592
+#endif
1593
+{ SEARCHLEAFNONNAT(Pjll, LeafPop1, Index, 6, JU_COPY6_PINDEX_TO_LONG); }
1594
+
1595
+#ifdef JU_WIN
1596
+static __inline int j__udySearchLeaf7(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1597
+#else
1598
+static inline int j__udySearchLeaf7(Pjll_t Pjll, Word_t LeafPop1, Word_t Index)
1599
+#endif
1600
+{ SEARCHLEAFNONNAT(Pjll, LeafPop1, Index, 7, JU_COPY7_PINDEX_TO_LONG); }
1601
+
1602
+#endif // JU_64BIT
1603
+
1604
+#ifdef JU_WIN
1605
+static __inline int j__udySearchLeafW(Pjlw_t Pjlw, Word_t LeafPop1, Word_t Index)
1606
+#else
1607
+static inline int j__udySearchLeafW(Pjlw_t Pjlw, Word_t LeafPop1, Word_t Index)
1608
+#endif
1609
+{ SEARCHLEAFNATIVE(Word_t, Pjlw, LeafPop1, Index); }
1610
+
1611
+#endif // compiler support for inline
1612
+
1613
+#endif // ! _JUDYPRIVATE_INCLUDED
libnetdata/libjudy/src/JudyCommon/JudyPrivate1L.h
new
+485
@@ -0,0 +1,485 @@
1
+#ifndef _JUDYPRIVATE1L_INCLUDED
2
+#define _JUDYPRIVATE1L_INCLUDED
3
+// _________________
4
+//
5
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
6
+//
7
+// This program is free software; you can redistribute it and/or modify it
8
+// under the term of the GNU Lesser General Public License as published by the
9
+// Free Software Foundation; either version 2 of the License, or (at your
10
+// option) any later version.
11
+//
12
+// This program is distributed in the hope that it will be useful, but WITHOUT
13
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
+// for more details.
16
+//
17
+// You should have received a copy of the GNU Lesser General Public License
18
+// along with this program; if not, write to the Free Software Foundation,
19
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+// _________________
21
+
22
+// @(#) $Revision: 4.31 $ $Source: /judy/src/JudyCommon/JudyPrivate1L.h $
23
+
24
+// ****************************************************************************
25
+// Declare common cJU_* names for JP Types that occur in both Judy1 and JudyL,
26
+// for use by code that ifdefs JUDY1 and JUDYL. Only JP Types common to both
27
+// Judy1 and JudyL are #defined here with equivalent cJU_* names. JP Types
28
+// unique to only Judy1 or JudyL are listed in comments, so the type lists
29
+// match the Judy1.h and JudyL.h files.
30
+//
31
+// This file also defines cJU_* for other JP-related constants and functions
32
+// that some shared JUDY1/JUDYL code finds handy.
33
+//
34
+// At least in principle this file should be included AFTER Judy1.h or JudyL.h.
35
+//
36
+// WARNING: This file must be kept consistent with the enums in Judy1.h and
37
+// JudyL.h.
38
+//
39
+// TBD: You might think, why not define common cJU_* enums in, say,
40
+// JudyPrivate.h, and then inherit them into superset enums in Judy1.h and
41
+// JudyL.h? The problem is that the enum lists for each class (cJ1_* and
42
+// cJL_*) must be numerically "packed" into the correct order, for two reasons:
43
+// (1) allow the compiler to generate "tight" switch statements with no wasted
44
+// slots (although this is not very big), and (2) allow calculations using the
45
+// enum values, although this is also not an issue if the calculations are only
46
+// within each cJ*_JPIMMED_*_* class and the members are packed within the
47
+// class.
48
+
49
+#ifdef JUDY1
50
+
51
+#define cJU_JRPNULL cJ1_JRPNULL
52
+#define cJU_JPNULL1 cJ1_JPNULL1
53
+#define cJU_JPNULL2 cJ1_JPNULL2
54
+#define cJU_JPNULL3 cJ1_JPNULL3
55
+#ifdef JU_64BIT
56
+#define cJU_JPNULL4 cJ1_JPNULL4
57
+#define cJU_JPNULL5 cJ1_JPNULL5
58
+#define cJU_JPNULL6 cJ1_JPNULL6
59
+#define cJU_JPNULL7 cJ1_JPNULL7
60
+#endif
61
+#define cJU_JPNULLMAX cJ1_JPNULLMAX
62
+#define cJU_JPBRANCH_L2 cJ1_JPBRANCH_L2
63
+#define cJU_JPBRANCH_L3 cJ1_JPBRANCH_L3
64
+#ifdef JU_64BIT
65
+#define cJU_JPBRANCH_L4 cJ1_JPBRANCH_L4
66
+#define cJU_JPBRANCH_L5 cJ1_JPBRANCH_L5
67
+#define cJU_JPBRANCH_L6 cJ1_JPBRANCH_L6
68
+#define cJU_JPBRANCH_L7 cJ1_JPBRANCH_L7
69
+#endif
70
+#define cJU_JPBRANCH_L cJ1_JPBRANCH_L
71
+#define j__U_BranchBJPPopToWords j__1_BranchBJPPopToWords
72
+#define cJU_JPBRANCH_B2 cJ1_JPBRANCH_B2
73
+#define cJU_JPBRANCH_B3 cJ1_JPBRANCH_B3
74
+#ifdef JU_64BIT
75
+#define cJU_JPBRANCH_B4 cJ1_JPBRANCH_B4
76
+#define cJU_JPBRANCH_B5 cJ1_JPBRANCH_B5
77
+#define cJU_JPBRANCH_B6 cJ1_JPBRANCH_B6
78
+#define cJU_JPBRANCH_B7 cJ1_JPBRANCH_B7
79
+#endif
80
+#define cJU_JPBRANCH_B cJ1_JPBRANCH_B
81
+#define cJU_JPBRANCH_U2 cJ1_JPBRANCH_U2
82
+#define cJU_JPBRANCH_U3 cJ1_JPBRANCH_U3
83
+#ifdef JU_64BIT
84
+#define cJU_JPBRANCH_U4 cJ1_JPBRANCH_U4
85
+#define cJU_JPBRANCH_U5 cJ1_JPBRANCH_U5
86
+#define cJU_JPBRANCH_U6 cJ1_JPBRANCH_U6
87
+#define cJU_JPBRANCH_U7 cJ1_JPBRANCH_U7
88
+#endif
89
+#define cJU_JPBRANCH_U cJ1_JPBRANCH_U
90
+#ifndef JU_64BIT
91
+#define cJU_JPLEAF1 cJ1_JPLEAF1
92
+#endif
93
+#define cJU_JPLEAF2 cJ1_JPLEAF2
94
+#define cJU_JPLEAF3 cJ1_JPLEAF3
95
+#ifdef JU_64BIT
96
+#define cJU_JPLEAF4 cJ1_JPLEAF4
97
+#define cJU_JPLEAF5 cJ1_JPLEAF5
98
+#define cJU_JPLEAF6 cJ1_JPLEAF6
99
+#define cJU_JPLEAF7 cJ1_JPLEAF7
100
+#endif
101
+#define cJU_JPLEAF_B1 cJ1_JPLEAF_B1
102
+// cJ1_JPFULLPOPU1
103
+#define cJU_JPIMMED_1_01 cJ1_JPIMMED_1_01
104
+#define cJU_JPIMMED_2_01 cJ1_JPIMMED_2_01
105
+#define cJU_JPIMMED_3_01 cJ1_JPIMMED_3_01
106
+#ifdef JU_64BIT
107
+#define cJU_JPIMMED_4_01 cJ1_JPIMMED_4_01
108
+#define cJU_JPIMMED_5_01 cJ1_JPIMMED_5_01
109
+#define cJU_JPIMMED_6_01 cJ1_JPIMMED_6_01
110
+#define cJU_JPIMMED_7_01 cJ1_JPIMMED_7_01
111
+#endif
112
+#define cJU_JPIMMED_1_02 cJ1_JPIMMED_1_02
113
+#define cJU_JPIMMED_1_03 cJ1_JPIMMED_1_03
114
+#define cJU_JPIMMED_1_04 cJ1_JPIMMED_1_04
115
+#define cJU_JPIMMED_1_05 cJ1_JPIMMED_1_05
116
+#define cJU_JPIMMED_1_06 cJ1_JPIMMED_1_06
117
+#define cJU_JPIMMED_1_07 cJ1_JPIMMED_1_07
118
+#ifdef JU_64BIT
119
+// cJ1_JPIMMED_1_08
120
+// cJ1_JPIMMED_1_09
121
+// cJ1_JPIMMED_1_10
122
+// cJ1_JPIMMED_1_11
123
+// cJ1_JPIMMED_1_12
124
+// cJ1_JPIMMED_1_13
125
+// cJ1_JPIMMED_1_14
126
+// cJ1_JPIMMED_1_15
127
+#endif
128
+#define cJU_JPIMMED_2_02 cJ1_JPIMMED_2_02
129
+#define cJU_JPIMMED_2_03 cJ1_JPIMMED_2_03
130
+#ifdef JU_64BIT
131
+// cJ1_JPIMMED_2_04
132
+// cJ1_JPIMMED_2_05
133
+// cJ1_JPIMMED_2_06
134
+// cJ1_JPIMMED_2_07
135
+#endif
136
+#define cJU_JPIMMED_3_02 cJ1_JPIMMED_3_02
137
+#ifdef JU_64BIT
138
+// cJ1_JPIMMED_3_03
139
+// cJ1_JPIMMED_3_04
140
+// cJ1_JPIMMED_3_05
141
+// cJ1_JPIMMED_4_02
142
+// cJ1_JPIMMED_4_03
143
+// cJ1_JPIMMED_5_02
144
+// cJ1_JPIMMED_5_03
145
+// cJ1_JPIMMED_6_02
146
+// cJ1_JPIMMED_7_02
147
+#endif
148
+#define cJU_JPIMMED_CAP cJ1_JPIMMED_CAP
149
+
150
+#else // JUDYL ****************************************************************
151
+
152
+#define cJU_JRPNULL cJL_JRPNULL
153
+#define cJU_JPNULL1 cJL_JPNULL1
154
+#define cJU_JPNULL2 cJL_JPNULL2
155
+#define cJU_JPNULL3 cJL_JPNULL3
156
+#ifdef JU_64BIT
157
+#define cJU_JPNULL4 cJL_JPNULL4
158
+#define cJU_JPNULL5 cJL_JPNULL5
159
+#define cJU_JPNULL6 cJL_JPNULL6
160
+#define cJU_JPNULL7 cJL_JPNULL7
161
+#endif
162
+#define cJU_JPNULLMAX cJL_JPNULLMAX
163
+#define cJU_JPBRANCH_L2 cJL_JPBRANCH_L2
164
+#define cJU_JPBRANCH_L3 cJL_JPBRANCH_L3
165
+#ifdef JU_64BIT
166
+#define cJU_JPBRANCH_L4 cJL_JPBRANCH_L4
167
+#define cJU_JPBRANCH_L5 cJL_JPBRANCH_L5
168
+#define cJU_JPBRANCH_L6 cJL_JPBRANCH_L6
169
+#define cJU_JPBRANCH_L7 cJL_JPBRANCH_L7
170
+#endif
171
+#define cJU_JPBRANCH_L cJL_JPBRANCH_L
172
+#define j__U_BranchBJPPopToWords j__L_BranchBJPPopToWords
173
+#define cJU_JPBRANCH_B2 cJL_JPBRANCH_B2
174
+#define cJU_JPBRANCH_B3 cJL_JPBRANCH_B3
175
+#ifdef JU_64BIT
176
+#define cJU_JPBRANCH_B4 cJL_JPBRANCH_B4
177
+#define cJU_JPBRANCH_B5 cJL_JPBRANCH_B5
178
+#define cJU_JPBRANCH_B6 cJL_JPBRANCH_B6
179
+#define cJU_JPBRANCH_B7 cJL_JPBRANCH_B7
180
+#endif
181
+#define cJU_JPBRANCH_B cJL_JPBRANCH_B
182
+#define cJU_JPBRANCH_U2 cJL_JPBRANCH_U2
183
+#define cJU_JPBRANCH_U3 cJL_JPBRANCH_U3
184
+#ifdef JU_64BIT
185
+#define cJU_JPBRANCH_U4 cJL_JPBRANCH_U4
186
+#define cJU_JPBRANCH_U5 cJL_JPBRANCH_U5
187
+#define cJU_JPBRANCH_U6 cJL_JPBRANCH_U6
188
+#define cJU_JPBRANCH_U7 cJL_JPBRANCH_U7
189
+#endif
190
+#define cJU_JPBRANCH_U cJL_JPBRANCH_U
191
+#define cJU_JPLEAF1 cJL_JPLEAF1
192
+#define cJU_JPLEAF2 cJL_JPLEAF2
193
+#define cJU_JPLEAF3 cJL_JPLEAF3
194
+#ifdef JU_64BIT
195
+#define cJU_JPLEAF4 cJL_JPLEAF4
196
+#define cJU_JPLEAF5 cJL_JPLEAF5
197
+#define cJU_JPLEAF6 cJL_JPLEAF6
198
+#define cJU_JPLEAF7 cJL_JPLEAF7
199
+#endif
200
+#define cJU_JPLEAF_B1 cJL_JPLEAF_B1
201
+#define cJU_JPIMMED_1_01 cJL_JPIMMED_1_01
202
+#define cJU_JPIMMED_2_01 cJL_JPIMMED_2_01
203
+#define cJU_JPIMMED_3_01 cJL_JPIMMED_3_01
204
+#ifdef JU_64BIT
205
+#define cJU_JPIMMED_4_01 cJL_JPIMMED_4_01
206
+#define cJU_JPIMMED_5_01 cJL_JPIMMED_5_01
207
+#define cJU_JPIMMED_6_01 cJL_JPIMMED_6_01
208
+#define cJU_JPIMMED_7_01 cJL_JPIMMED_7_01
209
+#endif
210
+#define cJU_JPIMMED_1_02 cJL_JPIMMED_1_02
211
+#define cJU_JPIMMED_1_03 cJL_JPIMMED_1_03
212
+#ifdef JU_64BIT
213
+#define cJU_JPIMMED_1_04 cJL_JPIMMED_1_04
214
+#define cJU_JPIMMED_1_05 cJL_JPIMMED_1_05
215
+#define cJU_JPIMMED_1_06 cJL_JPIMMED_1_06
216
+#define cJU_JPIMMED_1_07 cJL_JPIMMED_1_07
217
+#define cJU_JPIMMED_2_02 cJL_JPIMMED_2_02
218
+#define cJU_JPIMMED_2_03 cJL_JPIMMED_2_03
219
+#define cJU_JPIMMED_3_02 cJL_JPIMMED_3_02
220
+#endif
221
+#define cJU_JPIMMED_CAP cJL_JPIMMED_CAP
222
+
223
+#endif // JUDYL
224
+
225
+
226
+// ****************************************************************************
227
+// cJU*_ other than JP types:
228
+
229
+#ifdef JUDY1
230
+
231
+#define cJU_LEAFW_MAXPOP1 cJ1_LEAFW_MAXPOP1
232
+#ifndef JU_64BIT
233
+#define cJU_LEAF1_MAXPOP1 cJ1_LEAF1_MAXPOP1
234
+#endif
235
+#define cJU_LEAF2_MAXPOP1 cJ1_LEAF2_MAXPOP1
236
+#define cJU_LEAF3_MAXPOP1 cJ1_LEAF3_MAXPOP1
237
+#ifdef JU_64BIT
238
+#define cJU_LEAF4_MAXPOP1 cJ1_LEAF4_MAXPOP1
239
+#define cJU_LEAF5_MAXPOP1 cJ1_LEAF5_MAXPOP1
240
+#define cJU_LEAF6_MAXPOP1 cJ1_LEAF6_MAXPOP1
241
+#define cJU_LEAF7_MAXPOP1 cJ1_LEAF7_MAXPOP1
242
+#endif
243
+#define cJU_IMMED1_MAXPOP1 cJ1_IMMED1_MAXPOP1
244
+#define cJU_IMMED2_MAXPOP1 cJ1_IMMED2_MAXPOP1
245
+#define cJU_IMMED3_MAXPOP1 cJ1_IMMED3_MAXPOP1
246
+#ifdef JU_64BIT
247
+#define cJU_IMMED4_MAXPOP1 cJ1_IMMED4_MAXPOP1
248
+#define cJU_IMMED5_MAXPOP1 cJ1_IMMED5_MAXPOP1
249
+#define cJU_IMMED6_MAXPOP1 cJ1_IMMED6_MAXPOP1
250
+#define cJU_IMMED7_MAXPOP1 cJ1_IMMED7_MAXPOP1
251
+#endif
252
+
253
+#define JU_LEAF1POPTOWORDS(Pop1) J1_LEAF1POPTOWORDS(Pop1)
254
+#define JU_LEAF2POPTOWORDS(Pop1) J1_LEAF2POPTOWORDS(Pop1)
255
+#define JU_LEAF3POPTOWORDS(Pop1) J1_LEAF3POPTOWORDS(Pop1)
256
+#ifdef JU_64BIT
257
+#define JU_LEAF4POPTOWORDS(Pop1) J1_LEAF4POPTOWORDS(Pop1)
258
+#define JU_LEAF5POPTOWORDS(Pop1) J1_LEAF5POPTOWORDS(Pop1)
259
+#define JU_LEAF6POPTOWORDS(Pop1) J1_LEAF6POPTOWORDS(Pop1)
260
+#define JU_LEAF7POPTOWORDS(Pop1) J1_LEAF7POPTOWORDS(Pop1)
261
+#endif
262
+#define JU_LEAFWPOPTOWORDS(Pop1) J1_LEAFWPOPTOWORDS(Pop1)
263
+
264
+#ifndef JU_64BIT
265
+#define JU_LEAF1GROWINPLACE(Pop1) J1_LEAF1GROWINPLACE(Pop1)
266
+#endif
267
+#define JU_LEAF2GROWINPLACE(Pop1) J1_LEAF2GROWINPLACE(Pop1)
268
+#define JU_LEAF3GROWINPLACE(Pop1) J1_LEAF3GROWINPLACE(Pop1)
269
+#ifdef JU_64BIT
270
+#define JU_LEAF4GROWINPLACE(Pop1) J1_LEAF4GROWINPLACE(Pop1)
271
+#define JU_LEAF5GROWINPLACE(Pop1) J1_LEAF5GROWINPLACE(Pop1)
272
+#define JU_LEAF6GROWINPLACE(Pop1) J1_LEAF6GROWINPLACE(Pop1)
273
+#define JU_LEAF7GROWINPLACE(Pop1) J1_LEAF7GROWINPLACE(Pop1)
274
+#endif
275
+#define JU_LEAFWGROWINPLACE(Pop1) J1_LEAFWGROWINPLACE(Pop1)
276
+
277
+#define j__udyCreateBranchL j__udy1CreateBranchL
278
+#define j__udyCreateBranchB j__udy1CreateBranchB
279
+#define j__udyCreateBranchU j__udy1CreateBranchU
280
+#define j__udyCascade1 j__udy1Cascade1
281
+#define j__udyCascade2 j__udy1Cascade2
282
+#define j__udyCascade3 j__udy1Cascade3
283
+#ifdef JU_64BIT
284
+#define j__udyCascade4 j__udy1Cascade4
285
+#define j__udyCascade5 j__udy1Cascade5
286
+#define j__udyCascade6 j__udy1Cascade6
287
+#define j__udyCascade7 j__udy1Cascade7
288
+#endif
289
+#define j__udyCascadeL j__udy1CascadeL
290
+#define j__udyInsertBranch j__udy1InsertBranch
291
+
292
+#define j__udyBranchBToBranchL j__udy1BranchBToBranchL
293
+#ifndef JU_64BIT
294
+#define j__udyLeafB1ToLeaf1 j__udy1LeafB1ToLeaf1
295
+#endif
296
+#define j__udyLeaf1ToLeaf2 j__udy1Leaf1ToLeaf2
297
+#define j__udyLeaf2ToLeaf3 j__udy1Leaf2ToLeaf3
298
+#ifndef JU_64BIT
299
+#define j__udyLeaf3ToLeafW j__udy1Leaf3ToLeafW
300
+#else
301
+#define j__udyLeaf3ToLeaf4 j__udy1Leaf3ToLeaf4
302
+#define j__udyLeaf4ToLeaf5 j__udy1Leaf4ToLeaf5
303
+#define j__udyLeaf5ToLeaf6 j__udy1Leaf5ToLeaf6
304
+#define j__udyLeaf6ToLeaf7 j__udy1Leaf6ToLeaf7
305
+#define j__udyLeaf7ToLeafW j__udy1Leaf7ToLeafW
306
+#endif
307
+
308
+#define jpm_t j1pm_t
309
+#define Pjpm_t Pj1pm_t
310
+
311
+#define jlb_t j1lb_t
312
+#define Pjlb_t Pj1lb_t
313
+
314
+#define JU_JLB_BITMAP J1_JLB_BITMAP
315
+
316
+#define j__udyAllocJPM j__udy1AllocJ1PM
317
+#define j__udyAllocJBL j__udy1AllocJBL
318
+#define j__udyAllocJBB j__udy1AllocJBB
319
+#define j__udyAllocJBBJP j__udy1AllocJBBJP
320
+#define j__udyAllocJBU j__udy1AllocJBU
321
+#ifndef JU_64BIT
322
+#define j__udyAllocJLL1 j__udy1AllocJLL1
323
+#endif
324
+#define j__udyAllocJLL2 j__udy1AllocJLL2
325
+#define j__udyAllocJLL3 j__udy1AllocJLL3
326
+#ifdef JU_64BIT
327
+#define j__udyAllocJLL4 j__udy1AllocJLL4
328
+#define j__udyAllocJLL5 j__udy1AllocJLL5
329
+#define j__udyAllocJLL6 j__udy1AllocJLL6
330
+#define j__udyAllocJLL7 j__udy1AllocJLL7
331
+#endif
332
+#define j__udyAllocJLW j__udy1AllocJLW
333
+#define j__udyAllocJLB1 j__udy1AllocJLB1
334
+#define j__udyFreeJPM j__udy1FreeJ1PM
335
+#define j__udyFreeJBL j__udy1FreeJBL
336
+#define j__udyFreeJBB j__udy1FreeJBB
337
+#define j__udyFreeJBBJP j__udy1FreeJBBJP
338
+#define j__udyFreeJBU j__udy1FreeJBU
339
+#ifndef JU_64BIT
340
+#define j__udyFreeJLL1 j__udy1FreeJLL1
341
+#endif
342
+#define j__udyFreeJLL2 j__udy1FreeJLL2
343
+#define j__udyFreeJLL3 j__udy1FreeJLL3
344
+#ifdef JU_64BIT
345
+#define j__udyFreeJLL4 j__udy1FreeJLL4
346
+#define j__udyFreeJLL5 j__udy1FreeJLL5
347
+#define j__udyFreeJLL6 j__udy1FreeJLL6
348
+#define j__udyFreeJLL7 j__udy1FreeJLL7
349
+#endif
350
+#define j__udyFreeJLW j__udy1FreeJLW
351
+#define j__udyFreeJLB1 j__udy1FreeJLB1
352
+#define j__udyFreeSM j__udy1FreeSM
353
+
354
+#define j__uMaxWords j__u1MaxWords
355
+
356
+#ifdef DEBUG
357
+#define JudyCheckPop Judy1CheckPop
358
+#endif
359
+
360
+#else // JUDYL ****************************************************************
361
+
362
+#define cJU_LEAFW_MAXPOP1 cJL_LEAFW_MAXPOP1
363
+#define cJU_LEAF1_MAXPOP1 cJL_LEAF1_MAXPOP1
364
+#define cJU_LEAF2_MAXPOP1 cJL_LEAF2_MAXPOP1
365
+#define cJU_LEAF3_MAXPOP1 cJL_LEAF3_MAXPOP1
366
+#ifdef JU_64BIT
367
+#define cJU_LEAF4_MAXPOP1 cJL_LEAF4_MAXPOP1
368
+#define cJU_LEAF5_MAXPOP1 cJL_LEAF5_MAXPOP1
369
+#define cJU_LEAF6_MAXPOP1 cJL_LEAF6_MAXPOP1
370
+#define cJU_LEAF7_MAXPOP1 cJL_LEAF7_MAXPOP1
371
+#endif
372
+#define cJU_IMMED1_MAXPOP1 cJL_IMMED1_MAXPOP1
373
+#define cJU_IMMED2_MAXPOP1 cJL_IMMED2_MAXPOP1
374
+#define cJU_IMMED3_MAXPOP1 cJL_IMMED3_MAXPOP1
375
+#ifdef JU_64BIT
376
+#define cJU_IMMED4_MAXPOP1 cJL_IMMED4_MAXPOP1
377
+#define cJU_IMMED5_MAXPOP1 cJL_IMMED5_MAXPOP1
378
+#define cJU_IMMED6_MAXPOP1 cJL_IMMED6_MAXPOP1
379
+#define cJU_IMMED7_MAXPOP1 cJL_IMMED7_MAXPOP1
380
+#endif
381
+
382
+#define JU_LEAF1POPTOWORDS(Pop1) JL_LEAF1POPTOWORDS(Pop1)
383
+#define JU_LEAF2POPTOWORDS(Pop1) JL_LEAF2POPTOWORDS(Pop1)
384
+#define JU_LEAF3POPTOWORDS(Pop1) JL_LEAF3POPTOWORDS(Pop1)
385
+#ifdef JU_64BIT
386
+#define JU_LEAF4POPTOWORDS(Pop1) JL_LEAF4POPTOWORDS(Pop1)
387
+#define JU_LEAF5POPTOWORDS(Pop1) JL_LEAF5POPTOWORDS(Pop1)
388
+#define JU_LEAF6POPTOWORDS(Pop1) JL_LEAF6POPTOWORDS(Pop1)
389
+#define JU_LEAF7POPTOWORDS(Pop1) JL_LEAF7POPTOWORDS(Pop1)
390
+#endif
391
+#define JU_LEAFWPOPTOWORDS(Pop1) JL_LEAFWPOPTOWORDS(Pop1)
392
+
393
+#define JU_LEAF1GROWINPLACE(Pop1) JL_LEAF1GROWINPLACE(Pop1)
394
+#define JU_LEAF2GROWINPLACE(Pop1) JL_LEAF2GROWINPLACE(Pop1)
395
+#define JU_LEAF3GROWINPLACE(Pop1) JL_LEAF3GROWINPLACE(Pop1)
396
+#ifdef JU_64BIT
397
+#define JU_LEAF4GROWINPLACE(Pop1) JL_LEAF4GROWINPLACE(Pop1)
398
+#define JU_LEAF5GROWINPLACE(Pop1) JL_LEAF5GROWINPLACE(Pop1)
399
+#define JU_LEAF6GROWINPLACE(Pop1) JL_LEAF6GROWINPLACE(Pop1)
400
+#define JU_LEAF7GROWINPLACE(Pop1) JL_LEAF7GROWINPLACE(Pop1)
401
+#endif
402
+#define JU_LEAFWGROWINPLACE(Pop1) JL_LEAFWGROWINPLACE(Pop1)
403
+
404
+#define j__udyCreateBranchL j__udyLCreateBranchL
405
+#define j__udyCreateBranchB j__udyLCreateBranchB
406
+#define j__udyCreateBranchU j__udyLCreateBranchU
407
+#define j__udyCascade1 j__udyLCascade1
408
+#define j__udyCascade2 j__udyLCascade2
409
+#define j__udyCascade3 j__udyLCascade3
410
+#ifdef JU_64BIT
411
+#define j__udyCascade4 j__udyLCascade4
412
+#define j__udyCascade5 j__udyLCascade5
413
+#define j__udyCascade6 j__udyLCascade6
414
+#define j__udyCascade7 j__udyLCascade7
415
+#endif
416
+#define j__udyCascadeL j__udyLCascadeL
417
+#define j__udyInsertBranch j__udyLInsertBranch
418
+
419
+#define j__udyBranchBToBranchL j__udyLBranchBToBranchL
420
+#define j__udyLeafB1ToLeaf1 j__udyLLeafB1ToLeaf1
421
+#define j__udyLeaf1ToLeaf2 j__udyLLeaf1ToLeaf2
422
+#define j__udyLeaf2ToLeaf3 j__udyLLeaf2ToLeaf3
423
+#ifndef JU_64BIT
424
+#define j__udyLeaf3ToLeafW j__udyLLeaf3ToLeafW
425
+#else
426
+#define j__udyLeaf3ToLeaf4 j__udyLLeaf3ToLeaf4
427
+#define j__udyLeaf4ToLeaf5 j__udyLLeaf4ToLeaf5
428
+#define j__udyLeaf5ToLeaf6 j__udyLLeaf5ToLeaf6
429
+#define j__udyLeaf6ToLeaf7 j__udyLLeaf6ToLeaf7
430
+#define j__udyLeaf7ToLeafW j__udyLLeaf7ToLeafW
431
+#endif
432
+
433
+#define jpm_t jLpm_t
434
+#define Pjpm_t PjLpm_t
435
+
436
+#define jlb_t jLlb_t
437
+#define Pjlb_t PjLlb_t
438
+
439
+#define JU_JLB_BITMAP JL_JLB_BITMAP
440
+
441
+#define j__udyAllocJPM j__udyLAllocJLPM
442
+#define j__udyAllocJBL j__udyLAllocJBL
443
+#define j__udyAllocJBB j__udyLAllocJBB
444
+#define j__udyAllocJBBJP j__udyLAllocJBBJP
445
+#define j__udyAllocJBU j__udyLAllocJBU
446
+#define j__udyAllocJLL1 j__udyLAllocJLL1
447
+#define j__udyAllocJLL2 j__udyLAllocJLL2
448
+#define j__udyAllocJLL3 j__udyLAllocJLL3
449
+#ifdef JU_64BIT
450
+#define j__udyAllocJLL4 j__udyLAllocJLL4
451
+#define j__udyAllocJLL5 j__udyLAllocJLL5
452
+#define j__udyAllocJLL6 j__udyLAllocJLL6
453
+#define j__udyAllocJLL7 j__udyLAllocJLL7
454
+#endif
455
+#define j__udyAllocJLW j__udyLAllocJLW
456
+#define j__udyAllocJLB1 j__udyLAllocJLB1
457
+// j__udyLAllocJV
458
+#define j__udyFreeJPM j__udyLFreeJLPM
459
+#define j__udyFreeJBL j__udyLFreeJBL
460
+#define j__udyFreeJBB j__udyLFreeJBB
461
+#define j__udyFreeJBBJP j__udyLFreeJBBJP
462
+#define j__udyFreeJBU j__udyLFreeJBU
463
+#define j__udyFreeJLL1 j__udyLFreeJLL1
464
+#define j__udyFreeJLL2 j__udyLFreeJLL2
465
+#define j__udyFreeJLL3 j__udyLFreeJLL3
466
+#ifdef JU_64BIT
467
+#define j__udyFreeJLL4 j__udyLFreeJLL4
468
+#define j__udyFreeJLL5 j__udyLFreeJLL5
469
+#define j__udyFreeJLL6 j__udyLFreeJLL6
470
+#define j__udyFreeJLL7 j__udyLFreeJLL7
471
+#endif
472
+#define j__udyFreeJLW j__udyLFreeJLW
473
+#define j__udyFreeJLB1 j__udyLFreeJLB1
474
+#define j__udyFreeSM j__udyLFreeSM
475
+// j__udyLFreeJV
476
+
477
+#define j__uMaxWords j__uLMaxWords
478
+
479
+#ifdef DEBUG
480
+#define JudyCheckPop JudyLCheckPop
481
+#endif
482
+
483
+#endif // JUDYL
484
+
485
+#endif // _JUDYPRIVATE1L_INCLUDED
libnetdata/libjudy/src/JudyCommon/JudyPrivateBranch.h
new
+788
@@ -0,0 +1,788 @@
1
+#ifndef _JUDY_PRIVATE_BRANCH_INCLUDED
2
+#define _JUDY_PRIVATE_BRANCH_INCLUDED
3
+// _________________
4
+//
5
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
6
+//
7
+// This program is free software; you can redistribute it and/or modify it
8
+// under the term of the GNU Lesser General Public License as published by the
9
+// Free Software Foundation; either version 2 of the License, or (at your
10
+// option) any later version.
11
+//
12
+// This program is distributed in the hope that it will be useful, but WITHOUT
13
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
+// for more details.
16
+//
17
+// You should have received a copy of the GNU Lesser General Public License
18
+// along with this program; if not, write to the Free Software Foundation,
19
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+// _________________
21
+
22
+// @(#) $Revision: 1.2 $ $Source: /home/doug/judy-1.0.5_min/test/../src/JudyCommon/RCS/JudyPrivateBranch.h,v $
23
+//
24
+// Header file for all Judy sources, for global but private (non-exported)
25
+// declarations specific to branch support.
26
+//
27
+// See also the "Judy Shop Manual" (try judy/doc/int/JudyShopManual.*).
28
+
29
+
30
+// ****************************************************************************
31
+// JUDY POINTER (JP) SUPPORT
32
+// ****************************************************************************
33
+//
34
+// This "rich pointer" object is pivotal to Judy execution.
35
+//
36
+// JP CONTAINING OTHER THAN IMMEDIATE INDEXES:
37
+//
38
+// If the JP points to a linear or bitmap leaf, jp_DcdPopO contains the
39
+// Population-1 in LSbs and Decode (Dcd) bytes in the MSBs. (In practice the
40
+// Decode bits are masked off while accessing the Pop0 bits.)
41
+//
42
+// The Decode Size, the number of Dcd bytes available, is encoded in jpo_Type.
43
+// It can also be thought of as the number of states "skipped" in the SM, where
44
+// each state decodes 8 bits = 1 byte.
45
+//
46
+// TBD: Dont need two structures, except possibly to force jp_Type to highest
47
+// address!
48
+//
49
+// Note: The jpo_u union is not required by HP-UX or Linux but Win32 because
50
+// the cl.exe compiler otherwise refuses to pack a bitfield (DcdPopO) with
51
+// anything else, even with the -Zp option. This is pretty ugly, but
52
+// fortunately portable, and its all hide-able by macros (see below).
53
+
54
+typedef struct J_UDY_POINTER_OTHERS // JPO.
55
+ {
56
+ Word_t j_po_Addr; // first word: Pjp_t, Word_t, etc.
57
+ union {
58
+ Word_t j_po_Addr1;
59
+ uint8_t j_po_DcdP0[sizeof(Word_t) - 1];
60
+ uint8_t j_po_Bytes[sizeof(Word_t)]; // last byte = jp_Type.
61
+ } jpo_u;
62
+ } jpo_t;
63
+
64
+
65
+// JP CONTAINING IMMEDIATE INDEXES:
66
+//
67
+// j_pi_1Index[] plus j_pi_LIndex[] together hold as many N-byte (1..3-byte
68
+// [1..7-byte]) Indexes as will fit in sizeof(jpi_t) less 1 byte for j_pi_Type
69
+// (that is, 7..1 [15..1] Indexes).
70
+//
71
+// For Judy1, j_pi_1Index[] is used and j_pi_LIndex[] is not used.
72
+// For JudyL, j_pi_LIndex[] is used and j_pi_1Index[] is not used.
73
+//
74
+// Note: Actually when Pop1 = 1, jpi_t is not used, and the least bytes of the
75
+// single Index are stored in j_po_DcdPopO, for both Judy1 and JudyL, so for
76
+// JudyL the j_po_Addr field can hold the target value.
77
+//
78
+// TBD: Revise this structure to not overload j_po_DcdPopO this way? The
79
+// current arrangement works, its just confusing.
80
+
81
+typedef struct _JUDY_POINTER_IMMEDL
82
+ {
83
+ Word_t j_pL_Addr;
84
+ uint8_t j_pL_LIndex[sizeof(Word_t) - 1]; // see above.
85
+ uint8_t j_pL_Type;
86
+ } jpL_t;
87
+
88
+typedef struct _JUDY_POINTER_IMMED1
89
+ {
90
+ uint8_t j_p1_1Index[(2 * sizeof(Word_t)) - 1];
91
+ uint8_t j_p1_Type;
92
+ } jp1_t;
93
+
94
+// UNION OF JP TYPES:
95
+//
96
+// A branch is an array of cJU_BRANCHUNUMJPS (256) of this object, or an
97
+// alternate data type such as: A linear branch which is a list of 2..7 JPs,
98
+// or a bitmap branch which contains 8 lists of 0..32 JPs. JPs reside only in
99
+// branches of a Judy SM.
100
+
101
+typedef union J_UDY_POINTER // JP.
102
+ {
103
+ jpo_t j_po; // other than immediate indexes.
104
+ jpL_t j_pL; // immediate indexes.
105
+ jp1_t j_p1; // immediate indexes.
106
+ } jp_t, *Pjp_t;
107
+
108
+// For coding convenience:
109
+//
110
+// Note, jp_Type has the same bits in jpo_t jpL_t and jp1_t.
111
+
112
+#define jp_1Index j_p1.j_p1_1Index // for storing Indexes in first word.
113
+#define jp_LIndex j_pL.j_pL_LIndex // for storing Indexes in second word.
114
+#define jp_Addr j_po.j_po_Addr
115
+#define jp_Addr1 j_po.jpo_u.j_po_Addr1
116
+//#define jp_DcdPop0 j_po.jpo_u.j_po_DcdPop0
117
+#define jp_Addr1 j_po.jpo_u.j_po_Addr1
118
+//#define jp_Type j_po.jpo_u.j_po_Bytes[sizeof(Word_t) - 1]
119
+#define jp_Type j_p1.j_p1_Type
120
+#define jp_DcdP0 j_po.jpo_u.j_po_DcdP0
121
+
122
+
123
+// ****************************************************************************
124
+// JUDY POINTER (JP) -- RELATED MACROS AND CONSTANTS
125
+// ****************************************************************************
126
+
127
+// EXTRACT VALUES FROM JP:
128
+//
129
+// Masks for the bytes in the Dcd and Pop0 parts of jp_DcdPopO:
130
+//
131
+// cJU_DCDMASK() consists of a mask that excludes the (LSb) Pop0 bytes and
132
+// also, just to be safe, the top byte of the word, since jp_DcdPopO is 1 byte
133
+// less than a full word.
134
+//
135
+// Note: These are constant macros (cJU) because cPopBytes should be a
136
+// constant. Also note cPopBytes == state in the SM.
137
+
138
+#define cJU_POP0MASK(cPopBytes) JU_LEASTBYTESMASK(cPopBytes)
139
+
140
+#define cJU_DCDMASK(cPopBytes) \
141
+ ((cJU_ALLONES >> cJU_BITSPERBYTE) & (~cJU_POP0MASK(cPopBytes)))
142
+
143
+// Mask off the high byte from INDEX to it can be compared to DcdPopO:
144
+
145
+#define JU_TRIMTODCDSIZE(INDEX) ((cJU_ALLONES >> cJU_BITSPERBYTE) & (INDEX))
146
+
147
+// Get from jp_DcdPopO the Pop0 for various branch JP Types:
148
+//
149
+// Note: There are no simple macros for cJU_BRANCH* Types because their
150
+// populations must be added up and dont reside in an already-calculated
151
+// place.
152
+
153
+#define JU_JPBRANCH_POP0(PJP,cPopBytes) \
154
+ (JU_JPDCDPOP0(PJP) & cJU_POP0MASK(cPopBytes))
155
+
156
+// METHOD FOR DETERMINING IF OBJECTS HAVE ROOM TO GROW:
157
+//
158
+// J__U_GROWCK() is a generic method to determine if an object can grow in
159
+// place, based on whether the next population size (one more) would use the
160
+// same space.
161
+
162
+#define J__U_GROWCK(POP1,MAXPOP1,POPTOWORDS) \
163
+ (((POP1) != (MAXPOP1)) && (POPTOWORDS[POP1] == POPTOWORDS[(POP1) + 1]))
164
+
165
+#define JU_BRANCHBJPGROWINPLACE(NumJPs) \
166
+ J__U_GROWCK(NumJPs, cJU_BITSPERSUBEXPB, j__U_BranchBJPPopToWords)
167
+
168
+
169
+// DETERMINE IF AN INDEX IS (NOT) IN A JPS EXPANSE:
170
+
171
+#define JU_DCDNOTMATCHINDEX(INDEX,PJP,POP0BYTES) \
172
+ (((INDEX) ^ JU_JPDCDPOP0(PJP)) & cJU_DCDMASK(POP0BYTES))
173
+
174
+
175
+// NUMBER OF JPs IN AN UNCOMPRESSED BRANCH:
176
+//
177
+// An uncompressed branch is simply an array of 256 Judy Pointers (JPs). It is
178
+// a minimum cacheline fill object. Define it here before its first needed.
179
+
180
+#define cJU_BRANCHUNUMJPS cJU_SUBEXPPERSTATE
181
+
182
+
183
+// ****************************************************************************
184
+// JUDY BRANCH LINEAR (JBL) SUPPORT
185
+// ****************************************************************************
186
+//
187
+// A linear branch is a way of compressing empty expanses (null JPs) out of an
188
+// uncompressed 256-way branch, when the number of populated expanses is so
189
+// small that even a bitmap branch is excessive.
190
+//
191
+// The maximum number of JPs in a Judy linear branch:
192
+//
193
+// Note: This number results in a 1-cacheline sized structure. Previous
194
+// versions had a larger struct so a linear branch didnt become a bitmap
195
+// branch until the memory consumed was even, but for speed, its better to
196
+// switch "sooner" and keep a linear branch fast.
197
+
198
+#define cJU_BRANCHLMAXJPS 7
199
+
200
+
201
+// LINEAR BRANCH STRUCT:
202
+//
203
+// 1-byte count, followed by array of byte-sized expanses, followed by JPs.
204
+
205
+typedef struct J__UDY_BRANCH_LINEAR
206
+ {
207
+ uint8_t jbl_NumJPs; // num of JPs (Pjp_t), 1..N.
208
+ uint8_t jbl_Expanse[cJU_BRANCHLMAXJPS]; // 1..7 MSbs of pop exps.
209
+ jp_t jbl_jp [cJU_BRANCHLMAXJPS]; // JPs for populated exps.
210
+ } jbl_t, * Pjbl_t;
211
+
212
+
213
+// ****************************************************************************
214
+// JUDY BRANCH BITMAP (JBB) SUPPORT
215
+// ****************************************************************************
216
+//
217
+// A bitmap branch is a way of compressing empty expanses (null JPs) out of
218
+// uncompressed 256-way branch. This costs 1 additional cache line fill, but
219
+// can save a lot of memory when it matters most, near the leaves, and
220
+// typically there will be only one at most in the path to any Index (leaf).
221
+//
222
+// The bitmap indicates which of the cJU_BRANCHUNUMJPS (256) JPs in the branch
223
+// are NOT null, that is, their expanses are populated. The jbb_t also
224
+// contains N pointers to "mini" Judy branches ("subexpanses") of up to M JPs
225
+// each (see BITMAP_BRANCHMxN, for example, BITMAP_BRANCH32x8), where M x N =
226
+// cJU_BRANCHUNUMJPS. These are dynamically allocated and never contain
227
+// cJ*_JPNULL* jp_Types. An empty subexpanse is represented by no bit sets in
228
+// the corresponding subexpanse bitmap, in which case the corresponding
229
+// jbbs_Pjp pointers value is unused.
230
+//
231
+// Note that the number of valid JPs in each 1-of-N subexpanses is determined
232
+// by POPULATION rather than by EXPANSE -- the desired outcome to save memory
233
+// when near the leaves. Note that the memory required for 185 JPs is about as
234
+// much as an uncompressed 256-way branch, therefore 184 is set as the maximum.
235
+// However, it is expected that a conversion to an uncompressed 256-way branch
236
+// will normally take place before this limit is reached for other reasons,
237
+// such as improving performance when the "wasted" memory is well amortized by
238
+// the population under the branch, preserving an acceptable overall
239
+// bytes/Index in the Judy array.
240
+//
241
+// The number of pointers to arrays of JPs in the Judy bitmap branch:
242
+//
243
+// Note: The numbers below are the same in both 32 and 64 bit systems.
244
+
245
+#define cJU_BRANCHBMAXJPS 184 // maximum JPs for bitmap branches.
246
+
247
+// Convenience wrappers for referencing BranchB bitmaps or JP subarray
248
+// pointers:
249
+//
250
+// Note: JU_JBB_PJP produces a "raw" memory address that must pass through
251
+// P_JP before use, except when freeing memory:
252
+
253
+#define JU_JBB_BITMAP(Pjbb, SubExp) ((Pjbb)->jbb_jbbs[SubExp].jbbs_Bitmap)
254
+#define JU_JBB_PJP( Pjbb, SubExp) ((Pjbb)->jbb_jbbs[SubExp].jbbs_Pjp)
255
+
256
+#define JU_SUBEXPB(Digit) (((Digit) / cJU_BITSPERSUBEXPB) & (cJU_NUMSUBEXPB-1))
257
+
258
+#define JU_BITMAPTESTB(Pjbb, Index) \
259
+ (JU_JBB_BITMAP(Pjbb, JU_SUBEXPB(Index)) & JU_BITPOSMASKB(Index))
260
+
261
+#define JU_BITMAPSETB(Pjbb, Index) \
262
+ (JU_JBB_BITMAP(Pjbb, JU_SUBEXPB(Index)) |= JU_BITPOSMASKB(Index))
263
+
264
+// Note: JU_BITMAPCLEARB is not defined because the code does it a faster way.
265
+
266
+typedef struct J__UDY_BRANCH_BITMAP_SUBEXPANSE
267
+ {
268
+ BITMAPB_t jbbs_Bitmap;
269
+ Pjp_t jbbs_Pjp;
270
+
271
+ } jbbs_t;
272
+
273
+typedef struct J__UDY_BRANCH_BITMAP
274
+ {
275
+ jbbs_t jbb_jbbs [cJU_NUMSUBEXPB];
276
+#ifdef SUBEXPCOUNTS
277
+ Word_t jbb_subPop1[cJU_NUMSUBEXPB];
278
+#endif
279
+ } jbb_t, * Pjbb_t;
280
+
281
+#define JU_BRANCHJP_NUMJPSTOWORDS(NumJPs) (j__U_BranchBJPPopToWords[NumJPs])
282
+
283
+#ifdef SUBEXPCOUNTS
284
+#define cJU_NUMSUBEXPU 16 // number of subexpanse counts.
285
+#endif
286
+
287
+
288
+// ****************************************************************************
289
+// JUDY BRANCH UNCOMPRESSED (JBU) SUPPORT
290
+// ****************************************************************************
291
+
292
+// Convenience wrapper for referencing BranchU JPs:
293
+//
294
+// Note: This produces a non-"raw" address already passed through P_JBU().
295
+
296
+#define JU_JBU_PJP(Pjp,Index,Level) \
297
+ (&((P_JBU((Pjp)->jp_Addr))->jbu_jp[JU_DIGITATSTATE(Index, Level)]))
298
+#define JU_JBU_PJP0(Pjp) \
299
+ (&((P_JBU((Pjp)->jp_Addr))->jbu_jp[0]))
300
+
301
+typedef struct J__UDY_BRANCH_UNCOMPRESSED
302
+ {
303
+ jp_t jbu_jp [cJU_BRANCHUNUMJPS]; // JPs for populated exp.
304
+#ifdef SUBEXPCOUNTS
305
+ Word_t jbu_subPop1[cJU_NUMSUBEXPU];
306
+#endif
307
+ } jbu_t, * Pjbu_t;
308
+
309
+
310
+// ****************************************************************************
311
+// OTHER SUPPORT FOR JUDY STATE MACHINES (SMs)
312
+// ****************************************************************************
313
+
314
+// OBJECT SIZES IN WORDS:
315
+//
316
+// Word_ts per various JudyL structures that have constant sizes.
317
+// cJU_WORDSPERJP should always be 2; this is fundamental to the Judy
318
+// structures.
319
+
320
+#define cJU_WORDSPERJP (sizeof(jp_t) / cJU_BYTESPERWORD)
321
+#define cJU_WORDSPERCL (cJU_BYTESPERCL / cJU_BYTESPERWORD)
322
+
323
+
324
+// OPPORTUNISTIC UNCOMPRESSION:
325
+//
326
+// Define populations at which a BranchL or BranchB must convert to BranchU.
327
+// Earlier conversion is possible with good memory efficiency -- see below.
328
+
329
+#ifndef NO_BRANCHU
330
+
331
+// Max population below BranchL, then convert to BranchU:
332
+
333
+#define JU_BRANCHL_MAX_POP 1000
334
+
335
+// Minimum global population increment before next conversion of a BranchB to a
336
+// BranchU:
337
+//
338
+// This is was done to allow malloc() to coalesce memory before the next big
339
+// (~512 words) allocation.
340
+
341
+#define JU_BTOU_POP_INCREMENT 300
342
+
343
+// Min/max population below BranchB, then convert to BranchU:
344
+
345
+#define JU_BRANCHB_MIN_POP 135
346
+#define JU_BRANCHB_MAX_POP 750
347
+
348
+#else // NO_BRANCHU
349
+
350
+// These are set up to have conservative conversion schedules to BranchU:
351
+
352
+#define JU_BRANCHL_MAX_POP (-1UL)
353
+#define JU_BTOU_POP_INCREMENT 300
354
+#define JU_BRANCHB_MIN_POP 1000
355
+#define JU_BRANCHB_MAX_POP (-1UL)
356
+
357
+#endif // NO_BRANCHU
358
+
359
+
360
+// MISCELLANEOUS MACROS:
361
+
362
+// Get N most significant bits from the shifted Index word:
363
+//
364
+// As Index words are decoded, they are shifted left so only relevant,
365
+// undecoded Index bits remain.
366
+
367
+#define JU_BITSFROMSFTIDX(SFTIDX, N) ((SFTIDX) >> (cJU_BITSPERWORD - (N)))
368
+
369
+// TBD: I have my doubts about the necessity of these macros (dlb):
370
+
371
+// Produce 1-digit mask at specified state:
372
+
373
+#define cJU_MASKATSTATE(State) (0xffL << (((State) - 1) * cJU_BITSPERBYTE))
374
+
375
+// Get byte (digit) from Index at the specified state, right justified:
376
+//
377
+// Note: State must be 1..cJU_ROOTSTATE, and Digits must be 1..(cJU_ROOTSTATE
378
+// - 1), but theres no way to assert these within an expression.
379
+
380
+#define JU_DIGITATSTATE(Index,cState) \
381
+ ((uint8_t)((Index) >> (((cState) - 1) * cJU_BITSPERBYTE)))
382
+
383
+// Similarly, place byte (digit) at correct position for the specified state:
384
+//
385
+// Note: Cast digit to a Word_t first so there are no complaints or problems
386
+// about shifting it more than 32 bits on a 64-bit system, say, when it is a
387
+// uint8_t from jbl_Expanse[]. (Believe it or not, the C standard says to
388
+// promote an unsigned char to a signed int; -Ac does not do this, but -Ae
389
+// does.)
390
+//
391
+// Also, to make lint happy, cast the whole result again because apparently
392
+// shifting a Word_t does not result in a Word_t!
393
+
394
+#define JU_DIGITTOSTATE(Digit,cState) \
395
+ ((Word_t) (((Word_t) (Digit)) << (((cState) - 1) * cJU_BITSPERBYTE)))
396
+
397
+#endif // ! _JUDY_PRIVATE_BRANCH_INCLUDED
398
+
399
+
400
+#ifdef TEST_INSDEL
401
+
402
+// ****************************************************************************
403
+// TEST CODE FOR INSERT/DELETE MACROS
404
+// ****************************************************************************
405
+//
406
+// To use this, compile a temporary *.c file containing:
407
+//
408
+// #define DEBUG
409
+// #define JUDY_ASSERT
410
+// #define TEST_INSDEL
411
+// #include "JudyPrivate.h"
412
+// #include "JudyPrivateBranch.h"
413
+//
414
+// Use a command like this: cc -Ae +DD64 -I. -I JudyCommon -o t t.c
415
+// For best results, include +DD64 on a 64-bit system.
416
+//
417
+// This test code exercises some tricky macros, but the output must be studied
418
+// manually to verify it. Assume that for even-index testing, whole words
419
+// (Word_t) suffices.
420
+
421
+#include <stdio.h>
422
+
423
+#define INDEXES 3 // in each array.
424
+
425
+
426
+// ****************************************************************************
427
+// I N I T
428
+//
429
+// Set up variables for next test. See usage.
430
+
431
+FUNCTION void Init (
432
+ int base,
433
+ PWord_t PeIndex,
434
+ PWord_t PoIndex,
435
+ PWord_t Peleaf, // always whole words.
436
+#ifndef JU_64BIT
437
+ uint8_t * Poleaf3)
438
+#else
439
+ uint8_t * Poleaf3,
440
+ uint8_t * Poleaf5,
441
+ uint8_t * Poleaf6,
442
+ uint8_t * Poleaf7)
443
+#endif
444
+{
445
+ int offset;
446
+
447
+ *PeIndex = 99;
448
+
449
+ for (offset = 0; offset <= INDEXES; ++offset)
450
+ Peleaf[offset] = base + offset;
451
+
452
+ for (offset = 0; offset < (INDEXES + 1) * 3; ++offset)
453
+ Poleaf3[offset] = base + offset;
454
+
455
+#ifndef JU_64BIT
456
+ *PoIndex = (91 << 24) | (92 << 16) | (93 << 8) | 94;
457
+#else
458
+
459
+ *PoIndex = (91L << 56) | (92L << 48) | (93L << 40) | (94L << 32)
460
+ | (95L << 24) | (96L << 16) | (97L << 8) | 98L;
461
+
462
+ for (offset = 0; offset < (INDEXES + 1) * 5; ++offset)
463
+ Poleaf5[offset] = base + offset;
464
+
465
+ for (offset = 0; offset < (INDEXES + 1) * 6; ++offset)
466
+ Poleaf6[offset] = base + offset;
467
+
468
+ for (offset = 0; offset < (INDEXES + 1) * 7; ++offset)
469
+ Poleaf7[offset] = base + offset;
470
+#endif
471
+
472
+} // Init()
473
+
474
+
475
+// ****************************************************************************
476
+// P R I N T L E A F
477
+//
478
+// Print the byte values in a leaf.
479
+
480
+FUNCTION void PrintLeaf (
481
+ char * Label, // for output.
482
+ int IOffset, // insertion offset in array.
483
+ int Indsize, // index size in bytes.
484
+ uint8_t * PLeaf) // array of Index bytes.
485
+{
486
+ int offset; // in PLeaf.
487
+ int byte; // in one word.
488
+
489
+ (void) printf("%s %u: ", Label, IOffset);
490
+
491
+ for (offset = 0; offset <= INDEXES; ++offset)
492
+ {
493
+ for (byte = 0; byte < Indsize; ++byte)
494
+ (void) printf("%2d", PLeaf[(offset * Indsize) + byte]);
495
+
496
+ (void) printf(" ");
497
+ }
498
+
499
+ (void) printf("\n");
500
+
501
+} // PrintLeaf()
502
+
503
+
504
+// ****************************************************************************
505
+// M A I N
506
+//
507
+// Test program.
508
+
509
+FUNCTION main()
510
+{
511
+ Word_t eIndex; // even, to insert.
512
+ Word_t oIndex; // odd, to insert.
513
+ Word_t eleaf [ INDEXES + 1]; // even leaf, index size 4.
514
+ uint8_t oleaf3[(INDEXES + 1) * 3]; // odd leaf, index size 3.
515
+#ifdef JU_64BIT
516
+ uint8_t oleaf5[(INDEXES + 1) * 5]; // odd leaf, index size 5.
517
+ uint8_t oleaf6[(INDEXES + 1) * 6]; // odd leaf, index size 6.
518
+ uint8_t oleaf7[(INDEXES + 1) * 7]; // odd leaf, index size 7.
519
+#endif
520
+ Word_t eleaf_2 [ INDEXES + 1]; // same, but second arrays:
521
+ uint8_t oleaf3_2[(INDEXES + 1) * 3];
522
+#ifdef JU_64BIT
523
+ uint8_t oleaf5_2[(INDEXES + 1) * 5];
524
+ uint8_t oleaf6_2[(INDEXES + 1) * 6];
525
+ uint8_t oleaf7_2[(INDEXES + 1) * 7];
526
+#endif
527
+ int ioffset; // index insertion offset.
528
+
529
+#ifndef JU_64BIT
530
+#define INIT Init( 0, & eIndex, & oIndex, eleaf, oleaf3)
531
+#define INIT2 INIT; Init(50, & eIndex, & oIndex, eleaf_2, oleaf3_2)
532
+#else
533
+#define INIT Init( 0, & eIndex, & oIndex, eleaf, oleaf3, \
534
+ oleaf5, oleaf6, oleaf7)
535
+#define INIT2 INIT; Init(50, & eIndex, & oIndex, eleaf_2, oleaf3_2, \
536
+ oleaf5_2, oleaf6_2, oleaf7_2)
537
+#endif
538
+
539
+#define WSIZE sizeof (Word_t) // shorthand.
540
+
541
+#ifdef PRINTALL // to turn on "noisy" printouts.
542
+#define PRINTLEAF(Label,IOffset,Indsize,PLeaf) \
543
+ PrintLeaf(Label,IOffset,Indsize,PLeaf)
544
+#else
545
+#define PRINTLEAF(Label,IOffset,Indsize,PLeaf) \
546
+ if (ioffset == 0) \
547
+ PrintLeaf(Label,IOffset,Indsize,PLeaf)
548
+#endif
549
+
550
+ (void) printf(
551
+"In each case, tests operate on an initial array of %d indexes. Even-index\n"
552
+"tests set index values to 0,1,2...; odd-index tests set byte values to\n"
553
+"0,1,2... Inserted indexes have a value of 99 or else byte values 91,92,...\n",
554
+ INDEXES);
555
+
556
+ (void) puts("\nJU_INSERTINPLACE():");
557
+
558
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
559
+ {
560
+ INIT;
561
+ PRINTLEAF("Before", ioffset, WSIZE, (uint8_t *) eleaf);
562
+ JU_INSERTINPLACE(eleaf, INDEXES, ioffset, eIndex);
563
+ PrintLeaf("After ", ioffset, WSIZE, (uint8_t *) eleaf);
564
+ }
565
+
566
+ (void) puts("\nJU_INSERTINPLACE3():");
567
+
568
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
569
+ {
570
+ INIT;
571
+ PRINTLEAF("Before", ioffset, 3, oleaf3);
572
+ JU_INSERTINPLACE3(oleaf3, INDEXES, ioffset, oIndex);
573
+ PrintLeaf("After ", ioffset, 3, oleaf3);
574
+ }
575
+
576
+#ifdef JU_64BIT
577
+ (void) puts("\nJU_INSERTINPLACE5():");
578
+
579
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
580
+ {
581
+ INIT;
582
+ PRINTLEAF("Before", ioffset, 5, oleaf5);
583
+ JU_INSERTINPLACE5(oleaf5, INDEXES, ioffset, oIndex);
584
+ PrintLeaf("After ", ioffset, 5, oleaf5);
585
+ }
586
+
587
+ (void) puts("\nJU_INSERTINPLACE6():");
588
+
589
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
590
+ {
591
+ INIT;
592
+ PRINTLEAF("Before", ioffset, 6, oleaf6);
593
+ JU_INSERTINPLACE6(oleaf6, INDEXES, ioffset, oIndex);
594
+ PrintLeaf("After ", ioffset, 6, oleaf6);
595
+ }
596
+
597
+ (void) puts("\nJU_INSERTINPLACE7():");
598
+
599
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
600
+ {
601
+ INIT;
602
+ PRINTLEAF("Before", ioffset, 7, oleaf7);
603
+ JU_INSERTINPLACE7(oleaf7, INDEXES, ioffset, oIndex);
604
+ PrintLeaf("After ", ioffset, 7, oleaf7);
605
+ }
606
+#endif // JU_64BIT
607
+
608
+ (void) puts("\nJU_DELETEINPLACE():");
609
+
610
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
611
+ {
612
+ INIT;
613
+ PRINTLEAF("Before", ioffset, WSIZE, (uint8_t *) eleaf);
614
+ JU_DELETEINPLACE(eleaf, INDEXES, ioffset);
615
+ PrintLeaf("After ", ioffset, WSIZE, (uint8_t *) eleaf);
616
+ }
617
+
618
+ (void) puts("\nJU_DELETEINPLACE_ODD(3):");
619
+
620
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
621
+ {
622
+ INIT;
623
+ PRINTLEAF("Before", ioffset, 3, oleaf3);
624
+ JU_DELETEINPLACE_ODD(oleaf3, INDEXES, ioffset, 3);
625
+ PrintLeaf("After ", ioffset, 3, oleaf3);
626
+ }
627
+
628
+#ifdef JU_64BIT
629
+ (void) puts("\nJU_DELETEINPLACE_ODD(5):");
630
+
631
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
632
+ {
633
+ INIT;
634
+ PRINTLEAF("Before", ioffset, 5, oleaf5);
635
+ JU_DELETEINPLACE_ODD(oleaf5, INDEXES, ioffset, 5);
636
+ PrintLeaf("After ", ioffset, 5, oleaf5);
637
+ }
638
+
639
+ (void) puts("\nJU_DELETEINPLACE_ODD(6):");
640
+
641
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
642
+ {
643
+ INIT;
644
+ PRINTLEAF("Before", ioffset, 6, oleaf6);
645
+ JU_DELETEINPLACE_ODD(oleaf6, INDEXES, ioffset, 6);
646
+ PrintLeaf("After ", ioffset, 6, oleaf6);
647
+ }
648
+
649
+ (void) puts("\nJU_DELETEINPLACE_ODD(7):");
650
+
651
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
652
+ {
653
+ INIT;
654
+ PRINTLEAF("Before", ioffset, 7, oleaf7);
655
+ JU_DELETEINPLACE_ODD(oleaf7, INDEXES, ioffset, 7);
656
+ PrintLeaf("After ", ioffset, 7, oleaf7);
657
+ }
658
+#endif // JU_64BIT
659
+
660
+ (void) puts("\nJU_INSERTCOPY():");
661
+
662
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
663
+ {
664
+ INIT2;
665
+ PRINTLEAF("Before, src ", ioffset, WSIZE, (uint8_t *) eleaf);
666
+ PRINTLEAF("Before, dest", ioffset, WSIZE, (uint8_t *) eleaf_2);
667
+ JU_INSERTCOPY(eleaf_2, eleaf, INDEXES, ioffset, eIndex);
668
+ PRINTLEAF("After, src ", ioffset, WSIZE, (uint8_t *) eleaf);
669
+ PrintLeaf("After, dest", ioffset, WSIZE, (uint8_t *) eleaf_2);
670
+ }
671
+
672
+ (void) puts("\nJU_INSERTCOPY3():");
673
+
674
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
675
+ {
676
+ INIT2;
677
+ PRINTLEAF("Before, src ", ioffset, 3, oleaf3);
678
+ PRINTLEAF("Before, dest", ioffset, 3, oleaf3_2);
679
+ JU_INSERTCOPY3(oleaf3_2, oleaf3, INDEXES, ioffset, oIndex);
680
+ PRINTLEAF("After, src ", ioffset, 3, oleaf3);
681
+ PrintLeaf("After, dest", ioffset, 3, oleaf3_2);
682
+ }
683
+
684
+#ifdef JU_64BIT
685
+ (void) puts("\nJU_INSERTCOPY5():");
686
+
687
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
688
+ {
689
+ INIT2;
690
+ PRINTLEAF("Before, src ", ioffset, 5, oleaf5);
691
+ PRINTLEAF("Before, dest", ioffset, 5, oleaf5_2);
692
+ JU_INSERTCOPY5(oleaf5_2, oleaf5, INDEXES, ioffset, oIndex);
693
+ PRINTLEAF("After, src ", ioffset, 5, oleaf5);
694
+ PrintLeaf("After, dest", ioffset, 5, oleaf5_2);
695
+ }
696
+
697
+ (void) puts("\nJU_INSERTCOPY6():");
698
+
699
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
700
+ {
701
+ INIT2;
702
+ PRINTLEAF("Before, src ", ioffset, 6, oleaf6);
703
+ PRINTLEAF("Before, dest", ioffset, 6, oleaf6_2);
704
+ JU_INSERTCOPY6(oleaf6_2, oleaf6, INDEXES, ioffset, oIndex);
705
+ PRINTLEAF("After, src ", ioffset, 6, oleaf6);
706
+ PrintLeaf("After, dest", ioffset, 6, oleaf6_2);
707
+ }
708
+
709
+ (void) puts("\nJU_INSERTCOPY7():");
710
+
711
+ for (ioffset = 0; ioffset <= INDEXES; ++ioffset)
712
+ {
713
+ INIT2;
714
+ PRINTLEAF("Before, src ", ioffset, 7, oleaf7);
715
+ PRINTLEAF("Before, dest", ioffset, 7, oleaf7_2);
716
+ JU_INSERTCOPY7(oleaf7_2, oleaf7, INDEXES, ioffset, oIndex);
717
+ PRINTLEAF("After, src ", ioffset, 7, oleaf7);
718
+ PrintLeaf("After, dest", ioffset, 7, oleaf7_2);
719
+ }
720
+#endif // JU_64BIT
721
+
722
+ (void) puts("\nJU_DELETECOPY():");
723
+
724
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
725
+ {
726
+ INIT2;
727
+ PRINTLEAF("Before, src ", ioffset, WSIZE, (uint8_t *) eleaf);
728
+ PRINTLEAF("Before, dest", ioffset, WSIZE, (uint8_t *) eleaf_2);
729
+ JU_DELETECOPY(eleaf_2, eleaf, INDEXES, ioffset, ignore);
730
+ PRINTLEAF("After, src ", ioffset, WSIZE, (uint8_t *) eleaf);
731
+ PrintLeaf("After, dest", ioffset, WSIZE, (uint8_t *) eleaf_2);
732
+ }
733
+
734
+ (void) puts("\nJU_DELETECOPY_ODD(3):");
735
+
736
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
737
+ {
738
+ INIT2;
739
+ PRINTLEAF("Before, src ", ioffset, 3, oleaf3);
740
+ PRINTLEAF("Before, dest", ioffset, 3, oleaf3_2);
741
+ JU_DELETECOPY_ODD(oleaf3_2, oleaf3, INDEXES, ioffset, 3);
742
+ PRINTLEAF("After, src ", ioffset, 3, oleaf3);
743
+ PrintLeaf("After, dest", ioffset, 3, oleaf3_2);
744
+ }
745
+
746
+#ifdef JU_64BIT
747
+ (void) puts("\nJU_DELETECOPY_ODD(5):");
748
+
749
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
750
+ {
751
+ INIT2;
752
+ PRINTLEAF("Before, src ", ioffset, 5, oleaf5);
753
+ PRINTLEAF("Before, dest", ioffset, 5, oleaf5_2);
754
+ JU_DELETECOPY_ODD(oleaf5_2, oleaf5, INDEXES, ioffset, 5);
755
+ PRINTLEAF("After, src ", ioffset, 5, oleaf5);
756
+ PrintLeaf("After, dest", ioffset, 5, oleaf5_2);
757
+ }
758
+
759
+ (void) puts("\nJU_DELETECOPY_ODD(6):");
760
+
761
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
762
+ {
763
+ INIT2;
764
+ PRINTLEAF("Before, src ", ioffset, 6, oleaf6);
765
+ PRINTLEAF("Before, dest", ioffset, 6, oleaf6_2);
766
+ JU_DELETECOPY_ODD(oleaf6_2, oleaf6, INDEXES, ioffset, 6);
767
+ PRINTLEAF("After, src ", ioffset, 6, oleaf6);
768
+ PrintLeaf("After, dest", ioffset, 6, oleaf6_2);
769
+ }
770
+
771
+ (void) puts("\nJU_DELETECOPY_ODD(7):");
772
+
773
+ for (ioffset = 0; ioffset < INDEXES; ++ioffset)
774
+ {
775
+ INIT2;
776
+ PRINTLEAF("Before, src ", ioffset, 7, oleaf7);
777
+ PRINTLEAF("Before, dest", ioffset, 7, oleaf7_2);
778
+ JU_DELETECOPY_ODD(oleaf7_2, oleaf7, INDEXES, ioffset, 7);
779
+ PRINTLEAF("After, src ", ioffset, 7, oleaf7);
780
+ PrintLeaf("After, dest", ioffset, 7, oleaf7_2);
781
+ }
782
+#endif // JU_64BIT
783
+
784
+ return(0);
785
+
786
+} // main()
787
+
788
+#endif // TEST_INSDEL
libnetdata/libjudy/src/JudyHS/JudyHS.c
new
+771
@@ -0,0 +1,771 @@
1
+// @(#) $Revision: 4.1 $ $Source: /judy/src/JudyHS/JudyHS.c
2
+//=======================================================================
3
+// Author Douglas L. Baskins, Dec 2003.
4
+// Permission to use this code is freely granted, provided that this
5
+// statement is retained.
6
+// email - doug@sourcejudy.com -or- dougbaskins@yahoo.com
7
+//=======================================================================
8
+
9
+#include <string.h> // for memcmp(), memcpy()
10
+
11
+#include <Judy.h> // for JudyL* routines/macros
12
+
13
+/*
14
+ This routine is a very fast "string" version of an ADT that stores
15
+ (JudyHSIns()), retrieves (JudyHSGet()), deletes (JudyHSDel()) and
16
+ frees the entire ADT (JudyHSFreeArray()) strings. It uses the "Judy
17
+ arrays" JudyL() API as the main workhorse. The length of the string
18
+ is included in the calling parameters so that strings with embedded
19
+ \0s can be used. The string lengths can be from 0 bytes to whatever
20
+ malloc() can handle (~2GB).
21
+
22
+ Compile:
23
+
24
+ cc -O JudyHS.c -c needs to link with -lJudy (libJudy.a)
25
+
26
+ Note: in gcc version 3.3.1, -O2 generates faster code than -O
27
+ Note: in gcc version 3.3.2, -O3 generates faster code than -O2
28
+
29
+ NOTES:
30
+
31
+1) There may be some performance issues with 64 bit machines, because I
32
+ have not characterized that it yet.
33
+
34
+2) It appears that a modern CPU (>2Ghz) that the instruction times are
35
+ much faster that a RAM access, so building up a word from bytes takes
36
+ no longer that a whole word access. I am taking advantage of this to
37
+ make this code endian neutral. A side effect of this is strings do
38
+ not need to be aligned, nor tested to be on to a word boundry. In
39
+ older and in slow (RISC) machines, this may be a performance issue.
40
+ I have given up trying to optimize for machines that have very slow
41
+ mpy, mod, variable shifts and call returns.
42
+
43
+3) JudyHS is very scalable from 1 string to billions (with enough RAM).
44
+ The memory usage is also scales with population. I have attempted to
45
+ combine the best characteristics of JudyL arrays with Hashing methods
46
+ and well designed modern processors (such as the 1.3Ghz Intel
47
+ Centrino this is being written on).
48
+
49
+ HOW JudyHS WORKS: ( 4[8] means 4 bytes in 32 bit machine and 8 in 64)
50
+
51
+ A) A JudyL array is used to separate strings of equal lengths into
52
+ their own structures (a different hash table is used for each length
53
+ of string). The additional time overhead is very near zero because
54
+ of the CPU cache. The space efficiency is improved because the
55
+ length need not be stored with the string (ls_t). The "JLHash" ADT
56
+ in the test program "StringCompare" is verification of both these
57
+ assumptions.
58
+
59
+ B) A 32 bit hash value is produced from the string. Many thanks to
60
+ the Internet and the author (Bob Jenkins) for coming up with a very
61
+ good and fast universal string hash. Next the 32 bit hash number is
62
+ used as an Index to another JudyL array. Notice that one (1) JudyL
63
+ array is used as a hash table per each string length. If there are
64
+ no hash collisions (normally) then the string is copied to a
65
+ structure (ls_t) along with room for storing a Value. A flag is
66
+ added to the pointer to note it is pointing to a ls_t structure.
67
+ Since the lengths of the strings are the same, there is no need to
68
+ stored length of string in the ls_t structure. This saves about a
69
+ word per string of memory.
70
+
71
+ C) When there is a hashing collision (very rare), a JudyL array is
72
+ used to decode the next 4[8] bytes of the string. That is, the next
73
+ 4[8] bytes of the string are used as the Index. This process is
74
+ repeated until the remaining string is unique. The remaining string
75
+ (if any) is stored in a (now smaller) ls_t structure. If the
76
+ remaining string is less or equal to 4[8] bytes, then the ls_t
77
+ structure is not needed and the Value area in the JudyL array is
78
+ used. A compile option -DDONOTUSEHASH is available to test this
79
+ structure without using hashing (only the JudyL tree is used). This
80
+ is equivalent to having all strings hashed to the same bucket. The
81
+ speed is still better than all other tree based ADTs I have tested.
82
+ An added benefit of this is a very fast "hash collision" resolving.
83
+ It could foil hackers that exploit the slow synonym (linked-list)
84
+ collision handling property used with most hashing algorithms. If
85
+ this is not a necessary property, then a simpler ADT "JLHash" that is
86
+ documented the the test program "StringCompare.c" may be used with a
87
+ little loss of memory efficiency (because it includes the string
88
+ length with the ls_t structure). JudyHS was written to be the
89
+ fastest, very scalable, memory efficient, general purpose string ADT
90
+ possible. (However, I would like to eat those words someday). (dlb)
91
+
92
+*/
93
+
94
+#ifdef EXAMPLE_CODE
95
+#include <stdio.h>
96
+#include <unistd.h>
97
+#include <string.h>
98
+
99
+#include <Judy.h>
100
+
101
+//#include "JudyHS.h" // for Judy.h without JudyHS*()
102
+
103
+// By Doug Baskins Apr 2004 - for JudyHS man page
104
+
105
+#define MAXLINE 1000000 /* max length of line */
106
+char Index[MAXLINE]; // string to check
107
+
108
+int // Usage: CheckDupLines < file
109
+main()
110
+{
111
+ Pvoid_t PJArray = (PWord_t)NULL; // Judy array.
112
+ PWord_t PValue; // ^ Judy array element.
113
+ Word_t Bytes; // size of JudyHS array.
114
+ Word_t LineNumb = 0; // current line number
115
+ Word_t Dups = 0; // number of duplicate lines
116
+
117
+ while (fgets(Index, MAXLINE, stdin) != (char *)NULL)
118
+ {
119
+ LineNumb++; // line number
120
+
121
+// store string into array
122
+ JHSI(PValue, PJArray, Index, strlen(Index));
123
+ if (*PValue) // check if duplicate
124
+ {
125
+ Dups++; // count duplicates
126
+ printf("Duplicate lines %lu:%lu:%s", *PValue, LineNumb, Index);
127
+ }
128
+ else
129
+ {
130
+ *PValue = LineNumb; // store Line number
131
+ }
132
+ }
133
+ printf("%lu Duplicates, free JudyHS array of %lu Lines\n",
134
+ Dups, LineNumb - Dups);
135
+ JHSFA(Bytes, PJArray); // free array
136
+ printf("The JudyHS array allocated %lu bytes of memory\n", Bytes);
137
+ return (0);
138
+}
139
+#endif // EXAMPLE_CODE
140
+
141
+// Note: Use JLAP_INVALID, which is non-zero, to mark pointers to a ls_t
142
+// This makes it compatable with previous versions of JudyL()
143
+
144
+#define IS_PLS(PLS) (((Word_t) (PLS)) & JLAP_INVALID)
145
+#define CLEAR_PLS(PLS) (((Word_t) (PLS)) & (~JLAP_INVALID))
146
+#define SET_PLS(PLS) (((Word_t) (PLS)) | JLAP_INVALID)
147
+
148
+#define WORDSIZE (sizeof(Word_t))
149
+
150
+// this is the struct used for "leaf" strings. Note that
151
+// the Value is followed by a "variable" length ls_String array.
152
+//
153
+typedef struct L_EAFSTRING
154
+{
155
+ Word_t ls_Value; // Value area (cannot change size)
156
+ uint8_t ls_String[WORDSIZE]; // to fill out to a Word_t size
157
+} ls_t , *Pls_t;
158
+
159
+#define LS_STRUCTOVD (sizeof(ls_t) - WORDSIZE)
160
+
161
+// Calculate size of ls_t including the string of length of LEN.
162
+//
163
+#define LS_WORDLEN(LEN) (((LEN) + LS_STRUCTOVD + WORDSIZE - 1) / WORDSIZE)
164
+
165
+// Copy from 0..4[8] bytes from string to a Word_t
166
+// NOTE: the copy in in little-endian order to take advantage of improved
167
+// memory efficiency of JudyLIns() with smaller numbers
168
+//
169
+#define COPYSTRING4toWORD(WORD,STR,LEN) \
170
+{ \
171
+ WORD = 0; \
172
+ switch(LEN) \
173
+ { \
174
+ default: /* four and greater */ \
175
+ case 4: \
176
+ WORD += (Word_t)(((uint8_t *)(STR))[3] << 24); \
177
+ case 3: \
178
+ WORD += (Word_t)(((uint8_t *)(STR))[2] << 16); \
179
+ case 2: \
180
+ WORD += (Word_t)(((uint8_t *)(STR))[1] << 8); \
181
+ case 1: \
182
+ WORD += (Word_t)(((uint8_t *)(STR))[0]); \
183
+ case 0: break; \
184
+ } \
185
+}
186
+
187
+#ifdef JU_64BIT
188
+
189
+// copy from 0..8 bytes from string to Word_t
190
+//
191
+#define COPYSTRING8toWORD(WORD,STR,LEN) \
192
+{ \
193
+ WORD = 0UL; \
194
+ switch(LEN) \
195
+ { \
196
+ default: /* eight and greater */ \
197
+ case 8: \
198
+ WORD += ((Word_t)((uint8_t *)(STR))[7] << 56); \
199
+ case 7: \
200
+ WORD += ((Word_t)((uint8_t *)(STR))[6] << 48); \
201
+ case 6: \
202
+ WORD += ((Word_t)((uint8_t *)(STR))[5] << 40); \
203
+ case 5: \
204
+ WORD += ((Word_t)((uint8_t *)(STR))[4] << 32); \
205
+ case 4: \
206
+ WORD += ((Word_t)((uint8_t *)(STR))[3] << 24); \
207
+ case 3: \
208
+ WORD += ((Word_t)((uint8_t *)(STR))[2] << 16); \
209
+ case 2: \
210
+ WORD += ((Word_t)((uint8_t *)(STR))[1] << 8); \
211
+ case 1: \
212
+ WORD += ((Word_t)((uint8_t *)(STR))[0]); \
213
+ case 0: break; \
214
+ } \
215
+}
216
+
217
+#define COPYSTRINGtoWORD COPYSTRING8toWORD
218
+
219
+#else // JU_32BIT
220
+
221
+#define COPYSTRINGtoWORD COPYSTRING4toWORD
222
+
223
+#endif // JU_32BIT
224
+
225
+// set JError_t locally
226
+
227
+#define JU_SET_ERRNO(PJERROR, JERRNO) \
228
+{ \
229
+ if (PJERROR != (PJError_t) NULL) \
230
+ { \
231
+ if (JERRNO) \
232
+ JU_ERRNO(PJError) = (JERRNO); \
233
+ JU_ERRID(PJERROR) = __LINE__; \
234
+ } \
235
+}
236
+
237
+//=======================================================================
238
+// This routine must hash string to 24..32 bits. The "goodness" of
239
+// the hash is not as important as its speed.
240
+//=======================================================================
241
+
242
+// hash to no more than 32 bits
243
+
244
+// extern Word_t gHmask; for hash bits experiments
245
+
246
+#define JUDYHASHSTR(HVALUE,STRING,LENGTH) \
247
+{ \
248
+ uint8_t *p_ = (uint8_t *)(STRING); \
249
+ uint8_t *q_ = p_ + (LENGTH); \
250
+ uint32_t c_ = 0; \
251
+ for (; p_ != q_; ++p_) \
252
+ { \
253
+ c_ = (c_ * 31) + *p_; \
254
+ } \
255
+/* c_ &= gHmask; see above */ \
256
+ (HVALUE) = c_; \
257
+}
258
+
259
+// Find String of Len in JudyHS structure, return pointer to associated Value
260
+
261
+PPvoid_t
262
+JudyHSGet(Pcvoid_t PArray, // pointer (^) to structure
263
+ void * Str, // pointer to string
264
+ Word_t Len // length of string
265
+ )
266
+{
267
+ uint8_t *String = (uint8_t *)Str;
268
+ PPvoid_t PPValue; // pointer to Value
269
+ Word_t Index; // 4[8] bytes of String
270
+
271
+ JLG(PPValue, PArray, Len); // find hash table for strings of Len
272
+ if (PPValue == (PPvoid_t) NULL)
273
+ return ((PPvoid_t) NULL); // no strings of this Len
274
+
275
+// check for caller error (null pointer)
276
+//
277
+ if ((String == (void *) NULL) && (Len != 0))
278
+ return ((PPvoid_t) NULL); // avoid null-pointer dereference
279
+
280
+#ifndef DONOTUSEHASH
281
+ if (Len > WORDSIZE) // Hash table not necessary with short
282
+ {
283
+ uint32_t HValue; // hash of input string
284
+ JUDYHASHSTR(HValue, String, Len); // hash to no more than 32 bits
285
+ JLG(PPValue, *PPValue, (Word_t)HValue); // get ^ to hash bucket
286
+ if (PPValue == (PPvoid_t) NULL)
287
+ return ((PPvoid_t) NULL); // no entry in Hash table
288
+ }
289
+#endif // DONOTUSEHASH
290
+
291
+/*
292
+ Each JudyL array decodes 4[8] bytes of the string. Since the hash
293
+ collisions occur very infrequently, the performance is not important.
294
+ However, even if the Hash code is not used this method still is
295
+ significantly faster than common tree methods (AVL, Red-Black, Splay,
296
+ b-tree, etc..). You can compare it yourself with #define DONOTUSEHASH
297
+ 1 or putting -DDONOTUSEHASH in the cc line. Use the "StringCompare.c"
298
+ code to compare (9Dec2003 dlb).
299
+*/
300
+ while (Len > WORDSIZE) // traverse tree of JudyL arrays
301
+ {
302
+ if (IS_PLS(*PPValue)) // ^ to JudyL array or ls_t struct?
303
+ {
304
+ Pls_t Pls; // ls_t struct, termination of tree
305
+ Pls = (Pls_t) CLEAR_PLS(*PPValue); // remove flag from ^
306
+
307
+// if remaining string matches, return ^ to Value, else NULL
308
+
309
+ if (memcmp(String, Pls->ls_String, Len) == 0)
310
+ return ((PPvoid_t) (&(Pls->ls_Value)));
311
+ else
312
+ return ((PPvoid_t) NULL); // string does not match
313
+ }
314
+ else
315
+ {
316
+ COPYSTRINGtoWORD(Index, String, WORDSIZE);
317
+
318
+ JLG(PPValue, *PPValue, Index); // decode next 4[8] bytes
319
+ if (PPValue == (PPvoid_t) NULL) // if NULL array, bail out
320
+ return ((PPvoid_t) NULL); // string does not match
321
+
322
+ String += WORDSIZE; // advance
323
+ Len -= WORDSIZE;
324
+ }
325
+ }
326
+
327
+// Get remaining 1..4[8] bytes left in string
328
+
329
+ COPYSTRINGtoWORD(Index, String, Len);
330
+ JLG(PPValue, *PPValue, Index); // decode last 1-4[8] bytes
331
+ return (PPValue);
332
+}
333
+
334
+// Add string to a tree of JudyL arrays (all lengths must be same)
335
+
336
+static PPvoid_t
337
+insStrJudyLTree(uint8_t * String, // string to add to tree of JudyL arrays
338
+ Word_t Len, // length of string
339
+ PPvoid_t PPValue, // pointer to root pointer
340
+ PJError_t PJError // for returning error info
341
+ )
342
+{
343
+ Word_t Index; // next 4[8] bytes of String
344
+
345
+ while (Len > WORDSIZE) // add to JudyL tree
346
+ {
347
+// CASE 1, pointer is to a NULL, make a new ls_t leaf
348
+
349
+ if (*PPValue == (Pvoid_t)NULL)
350
+ {
351
+ Pls_t Pls; // memory for a ls_t
352
+ Pls = (Pls_t) JudyMalloc(LS_WORDLEN(Len));
353
+ if (Pls == NULL)
354
+ {
355
+ JU_SET_ERRNO(PJError, JU_ERRNO_NOMEM);
356
+ return (PPJERR);
357
+ }
358
+ Pls->ls_Value = 0; // clear Value word
359
+ memcpy(Pls->ls_String, String, Len); // copy to new struct
360
+ *PPValue = (Pvoid_t)SET_PLS(Pls); // mark pointer
361
+ return ((PPvoid_t) (&Pls->ls_Value)); // return ^ to Value
362
+ } // no exit here
363
+// CASE 2: is a ls_t, free (and shorten), then decode into JudyL tree
364
+
365
+ if (IS_PLS(*PPValue)) // pointer to a ls_t? (leaf)
366
+ {
367
+ Pls_t Pls; // ^ to ls_t
368
+ uint8_t *String0; // ^ to string in ls_t
369
+ Word_t Index0; // 4[8] bytes in string
370
+ Word_t FreeLen; // length of ls_t
371
+ PPvoid_t PPsplit;
372
+
373
+ FreeLen = LS_WORDLEN(Len); // length of ls_t
374
+
375
+ Pls = (Pls_t) CLEAR_PLS(*PPValue); // demangle ^ to ls_t
376
+ String0 = Pls->ls_String;
377
+ if (memcmp(String, String0, Len) == 0) // check if match?
378
+ {
379
+ return ((PPvoid_t) (&Pls->ls_Value)); // yes, duplicate
380
+ }
381
+
382
+ *PPValue = NULL; // clear ^ to ls_t and make JudyL
383
+
384
+// This do loop is technically not required, saves multiple JudyFree()
385
+// when storing already sorted strings into structure
386
+
387
+ do // decode next 4[8] bytes of string
388
+ { // with a JudyL array
389
+// Note: string0 is always aligned
390
+
391
+ COPYSTRINGtoWORD(Index0, String0, WORDSIZE);
392
+ String0 += WORDSIZE;
393
+ COPYSTRINGtoWORD(Index, String, WORDSIZE);
394
+ String += WORDSIZE;
395
+ Len -= WORDSIZE;
396
+ PPsplit = PPValue; // save for split below
397
+ PPValue = JudyLIns(PPValue, Index0, PJError);
398
+ if (PPValue == PPJERR)
399
+ {
400
+ JU_SET_ERRNO(PJError, 0);
401
+ return (PPJERR);
402
+ }
403
+
404
+ } while ((Index0 == Index) && (Len > WORDSIZE));
405
+
406
+// finish storing remainder of string that was in the ls_t
407
+
408
+ PPValue = insStrJudyLTree(String0, Len, PPValue, PJError);
409
+ if (PPValue == PPJERR)
410
+ {
411
+ return (PPJERR);
412
+ }
413
+// copy old Value to Value in new struct
414
+
415
+ *(PWord_t)PPValue = Pls->ls_Value;
416
+
417
+// free the string buffer (ls_t)
418
+
419
+ JudyFree((Pvoid_t)Pls, FreeLen);
420
+ PPValue = JudyLIns(PPsplit, Index, PJError);
421
+ if (PPValue == PPJERR)
422
+ {
423
+ JU_SET_ERRNO(PJError, 0);
424
+ return (PPValue);
425
+ }
426
+
427
+// finish remainder of newly inserted string
428
+
429
+ PPValue = insStrJudyLTree(String, Len, PPValue, PJError);
430
+ return (PPValue);
431
+ } // no exit here
432
+// CASE 3, more JudyL arrays, decode to next tree
433
+
434
+ COPYSTRINGtoWORD(Index, String, WORDSIZE);
435
+ Len -= WORDSIZE;
436
+ String += WORDSIZE;
437
+
438
+ PPValue = JudyLIns(PPValue, Index, PJError); // next 4[8] bytes
439
+ if (PPValue == PPJERR)
440
+ {
441
+ JU_SET_ERRNO(PJError, 0);
442
+ return (PPValue);
443
+ }
444
+ }
445
+// this is done outside of loop so "Len" can be an unsigned number
446
+
447
+ COPYSTRINGtoWORD(Index, String, Len);
448
+ PPValue = JudyLIns(PPValue, Index, PJError); // remaining 4[8] bytes
449
+
450
+ return (PPValue);
451
+}
452
+
453
+
454
+// Insert string to JudyHS structure, return pointer to associated Value
455
+
456
+PPvoid_t
457
+JudyHSIns(PPvoid_t PPArray, // ^ to JudyHashArray name
458
+ void * Str, // pointer to string
459
+ Word_t Len, // length of string
460
+ PJError_t PJError // optional, for returning error info
461
+ )
462
+{
463
+ uint8_t * String = (uint8_t *)Str;
464
+ PPvoid_t PPValue;
465
+
466
+// string can only be NULL if Len is 0.
467
+
468
+ if ((String == (uint8_t *) NULL) && (Len != 0UL))
469
+ {
470
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
471
+ return (PPJERR);
472
+ }
473
+ JLG(PPValue, *PPArray, Len); // JudyL hash table for strings of Len
474
+ if (PPValue == (PPvoid_t) NULL) // make new if missing, (very rare)
475
+ {
476
+ PPValue = JudyLIns(PPArray, Len, PJError);
477
+ if (PPValue == PPJERR)
478
+ {
479
+ JU_SET_ERRNO(PJError, 0);
480
+ return (PPJERR);
481
+ }
482
+ }
483
+#ifndef DONOTUSEHASH
484
+ if (Len > WORDSIZE)
485
+ {
486
+ uint32_t HValue; // hash of input string
487
+ JUDYHASHSTR(HValue, String, Len); // hash to no more than 32 bits
488
+ PPValue = JudyLIns(PPValue, (Word_t)HValue, PJError);
489
+ if (PPValue == PPJERR)
490
+ {
491
+ JU_SET_ERRNO(PJError, 0);
492
+ return (PPJERR);
493
+ }
494
+ }
495
+#endif // DONOTUSEHASH
496
+
497
+ PPValue = insStrJudyLTree(String, Len, PPValue, PJError); // add string
498
+ return (PPValue); // ^ to Value
499
+}
500
+
501
+// Delete string from tree of JudyL arrays (all Lens must be same)
502
+
503
+static int
504
+delStrJudyLTree(uint8_t * String, // delete from tree of JudyL arrays
505
+ Word_t Len, // length of string
506
+ PPvoid_t PPValue, // ^ to hash bucket
507
+ PJError_t PJError // for returning error info
508
+ )
509
+{
510
+ PPvoid_t PPValueN; // next pointer
511
+ Word_t Index;
512
+ int Ret; // -1=failed, 1=success, 2=quit del
513
+
514
+ if (IS_PLS(*PPValue)) // is pointer to ls_t?
515
+ {
516
+ Pls_t Pls;
517
+ Pls = (Pls_t) CLEAR_PLS(*PPValue); // demangle pointer
518
+ JudyFree((Pvoid_t)Pls, LS_WORDLEN(Len)); // free the ls_t
519
+
520
+ *PPValue = (Pvoid_t)NULL; // clean pointer
521
+ return (1); // successfully deleted
522
+ }
523
+
524
+ if (Len > WORDSIZE) // delete from JudyL tree, not leaf
525
+ {
526
+ COPYSTRINGtoWORD(Index, String, WORDSIZE); // get Index
527
+ JLG(PPValueN, *PPValue, Index); // get pointer to next JudyL array
528
+
529
+ String += WORDSIZE; // advance to next 4[8] bytes
530
+ Len -= WORDSIZE;
531
+
532
+ Ret = delStrJudyLTree(String, Len, PPValueN, PJError);
533
+ if (Ret != 1) return(Ret);
534
+
535
+ if (*PPValueN == (PPvoid_t) NULL)
536
+ {
537
+// delete JudyL element from tree
538
+
539
+ Ret = JudyLDel(PPValue, Index, PJError);
540
+ }
541
+ }
542
+ else
543
+ {
544
+ COPYSTRINGtoWORD(Index, String, Len); // get leaf element
545
+
546
+// delete last 1-4[8] bytes from leaf element
547
+
548
+ Ret = JudyLDel(PPValue, Index, PJError);
549
+ }
550
+ return (Ret);
551
+}
552
+
553
+// Delete string from JHS structure
554
+
555
+int
556
+JudyHSDel(PPvoid_t PPArray, // ^ to JudyHashArray struct
557
+ void * Str, // pointer to string
558
+ Word_t Len, // length of string
559
+ PJError_t PJError // optional, for returning error info
560
+ )
561
+{
562
+ uint8_t * String = (uint8_t *)Str;
563
+ PPvoid_t PPBucket, PPHtble;
564
+ int Ret; // return bool from Delete routine
565
+#ifndef DONOTUSEHASH
566
+ uint32_t HValue = 0; // hash value of input string
567
+#endif // DONOTUSEHASH
568
+
569
+ if (PPArray == NULL)
570
+ return (0); // no pointer, return not found
571
+
572
+// This is a little slower than optimum method, but not much in new CPU
573
+// Verify that string is in the structure -- simplifies future assumptions
574
+
575
+ if (JudyHSGet(*PPArray, String, Len) == (PPvoid_t) NULL)
576
+ return (0); // string not found, return
577
+
578
+// string is in structure, so testing for absence is not necessary
579
+
580
+ JLG(PPHtble, *PPArray, Len); // JudyL hash table for strings of Len
581
+
582
+#ifdef DONOTUSEHASH
583
+ PPBucket = PPHtble; // simulate below code
584
+#else // USEHASH
585
+ if (Len > WORDSIZE)
586
+ {
587
+ JUDYHASHSTR(HValue, String, Len); // hash to no more than 32 bits
588
+
589
+// get pointer to hash bucket
590
+
591
+ JLG(PPBucket, *PPHtble, (Word_t)HValue);
592
+ }
593
+ else
594
+ {
595
+ PPBucket = PPHtble; // no bucket to JLGet
596
+ }
597
+#endif // USEHASH
598
+
599
+// delete from JudyL tree
600
+//
601
+ Ret = delStrJudyLTree(String, Len, PPBucket, PJError);
602
+ if (Ret != 1)
603
+ {
604
+ JU_SET_ERRNO(PJError, 0);
605
+ return(-1);
606
+ }
607
+// handle case of missing JudyL array from hash table and length table
608
+
609
+ if (*PPBucket == (Pvoid_t)NULL) // if JudyL tree gone
610
+ {
611
+#ifndef DONOTUSEHASH
612
+ if (Len > WORDSIZE)
613
+ {
614
+// delete entry in Hash table
615
+
616
+ Ret = JudyLDel(PPHtble, (Word_t)HValue, PJError);
617
+ if (Ret != 1)
618
+ {
619
+ JU_SET_ERRNO(PJError, 0);
620
+ return(-1);
621
+ }
622
+ }
623
+#endif // USEHASH
624
+ if (*PPHtble == (PPvoid_t) NULL) // if Hash table gone
625
+ {
626
+// delete entry from the String length table
627
+
628
+ Ret = JudyLDel(PPArray, Len, PJError);
629
+ if (Ret != 1)
630
+ {
631
+ JU_SET_ERRNO(PJError, 0);
632
+ return(-1);
633
+ }
634
+ }
635
+ }
636
+ return (1); // success
637
+}
638
+
639
+static Word_t
640
+delJudyLTree(PPvoid_t PPValue, // ^ to JudyL root pointer
641
+ Word_t Len, // length of string
642
+ PJError_t PJError) // for returning error info
643
+{
644
+ Word_t bytes_freed = 0; // bytes freed at point
645
+ Word_t bytes_total = 0; // accumulated bytes freed
646
+ PPvoid_t PPValueN;
647
+
648
+// Pointer is to another tree of JudyL arrays or ls_t struct
649
+
650
+ if (Len > WORDSIZE) // more depth to tree
651
+ {
652
+ Word_t NEntry;
653
+
654
+// Pointer is to a ls_t struct
655
+
656
+ if (IS_PLS(*PPValue))
657
+ {
658
+ Pls_t Pls;
659
+ Word_t freewords;
660
+
661
+ freewords = LS_WORDLEN(Len); // calculate length
662
+ Pls = (Pls_t)CLEAR_PLS(*PPValue); // demangle pointer
663
+
664
+// *PPValue = (Pvoid_t)NULL; // clean pointer
665
+ JudyFree((Pvoid_t)Pls, freewords); // free the ls_t
666
+
667
+ return(freewords * WORDSIZE);
668
+ }
669
+// else
670
+// Walk all the entrys in the JudyL array
671
+
672
+ NEntry = 0; // start at beginning
673
+ for (PPValueN = JudyLFirst(*PPValue, &NEntry, PJError);
674
+ (PPValueN != (PPvoid_t) NULL) && (PPValueN != PPJERR);
675
+ PPValueN = JudyLNext(*PPValue, &NEntry, PJError))
676
+ {
677
+// recurse to the next level in the tree of arrays
678
+
679
+ bytes_freed = delJudyLTree(PPValueN, Len - WORDSIZE, PJError);
680
+ if (bytes_freed == JERR) return(JERR);
681
+ bytes_total += bytes_freed;
682
+ }
683
+ if (PPValueN == PPJERR) return(JERR);
684
+
685
+// now free this JudyL array
686
+
687
+ bytes_freed = JudyLFreeArray(PPValue, PJError);
688
+ if (bytes_freed == JERR) return(JERR);
689
+ bytes_total += bytes_freed;
690
+
691
+ return(bytes_total); // return amount freed
692
+ }
693
+// else
694
+
695
+// Pointer to simple JudyL array
696
+
697
+ bytes_freed = JudyLFreeArray(PPValue, PJError);
698
+
699
+ return(bytes_freed);
700
+}
701
+
702
+
703
+Word_t // bytes freed
704
+JudyHSFreeArray(PPvoid_t PPArray, // ^ to JudyHashArray struct
705
+ PJError_t PJError // optional, for returning error info
706
+ )
707
+{
708
+ Word_t Len; // start at beginning
709
+ Word_t bytes_freed; // bytes freed at this level.
710
+ Word_t bytes_total; // bytes total at all levels.
711
+ PPvoid_t PPHtble;
712
+
713
+ if (PPArray == NULL)
714
+ return (0); // no pointer, return none
715
+
716
+// Walk the string length table for subsidary hash structs
717
+// NOTE: This is necessary to determine the depth of the tree
718
+
719
+ bytes_freed = 0;
720
+ bytes_total = 0;
721
+ Len = 0; // walk to length table
722
+
723
+ for (PPHtble = JudyLFirst(*PPArray, &Len, PJError);
724
+ (PPHtble != (PPvoid_t) NULL) && (PPHtble != PPJERR);
725
+ PPHtble = JudyLNext(*PPArray, &Len, PJError))
726
+ {
727
+ PPvoid_t PPValueH;
728
+
729
+#ifndef DONOTUSEHASH
730
+ if (Len > WORDSIZE)
731
+ {
732
+ Word_t HEntry = 0; // walk the hash tables
733
+
734
+ for (PPValueH = JudyLFirst(*PPHtble, &HEntry, PJError);
735
+ (PPValueH != (PPvoid_t) NULL) && (PPValueH != PPJERR);
736
+ PPValueH = JudyLNext(*PPHtble, &HEntry, PJError))
737
+ {
738
+ bytes_freed = delJudyLTree(PPValueH, Len, PJError);
739
+ if (bytes_freed == JERR) return(JERR);
740
+ bytes_total += bytes_freed;
741
+ }
742
+
743
+ if (PPValueH == PPJERR) return(JERR);
744
+
745
+// free the Hash table for this length of string
746
+
747
+ bytes_freed = JudyLFreeArray(PPHtble, PJError);
748
+ if (bytes_freed == JERR) return(JERR);
749
+ bytes_total += bytes_freed;
750
+ }
751
+ else
752
+#endif // DONOTUSEHASH
753
+ {
754
+ PPValueH = PPHtble; // simulate hash table
755
+
756
+ bytes_freed = delJudyLTree(PPValueH, Len, PJError);
757
+ if (bytes_freed == JERR) return(JERR);
758
+ bytes_total += bytes_freed;
759
+ }
760
+ }
761
+ if (PPHtble == PPJERR) return(JERR);
762
+
763
+// free the length table
764
+
765
+ bytes_freed = JudyLFreeArray(PPArray, PJError);
766
+ if (bytes_freed == JERR) return(JERR);
767
+
768
+ bytes_total += bytes_freed;
769
+
770
+ return(bytes_total); // return bytes freed
771
+}
libnetdata/libjudy/src/JudyL/JudyL.h
new
+505
@@ -0,0 +1,505 @@
1
+#ifndef _JUDYL_INCLUDED
2
+#define _JUDYL_INCLUDED
3
+// _________________
4
+//
5
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
6
+//
7
+// This program is free software; you can redistribute it and/or modify it
8
+// under the term of the GNU Lesser General Public License as published by the
9
+// Free Software Foundation; either version 2 of the License, or (at your
10
+// option) any later version.
11
+//
12
+// This program is distributed in the hope that it will be useful, but WITHOUT
13
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15
+// for more details.
16
+//
17
+// You should have received a copy of the GNU Lesser General Public License
18
+// along with this program; if not, write to the Free Software Foundation,
19
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
+// _________________
21
+
22
+// @(#) $Revision: 4.41 $ $Source: /judy/src/JudyL/JudyL.h $
23
+
24
+// ****************************************************************************
25
+// JUDYL -- SMALL/LARGE AND/OR CLUSTERED/SPARSE ARRAYS
26
+//
27
+// -by-
28
+//
29
+// Douglas L. Baskins
30
+// doug@sourcejudy.com
31
+//
32
+// Judy arrays are designed to be used instead of arrays. The performance
33
+// suggests the reason why Judy arrays are thought of as arrays, instead of
34
+// trees. They are remarkably memory efficient at all populations.
35
+// Implemented as a hybrid digital tree (but really a state machine, see
36
+// below), Judy arrays feature fast insert/retrievals, fast near neighbor
37
+// searching, and contain a population tree for extremely fast ordinal related
38
+// retrievals.
39
+//
40
+// CONVENTIONS:
41
+//
42
+// - The comments here refer to 32-bit [64-bit] systems.
43
+//
44
+// - BranchL, LeafL refer to linear branches and leaves (small populations),
45
+// except LeafL does not actually appear as such; rather, Leaf1..3 [Leaf1..7]
46
+// is used to represent leaf Index sizes, and LeafW refers to a Leaf with
47
+// full (Long) word Indexes, which is also a type of linear leaf. Note that
48
+// root-level LeafW (Leaf4 [Leaf8]) leaves are called LEAFW.
49
+//
50
+// - BranchB, LeafB1 refer to bitmap branches and leaves (intermediate
51
+// populations).
52
+//
53
+// - BranchU refers to uncompressed branches. An uncompressed branch has 256
54
+// JPs, some of which could be null. Note: All leaves are compressed (and
55
+// sorted), or else an expanse is full (FullPopu), so there is no LeafU
56
+// equivalent to BranchU.
57
+//
58
+// - "Popu" is short for "Population".
59
+// - "Pop1" refers to actual population (base 1).
60
+// - "Pop0" refers to Pop1 - 1 (base 0), the way populations are stored in data
61
+// structures.
62
+//
63
+// - Branches and Leaves are both named by the number of bytes in their Pop0
64
+// field. In the case of Leaves, the same number applies to the Index sizes.
65
+//
66
+// - The representation of many numbers as hex is a relatively safe and
67
+// portable way to get desired bitpatterns as unsigned longs.
68
+//
69
+// - Some preprocessors cant handle single apostrophe characters within
70
+// #ifndef code, so here, delete all instead.
71
+
72
+
73
+#include "JudyPrivate.h" // includes Judy.h in turn.
74
+#include "JudyPrivateBranch.h" // support for branches.
75
+
76
+
77
+// ****************************************************************************
78
+// JUDYL ROOT POINTER (JRP) AND JUDYL POINTER (JP) TYPE FIELDS
79
+// ****************************************************************************
80
+
81
+typedef enum // uint8_t -- but C does not support this type of enum.
82
+{
83
+
84
+// JP NULL TYPES:
85
+//
86
+// There is a series of cJL_JPNULL* Types because each one pre-records a
87
+// different Index Size for when the first Index is inserted in the previously
88
+// null JP. They must start >= 8 (three bits).
89
+//
90
+// Note: These Types must be in sequential order for doing relative
91
+// calculations between them.
92
+
93
+ cJL_JPNULL1 = 1,
94
+ // Index Size 1[1] byte when 1 Index inserted.
95
+ cJL_JPNULL2, // Index Size 2[2] bytes when 1 Index inserted.
96
+ cJL_JPNULL3, // Index Size 3[3] bytes when 1 Index inserted.
97
+
98
+#ifndef JU_64BIT
99
+#define cJL_JPNULLMAX cJL_JPNULL3
100
+#else
101
+ cJL_JPNULL4, // Index Size 4[4] bytes when 1 Index inserted.
102
+ cJL_JPNULL5, // Index Size 5[5] bytes when 1 Index inserted.
103
+ cJL_JPNULL6, // Index Size 6[6] bytes when 1 Index inserted.
104
+ cJL_JPNULL7, // Index Size 7[7] bytes when 1 Index inserted.
105
+#define cJL_JPNULLMAX cJL_JPNULL7
106
+#endif
107
+
108
+
109
+// JP BRANCH TYPES:
110
+//
111
+// Note: There are no state-1 branches; only leaves reside at state 1.
112
+
113
+// Linear branches:
114
+//
115
+// Note: These Types must be in sequential order for doing relative
116
+// calculations between them.
117
+
118
+ cJL_JPBRANCH_L2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
119
+ cJL_JPBRANCH_L3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
120
+
121
+#ifdef JU_64BIT
122
+ cJL_JPBRANCH_L4, // [4] bytes Pop0, [3] bytes Dcd.
123
+ cJL_JPBRANCH_L5, // [5] bytes Pop0, [2] bytes Dcd.
124
+ cJL_JPBRANCH_L6, // [6] bytes Pop0, [1] byte Dcd.
125
+ cJL_JPBRANCH_L7, // [7] bytes Pop0, [0] bytes Dcd.
126
+#endif
127
+
128
+ cJL_JPBRANCH_L, // note: DcdPopO field not used.
129
+
130
+// Bitmap branches:
131
+//
132
+// Note: These Types must be in sequential order for doing relative
133
+// calculations between them.
134
+
135
+ cJL_JPBRANCH_B2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
136
+ cJL_JPBRANCH_B3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
137
+
138
+#ifdef JU_64BIT
139
+ cJL_JPBRANCH_B4, // [4] bytes Pop0, [3] bytes Dcd.
140
+ cJL_JPBRANCH_B5, // [5] bytes Pop0, [2] bytes Dcd.
141
+ cJL_JPBRANCH_B6, // [6] bytes Pop0, [1] byte Dcd.
142
+ cJL_JPBRANCH_B7, // [7] bytes Pop0, [0] bytes Dcd.
143
+#endif
144
+
145
+ cJL_JPBRANCH_B, // note: DcdPopO field not used.
146
+
147
+// Uncompressed branches:
148
+//
149
+// Note: These Types must be in sequential order for doing relative
150
+// calculations between them.
151
+
152
+ cJL_JPBRANCH_U2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
153
+ cJL_JPBRANCH_U3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
154
+
155
+#ifdef JU_64BIT
156
+ cJL_JPBRANCH_U4, // [4] bytes Pop0, [3] bytes Dcd.
157
+ cJL_JPBRANCH_U5, // [5] bytes Pop0, [2] bytes Dcd.
158
+ cJL_JPBRANCH_U6, // [6] bytes Pop0, [1] byte Dcd.
159
+ cJL_JPBRANCH_U7, // [7] bytes Pop0, [0] bytes Dcd.
160
+#endif
161
+
162
+ cJL_JPBRANCH_U, // note: DcdPopO field not used.
163
+
164
+
165
+// JP LEAF TYPES:
166
+
167
+// Linear leaves:
168
+//
169
+// Note: These Types must be in sequential order for doing relative
170
+// calculations between them.
171
+//
172
+// Note: There is no full-word (4-byte [8-byte]) Index leaf under a JP because
173
+// non-root-state leaves only occur under branches that decode at least one
174
+// byte. Full-word, root-state leaves are under a JRP, not a JP. However, in
175
+// the code a "fake" JP can be created temporarily above a root-state leaf.
176
+
177
+ cJL_JPLEAF1, // 1[1] byte Pop0, 2 bytes Dcd.
178
+ cJL_JPLEAF2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
179
+ cJL_JPLEAF3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
180
+
181
+#ifdef JU_64BIT
182
+ cJL_JPLEAF4, // [4] bytes Pop0, [3] bytes Dcd.
183
+ cJL_JPLEAF5, // [5] bytes Pop0, [2] bytes Dcd.
184
+ cJL_JPLEAF6, // [6] bytes Pop0, [1] byte Dcd.
185
+ cJL_JPLEAF7, // [7] bytes Pop0, [0] bytes Dcd.
186
+#endif
187
+
188
+// Bitmap leaf; Index Size == 1:
189
+//
190
+// Note: These are currently only supported at state 1. At other states the
191
+// bitmap would grow from 256 to 256^2, 256^3, ... bits, which would not be
192
+// efficient..
193
+
194
+ cJL_JPLEAF_B1, // 1[1] byte Pop0, 2[6] bytes Dcd.
195
+
196
+// Full population; Index Size == 1 virtual leaf:
197
+//
198
+// Note: JudyL has no cJL_JPFULLPOPU1 equivalent to cJ1_JPFULLPOPU1, because
199
+// in the JudyL case this could result in a values-only leaf of up to 256 words
200
+// (value areas) that would be slow to insert/delete.
201
+
202
+
203
+// JP IMMEDIATES; leaves (Indexes) stored inside a JP:
204
+//
205
+// The second numeric suffix is the Pop1 for each type. As the Index Size
206
+// increases, the maximum possible population decreases.
207
+//
208
+// Note: These Types must be in sequential order in each group (Index Size),
209
+// and the groups in correct order too, for doing relative calculations between
210
+// them. For example, since these Types enumerate the Pop1 values (unlike
211
+// other JP Types where there is a Pop0 value in the JP), the maximum Pop1 for
212
+// each Index Size is computable.
213
+//
214
+// All enums equal or above this point are cJL_JPIMMEDs.
215
+
216
+ cJL_JPIMMED_1_01, // Index Size = 1, Pop1 = 1.
217
+ cJL_JPIMMED_2_01, // Index Size = 2, Pop1 = 1.
218
+ cJL_JPIMMED_3_01, // Index Size = 3, Pop1 = 1.
219
+
220
+#ifdef JU_64BIT
221
+ cJL_JPIMMED_4_01, // Index Size = 4, Pop1 = 1.
222
+ cJL_JPIMMED_5_01, // Index Size = 5, Pop1 = 1.
223
+ cJL_JPIMMED_6_01, // Index Size = 6, Pop1 = 1.
224
+ cJL_JPIMMED_7_01, // Index Size = 7, Pop1 = 1.
225
+#endif
226
+
227
+ cJL_JPIMMED_1_02, // Index Size = 1, Pop1 = 2.
228
+ cJL_JPIMMED_1_03, // Index Size = 1, Pop1 = 3.
229
+
230
+#ifdef JU_64BIT
231
+ cJL_JPIMMED_1_04, // Index Size = 1, Pop1 = 4.
232
+ cJL_JPIMMED_1_05, // Index Size = 1, Pop1 = 5.
233
+ cJL_JPIMMED_1_06, // Index Size = 1, Pop1 = 6.
234
+ cJL_JPIMMED_1_07, // Index Size = 1, Pop1 = 7.
235
+
236
+ cJL_JPIMMED_2_02, // Index Size = 2, Pop1 = 2.
237
+ cJL_JPIMMED_2_03, // Index Size = 2, Pop1 = 3.
238
+
239
+ cJL_JPIMMED_3_02, // Index Size = 3, Pop1 = 2.
240
+#endif
241
+
242
+// This special Type is merely a sentinel for doing relative calculations.
243
+// This value should not be used in switch statements (to avoid allocating code
244
+// for it), which is also why it appears at the end of the enum list.
245
+
246
+ cJL_JPIMMED_CAP
247
+
248
+} jpL_Type_t;
249
+
250
+
251
+// RELATED VALUES:
252
+
253
+// Index Size (state) for leaf JP, and JP type based on Index Size (state):
254
+
255
+#define JL_LEAFINDEXSIZE(jpType) ((jpType) - cJL_JPLEAF1 + 1)
256
+#define JL_LEAFTYPE(IndexSize) ((IndexSize) + cJL_JPLEAF1 - 1)
257
+
258
+
259
+// MAXIMUM POPULATIONS OF LINEAR LEAVES:
260
+
261
+#ifndef JU_64BIT // 32-bit
262
+
263
+#define J_L_MAXB (sizeof(Word_t) * 64)
264
+#define ALLOCSIZES { 3, 5, 7, 11, 15, 23, 32, 47, 64, TERMINATOR } // in words.
265
+#define cJL_LEAF1_MAXWORDS (32) // max Leaf1 size in words.
266
+
267
+// Note: cJL_LEAF1_MAXPOP1 is chosen such that the index portion is less than
268
+// 32 bytes -- the number of bytes the index takes in a bitmap leaf.
269
+
270
+#define cJL_LEAF1_MAXPOP1 \
271
+ ((cJL_LEAF1_MAXWORDS * cJU_BYTESPERWORD)/(1 + cJU_BYTESPERWORD))
272
+#define cJL_LEAF2_MAXPOP1 (J_L_MAXB / (2 + cJU_BYTESPERWORD))
273
+#define cJL_LEAF3_MAXPOP1 (J_L_MAXB / (3 + cJU_BYTESPERWORD))
274
+#define cJL_LEAFW_MAXPOP1 \
275
+ ((J_L_MAXB - cJU_BYTESPERWORD) / (2 * cJU_BYTESPERWORD))
276
+
277
+#else // 64-bit
278
+
279
+#define J_L_MAXB (sizeof(Word_t) * 64)
280
+#define ALLOCSIZES { 3, 5, 7, 11, 15, 23, 32, 47, 64, TERMINATOR } // in words.
281
+#define cJL_LEAF1_MAXWORDS (15) // max Leaf1 size in words.
282
+
283
+#define cJL_LEAF1_MAXPOP1 \
284
+ ((cJL_LEAF1_MAXWORDS * cJU_BYTESPERWORD)/(1 + cJU_BYTESPERWORD))
285
+#define cJL_LEAF2_MAXPOP1 (J_L_MAXB / (2 + cJU_BYTESPERWORD))
286
+#define cJL_LEAF3_MAXPOP1 (J_L_MAXB / (3 + cJU_BYTESPERWORD))
287
+#define cJL_LEAF4_MAXPOP1 (J_L_MAXB / (4 + cJU_BYTESPERWORD))
288
+#define cJL_LEAF5_MAXPOP1 (J_L_MAXB / (5 + cJU_BYTESPERWORD))
289
+#define cJL_LEAF6_MAXPOP1 (J_L_MAXB / (6 + cJU_BYTESPERWORD))
290
+#define cJL_LEAF7_MAXPOP1 (J_L_MAXB / (7 + cJU_BYTESPERWORD))
291
+#define cJL_LEAFW_MAXPOP1 \
292
+ ((J_L_MAXB - cJU_BYTESPERWORD) / (2 * cJU_BYTESPERWORD))
293
+
294
+#endif // 64-bit
295
+
296
+
297
+// MAXIMUM POPULATIONS OF IMMEDIATE JPs:
298
+//
299
+// These specify the maximum Population of immediate JPs with various Index
300
+// Sizes (== sizes of remaining undecoded Index bits). Since the JP Types enum
301
+// already lists all the immediates in order by state and size, calculate these
302
+// values from it to avoid redundancy.
303
+
304
+#define cJL_IMMED1_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 1) // 3 [7].
305
+#define cJL_IMMED2_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 2) // 1 [3].
306
+#define cJL_IMMED3_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 3) // 1 [2].
307
+
308
+#ifdef JU_64BIT
309
+#define cJL_IMMED4_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 4) // [1].
310
+#define cJL_IMMED5_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 5) // [1].
311
+#define cJL_IMMED6_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 6) // [1].
312
+#define cJL_IMMED7_MAXPOP1 ((cJU_BYTESPERWORD - 1) / 7) // [1].
313
+#endif
314
+
315
+
316
+// ****************************************************************************
317
+// JUDYL LEAF BITMAP (JLLB) SUPPORT
318
+// ****************************************************************************
319
+//
320
+// Assemble bitmap leaves out of smaller units that put bitmap subexpanses
321
+// close to their associated pointers. Why not just use a bitmap followed by a
322
+// series of pointers? (See 4.27.) Turns out this wastes a cache fill on
323
+// systems with smaller cache lines than the assumed value cJU_WORDSPERCL.
324
+
325
+#define JL_JLB_BITMAP(Pjlb, Subexp) ((Pjlb)->jLlb_jLlbs[Subexp].jLlbs_Bitmap)
326
+#define JL_JLB_PVALUE(Pjlb, Subexp) ((Pjlb)->jLlb_jLlbs[Subexp].jLlbs_PValue)
327
+
328
+typedef struct J__UDYL_LEAF_BITMAP_SUBEXPANSE
329
+{
330
+ BITMAPL_t jLlbs_Bitmap;
331
+ Pjv_t jLlbs_PValue;
332
+
333
+} jLlbs_t;
334
+
335
+typedef struct J__UDYL_LEAF_BITMAP
336
+{
337
+ jLlbs_t jLlb_jLlbs[cJU_NUMSUBEXPL];
338
+
339
+} jLlb_t, * PjLlb_t;
340
+
341
+// Words per bitmap leaf:
342
+
343
+#define cJL_WORDSPERLEAFB1 (sizeof(jLlb_t) / cJU_BYTESPERWORD)
344
+
345
+
346
+// ****************************************************************************
347
+// MEMORY ALLOCATION SUPPORT
348
+// ****************************************************************************
349
+
350
+// ARRAY-GLOBAL INFORMATION:
351
+//
352
+// At the cost of an occasional additional cache fill, this object, which is
353
+// pointed at by a JRP and in turn points to a JP_BRANCH*, carries array-global
354
+// information about a JudyL array that has sufficient population to amortize
355
+// the cost. The jpm_Pop0 field prevents having to add up the total population
356
+// for the array in insert, delete, and count code. The jpm_JP field prevents
357
+// having to build a fake JP for entry to a state machine; however, the
358
+// jp_DcdPopO field in jpm_JP, being one byte too small, is not used.
359
+//
360
+// Note: Struct fields are ordered to keep "hot" data in the first 8 words
361
+// (see left-margin comments) for machines with 8-word cache lines, and to keep
362
+// sub-word fields together for efficient packing.
363
+
364
+typedef struct J_UDYL_POPULATION_AND_MEMORY
365
+{
366
+/* 1 */ Word_t jpm_Pop0; // total population-1 in array.
367
+/* 2 */ jp_t jpm_JP; // JP to first branch; see above.
368
+/* 4 */ Word_t jpm_LastUPop0; // last jpm_Pop0 when convert to BranchU
369
+/* 7 */ Pjv_t jpm_PValue; // pointer to value to return.
370
+// Note: Field names match PJError_t for convenience in macros:
371
+/* 8 */ char je_Errno; // one of the enums in Judy.h.
372
+/* 8/9 */ int je_ErrID; // often an internal source line number.
373
+/* 9/10 */ Word_t jpm_TotalMemWords; // words allocated in array.
374
+} jLpm_t, *PjLpm_t;
375
+
376
+
377
+// TABLES FOR DETERMINING IF LEAVES HAVE ROOM TO GROW:
378
+//
379
+// These tables indicate if a given memory chunk can support growth of a given
380
+// object into wasted (rounded-up) memory in the chunk. Note: This violates
381
+// the hiddenness of the JudyMalloc code.
382
+
383
+extern const uint8_t j__L_Leaf1PopToWords[cJL_LEAF1_MAXPOP1 + 1];
384
+extern const uint8_t j__L_Leaf2PopToWords[cJL_LEAF2_MAXPOP1 + 1];
385
+extern const uint8_t j__L_Leaf3PopToWords[cJL_LEAF3_MAXPOP1 + 1];
386
+#ifdef JU_64BIT
387
+extern const uint8_t j__L_Leaf4PopToWords[cJL_LEAF4_MAXPOP1 + 1];
388
+extern const uint8_t j__L_Leaf5PopToWords[cJL_LEAF5_MAXPOP1 + 1];
389
+extern const uint8_t j__L_Leaf6PopToWords[cJL_LEAF6_MAXPOP1 + 1];
390
+extern const uint8_t j__L_Leaf7PopToWords[cJL_LEAF7_MAXPOP1 + 1];
391
+#endif
392
+extern const uint8_t j__L_LeafWPopToWords[cJL_LEAFW_MAXPOP1 + 1];
393
+extern const uint8_t j__L_LeafVPopToWords[];
394
+
395
+// These tables indicate where value areas start:
396
+
397
+extern const uint8_t j__L_Leaf1Offset [cJL_LEAF1_MAXPOP1 + 1];
398
+extern const uint8_t j__L_Leaf2Offset [cJL_LEAF2_MAXPOP1 + 1];
399
+extern const uint8_t j__L_Leaf3Offset [cJL_LEAF3_MAXPOP1 + 1];
400
+#ifdef JU_64BIT
401
+extern const uint8_t j__L_Leaf4Offset [cJL_LEAF4_MAXPOP1 + 1];
402
+extern const uint8_t j__L_Leaf5Offset [cJL_LEAF5_MAXPOP1 + 1];
403
+extern const uint8_t j__L_Leaf6Offset [cJL_LEAF6_MAXPOP1 + 1];
404
+extern const uint8_t j__L_Leaf7Offset [cJL_LEAF7_MAXPOP1 + 1];
405
+#endif
406
+extern const uint8_t j__L_LeafWOffset [cJL_LEAFW_MAXPOP1 + 1];
407
+
408
+// Also define macros to hide the details in the code using these tables.
409
+
410
+#define JL_LEAF1GROWINPLACE(Pop1) \
411
+ J__U_GROWCK(Pop1, cJL_LEAF1_MAXPOP1, j__L_Leaf1PopToWords)
412
+#define JL_LEAF2GROWINPLACE(Pop1) \
413
+ J__U_GROWCK(Pop1, cJL_LEAF2_MAXPOP1, j__L_Leaf2PopToWords)
414
+#define JL_LEAF3GROWINPLACE(Pop1) \
415
+ J__U_GROWCK(Pop1, cJL_LEAF3_MAXPOP1, j__L_Leaf3PopToWords)
416
+#ifdef JU_64BIT
417
+#define JL_LEAF4GROWINPLACE(Pop1) \
418
+ J__U_GROWCK(Pop1, cJL_LEAF4_MAXPOP1, j__L_Leaf4PopToWords)
419
+#define JL_LEAF5GROWINPLACE(Pop1) \
420
+ J__U_GROWCK(Pop1, cJL_LEAF5_MAXPOP1, j__L_Leaf5PopToWords)
421
+#define JL_LEAF6GROWINPLACE(Pop1) \
422
+ J__U_GROWCK(Pop1, cJL_LEAF6_MAXPOP1, j__L_Leaf6PopToWords)
423
+#define JL_LEAF7GROWINPLACE(Pop1) \
424
+ J__U_GROWCK(Pop1, cJL_LEAF7_MAXPOP1, j__L_Leaf7PopToWords)
425
+#endif
426
+#define JL_LEAFWGROWINPLACE(Pop1) \
427
+ J__U_GROWCK(Pop1, cJL_LEAFW_MAXPOP1, j__L_LeafWPopToWords)
428
+#define JL_LEAFVGROWINPLACE(Pop1) \
429
+ J__U_GROWCK(Pop1, cJU_BITSPERSUBEXPL, j__L_LeafVPopToWords)
430
+
431
+#define JL_LEAF1VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf1Offset[Pop1])
432
+#define JL_LEAF2VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf2Offset[Pop1])
433
+#define JL_LEAF3VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf3Offset[Pop1])
434
+#ifdef JU_64BIT
435
+#define JL_LEAF4VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf4Offset[Pop1])
436
+#define JL_LEAF5VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf5Offset[Pop1])
437
+#define JL_LEAF6VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf6Offset[Pop1])
438
+#define JL_LEAF7VALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_Leaf7Offset[Pop1])
439
+#endif
440
+#define JL_LEAFWVALUEAREA(Pjv,Pop1) (((PWord_t)(Pjv)) + j__L_LeafWOffset[Pop1])
441
+
442
+#define JL_LEAF1POPTOWORDS(Pop1) (j__L_Leaf1PopToWords[Pop1])
443
+#define JL_LEAF2POPTOWORDS(Pop1) (j__L_Leaf2PopToWords[Pop1])
444
+#define JL_LEAF3POPTOWORDS(Pop1) (j__L_Leaf3PopToWords[Pop1])
445
+#ifdef JU_64BIT
446
+#define JL_LEAF4POPTOWORDS(Pop1) (j__L_Leaf4PopToWords[Pop1])
447
+#define JL_LEAF5POPTOWORDS(Pop1) (j__L_Leaf5PopToWords[Pop1])
448
+#define JL_LEAF6POPTOWORDS(Pop1) (j__L_Leaf6PopToWords[Pop1])
449
+#define JL_LEAF7POPTOWORDS(Pop1) (j__L_Leaf7PopToWords[Pop1])
450
+#endif
451
+#define JL_LEAFWPOPTOWORDS(Pop1) (j__L_LeafWPopToWords[Pop1])
452
+#define JL_LEAFVPOPTOWORDS(Pop1) (j__L_LeafVPopToWords[Pop1])
453
+
454
+
455
+// FUNCTIONS TO ALLOCATE OBJECTS:
456
+
457
+PjLpm_t j__udyLAllocJLPM(void); // constant size.
458
+
459
+Pjbl_t j__udyLAllocJBL( PjLpm_t); // constant size.
460
+Pjbb_t j__udyLAllocJBB( PjLpm_t); // constant size.
461
+Pjp_t j__udyLAllocJBBJP(Word_t, PjLpm_t);
462
+Pjbu_t j__udyLAllocJBU( PjLpm_t); // constant size.
463
+
464
+Pjll_t j__udyLAllocJLL1( Word_t, PjLpm_t);
465
+Pjll_t j__udyLAllocJLL2( Word_t, PjLpm_t);
466
+Pjll_t j__udyLAllocJLL3( Word_t, PjLpm_t);
467
+
468
+#ifdef JU_64BIT
469
+Pjll_t j__udyLAllocJLL4( Word_t, PjLpm_t);
470
+Pjll_t j__udyLAllocJLL5( Word_t, PjLpm_t);
471
+Pjll_t j__udyLAllocJLL6( Word_t, PjLpm_t);
472
+Pjll_t j__udyLAllocJLL7( Word_t, PjLpm_t);
473
+#endif
474
+
475
+Pjlw_t j__udyLAllocJLW( Word_t ); // no PjLpm_t needed.
476
+PjLlb_t j__udyLAllocJLB1( PjLpm_t); // constant size.
477
+Pjv_t j__udyLAllocJV( Word_t, PjLpm_t);
478
+
479
+
480
+// FUNCTIONS TO FREE OBJECTS:
481
+
482
+void j__udyLFreeJLPM( PjLpm_t, PjLpm_t); // constant size.
483
+
484
+void j__udyLFreeJBL( Pjbl_t, PjLpm_t); // constant size.
485
+void j__udyLFreeJBB( Pjbb_t, PjLpm_t); // constant size.
486
+void j__udyLFreeJBBJP(Pjp_t, Word_t, PjLpm_t);
487
+void j__udyLFreeJBU( Pjbu_t, PjLpm_t); // constant size.
488
+
489
+void j__udyLFreeJLL1( Pjll_t, Word_t, PjLpm_t);
490
+void j__udyLFreeJLL2( Pjll_t, Word_t, PjLpm_t);
491
+void j__udyLFreeJLL3( Pjll_t, Word_t, PjLpm_t);
492
+
493
+#ifdef JU_64BIT
494
+void j__udyLFreeJLL4( Pjll_t, Word_t, PjLpm_t);
495
+void j__udyLFreeJLL5( Pjll_t, Word_t, PjLpm_t);
496
+void j__udyLFreeJLL6( Pjll_t, Word_t, PjLpm_t);
497
+void j__udyLFreeJLL7( Pjll_t, Word_t, PjLpm_t);
498
+#endif
499
+
500
+void j__udyLFreeJLW( Pjlw_t, Word_t, PjLpm_t);
501
+void j__udyLFreeJLB1( PjLlb_t, PjLpm_t); // constant size.
502
+void j__udyLFreeJV( Pjv_t, Word_t, PjLpm_t);
503
+void j__udyLFreeSM( Pjp_t, PjLpm_t); // everything below Pjp.
504
+
505
+#endif // ! _JUDYL_INCLUDED
libnetdata/libjudy/src/JudyL/JudyLByCount.c
new
+954
@@ -0,0 +1,954 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.28 $ $Source: /judy/src/JudyCommon/JudyByCount.c $
19
+//
20
+// Judy*ByCount() function for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a
24
+// version with cache line optimizations deleted, for testing.
25
+//
26
+// Judy*ByCount() is a conceptual although not literal inverse of Judy*Count().
27
+// Judy*Count() takes a pair of Indexes, and allows finding the ordinal of a
28
+// given Index (that is, its position in the list of valid indexes from the
29
+// beginning) as a degenerate case, because in general the count between two
30
+// Indexes, inclusive, is not always just the difference in their ordinals.
31
+// However, it suffices for Judy*ByCount() to simply be an ordinal-to-Index
32
+// mapper.
33
+//
34
+// Note: Like Judy*Count(), this code must "count sideways" in branches, which
35
+// can result in a lot of cache line fills. However, unlike Judy*Count(), this
36
+// code does not receive a specific Index, hence digit, where to start in each
37
+// branch, so it cant accurately calculate cache line fills required in each
38
+// direction. The best it can do is an approximation based on the total
39
+// population of the expanse (pop1 from Pjp) and the ordinal of the target
40
+// Index (see SETOFFSET()) within the expanse.
41
+//
42
+// Compile with -DSMARTMETRICS to obtain global variables containing smart
43
+// cache line metrics. Note: Dont turn this on simultaneously for this file
44
+// and JudyCount.c because they export the same globals.
45
+// ****************************************************************************
46
+
47
+#if (! (defined(JUDY1) || defined(JUDYL)))
48
+#error: One of -DJUDY1 or -DJUDYL must be specified.
49
+#endif
50
+
51
+#ifdef JUDY1
52
+#include "Judy1.h"
53
+#else
54
+#include "JudyL.h"
55
+#endif
56
+
57
+#include "JudyPrivate1L.h"
58
+
59
+// These are imported from JudyCount.c:
60
+//
61
+// TBD: Should this be in common code? Exported from a header file?
62
+
63
+#ifdef JUDY1
64
+extern Word_t j__udy1JPPop1(const Pjp_t Pjp);
65
+#define j__udyJPPop1 j__udy1JPPop1
66
+#else
67
+extern Word_t j__udyLJPPop1(const Pjp_t Pjp);
68
+#define j__udyJPPop1 j__udyLJPPop1
69
+#endif
70
+
71
+// Avoid duplicate symbols since this file is multi-compiled:
72
+
73
+#ifdef SMARTMETRICS
74
+#ifdef JUDY1
75
+Word_t jbb_upward = 0; // counts of directions taken:
76
+Word_t jbb_downward = 0;
77
+Word_t jbu_upward = 0;
78
+Word_t jbu_downward = 0;
79
+Word_t jlb_upward = 0;
80
+Word_t jlb_downward = 0;
81
+#else
82
+extern Word_t jbb_upward;
83
+extern Word_t jbb_downward;
84
+extern Word_t jbu_upward;
85
+extern Word_t jbu_downward;
86
+extern Word_t jlb_upward;
87
+extern Word_t jlb_downward;
88
+#endif
89
+#endif
90
+
91
+
92
+// ****************************************************************************
93
+// J U D Y 1 B Y C O U N T
94
+// J U D Y L B Y C O U N T
95
+//
96
+// See the manual entry.
97
+
98
+#ifdef JUDY1
99
+FUNCTION int Judy1ByCount
100
+#else
101
+FUNCTION PPvoid_t JudyLByCount
102
+#endif
103
+ (
104
+ Pcvoid_t PArray, // root pointer to first branch/leaf in SM.
105
+ Word_t Count, // ordinal of Index to find, 1..MAX.
106
+ Word_t * PIndex, // to return found Index.
107
+ PJError_t PJError // optional, for returning error info.
108
+ )
109
+{
110
+ Word_t Count0; // Count, base-0, to match pop0.
111
+ Word_t state; // current state in SM.
112
+ Word_t pop1; // of current branch or leaf, or of expanse.
113
+ Word_t pop1lower; // pop1 of expanses (JPs) below that for Count.
114
+ Word_t digit; // current word in branch.
115
+ Word_t jpcount; // JPs in a BranchB subexpanse.
116
+ long jpnum; // JP number in a branch (base 0).
117
+ long subexp; // for stepping through layer 1 (subexpanses).
118
+ int offset; // index ordinal within a leaf, base 0.
119
+
120
+ Pjp_t Pjp; // current JP in branch.
121
+ Pjll_t Pjll; // current Judy linear leaf.
122
+
123
+
124
+// CHECK FOR EMPTY ARRAY OR NULL PINDEX:
125
+
126
+ if (PArray == (Pvoid_t) NULL) JU_RET_NOTFOUND;
127
+
128
+ if (PIndex == (PWord_t) NULL)
129
+ {
130
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
131
+ JUDY1CODE(return(JERRI );)
132
+ JUDYLCODE(return(PPJERR);)
133
+ }
134
+
135
+// Convert Count to Count0; assume special case of Count = 0 maps to ~0, as
136
+// desired, to represent the last index in a full array:
137
+//
138
+// Note: Think of Count0 as a reliable "number of Indexes below the target."
139
+
140
+ Count0 = Count - 1;
141
+ assert((Count || Count0 == ~0)); // ensure CPU is sane about 0 - 1.
142
+ pop1lower = 0;
143
+
144
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
145
+ {
146
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
147
+
148
+ if (Count0 > Pjlw[0]) JU_RET_NOTFOUND; // too high.
149
+
150
+ *PIndex = Pjlw[Count]; // Index, base 1.
151
+
152
+ JU_RET_FOUND_LEAFW(Pjlw, Pjlw[0] + 1, Count0);
153
+ }
154
+ else
155
+ {
156
+ Pjpm_t Pjpm = P_JPM(PArray);
157
+
158
+ if (Count0 > (Pjpm->jpm_Pop0)) JU_RET_NOTFOUND; // too high.
159
+
160
+ Pjp = &(Pjpm->jpm_JP);
161
+ pop1 = (Pjpm->jpm_Pop0) + 1;
162
+
163
+// goto SMByCount;
164
+ }
165
+
166
+// COMMON CODE:
167
+//
168
+// Prepare to handle a root-level or lower-level branch: Save the current
169
+// state, obtain the total population for the branch in a state-dependent way,
170
+// and then branch to common code for multiple cases.
171
+//
172
+// For root-level branches, the state is always cJU_ROOTSTATE, and the array
173
+// population must already be set in pop1; it is not available in jp_DcdPopO.
174
+//
175
+// Note: The total population is only needed in cases where the common code
176
+// "counts down" instead of up to minimize cache line fills. However, its
177
+// available cheaply, and its better to do it with a constant shift (constant
178
+// state value) instead of a variable shift later "when needed".
179
+
180
+#define PREPB_ROOT(Next) \
181
+ state = cJU_ROOTSTATE; \
182
+ goto Next
183
+
184
+// Use PREPB_DCD() to first copy the Dcd bytes to *PIndex if there are any
185
+// (only if state < cJU_ROOTSTATE - 1):
186
+
187
+#define PREPB_DCD(Pjp,cState,Next) \
188
+ JU_SETDCD(*PIndex, Pjp, cState); \
189
+ PREPB((Pjp), cState, Next)
190
+
191
+#define PREPB(Pjp,cState,Next) \
192
+ state = (cState); \
193
+ pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \
194
+ goto Next
195
+
196
+// Calculate whether the ordinal of an Index within a given expanse falls in
197
+// the lower or upper half of the expanses population, taking care with
198
+// unsigned math and boundary conditions:
199
+//
200
+// Note: Assume the ordinal falls within the expanses population, that is,
201
+// 0 < (Count - Pop1lower) <= Pop1exp (assuming infinite math).
202
+//
203
+// Note: If the ordinal is the middle element, it doesnt matter whether
204
+// LOWERHALF() is TRUE or FALSE.
205
+
206
+#define LOWERHALF(Count0,Pop1lower,Pop1exp) \
207
+ (((Count0) - (Pop1lower)) < ((Pop1exp) / 2))
208
+
209
+// Calculate the (signed) offset within a leaf to the desired ordinal (Count -
210
+// Pop1lower; offset is one less), and optionally ensure its in range:
211
+
212
+#define SETOFFSET(Offset,Count0,Pop1lower,Pjp) \
213
+ (Offset) = (Count0) - (Pop1lower); \
214
+ assert((Offset) >= 0); \
215
+ assert((Offset) <= JU_JPLEAF_POP0(Pjp))
216
+
217
+// Variations for immediate indexes, with and without pop1-specific assertions:
218
+
219
+#define SETOFFSET_IMM_CK(Offset,Count0,Pop1lower,cPop1) \
220
+ (Offset) = (Count0) - (Pop1lower); \
221
+ assert((Offset) >= 0); \
222
+ assert((Offset) < (cPop1))
223
+
224
+#define SETOFFSET_IMM(Offset,Count0,Pop1lower) \
225
+ (Offset) = (Count0) - (Pop1lower)
226
+
227
+
228
+// STATE MACHINE -- TRAVERSE TREE:
229
+//
230
+// In branches, look for the expanse (digit), if any, where the total pop1
231
+// below or at that expanse would meet or exceed Count, meaning the Index must
232
+// be in this expanse.
233
+
234
+SMByCount: // return here for next branch/leaf.
235
+
236
+ switch (JU_JPTYPE(Pjp))
237
+ {
238
+
239
+
240
+// ----------------------------------------------------------------------------
241
+// LINEAR BRANCH; count populations in JPs in the JBL upwards until finding the
242
+// expanse (digit) containing Count, and "recurse".
243
+//
244
+// Note: There are no null JPs in a JBL; watch out for pop1 == 0.
245
+//
246
+// Note: A JBL should always fit in one cache line => no need to count up
247
+// versus down to save cache line fills.
248
+//
249
+// TBD: The previous is no longer true. Consider enhancing this code to count
250
+// up/down, but it can wait for a later tuning phase. In the meantime, PREPB()
251
+// sets pop1 for the whole array, but that value is not used here. 001215:
252
+// Maybe its true again?
253
+
254
+ case cJU_JPBRANCH_L2: PREPB_DCD(Pjp, 2, BranchL);
255
+#ifndef JU_64BIT
256
+ case cJU_JPBRANCH_L3: PREPB( Pjp, 3, BranchL);
257
+#else
258
+ case cJU_JPBRANCH_L3: PREPB_DCD(Pjp, 3, BranchL);
259
+ case cJU_JPBRANCH_L4: PREPB_DCD(Pjp, 4, BranchL);
260
+ case cJU_JPBRANCH_L5: PREPB_DCD(Pjp, 5, BranchL);
261
+ case cJU_JPBRANCH_L6: PREPB_DCD(Pjp, 6, BranchL);
262
+ case cJU_JPBRANCH_L7: PREPB( Pjp, 7, BranchL);
263
+#endif
264
+ case cJU_JPBRANCH_L: PREPB_ROOT( BranchL);
265
+ {
266
+ Pjbl_t Pjbl;
267
+
268
+// Common code (state-independent) for all cases of linear branches:
269
+
270
+BranchL:
271
+ Pjbl = P_JBL(Pjp->jp_Addr);
272
+
273
+ for (jpnum = 0; jpnum < (Pjbl->jbl_NumJPs); ++jpnum)
274
+ {
275
+ if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum))
276
+ == cJU_ALLONES)
277
+ {
278
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
279
+ JUDY1CODE(return(JERRI );)
280
+ JUDYLCODE(return(PPJERR);)
281
+ }
282
+ assert(pop1 != 0);
283
+
284
+// Warning: pop1lower and pop1 are unsigned, so do not subtract 1 and compare
285
+// >=, but instead use the following expression:
286
+
287
+ if (pop1lower + pop1 > Count0) // Index is in this expanse.
288
+ {
289
+ JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[jpnum], state);
290
+ Pjp = (Pjbl->jbl_jp) + jpnum;
291
+ goto SMByCount; // look under this expanse.
292
+ }
293
+
294
+ pop1lower += pop1; // add this JPs pop1.
295
+ }
296
+
297
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
298
+ JUDY1CODE(return(JERRI );)
299
+ JUDYLCODE(return(PPJERR);)
300
+
301
+ } // case cJU_JPBRANCH_L
302
+
303
+
304
+// ----------------------------------------------------------------------------
305
+// BITMAP BRANCH; count populations in JPs in the JBB upwards or downwards
306
+// until finding the expanse (digit) containing Count, and "recurse".
307
+//
308
+// Note: There are no null JPs in a JBB; watch out for pop1 == 0.
309
+
310
+ case cJU_JPBRANCH_B2: PREPB_DCD(Pjp, 2, BranchB);
311
+#ifndef JU_64BIT
312
+ case cJU_JPBRANCH_B3: PREPB( Pjp, 3, BranchB);
313
+#else
314
+ case cJU_JPBRANCH_B3: PREPB_DCD(Pjp, 3, BranchB);
315
+ case cJU_JPBRANCH_B4: PREPB_DCD(Pjp, 4, BranchB);
316
+ case cJU_JPBRANCH_B5: PREPB_DCD(Pjp, 5, BranchB);
317
+ case cJU_JPBRANCH_B6: PREPB_DCD(Pjp, 6, BranchB);
318
+ case cJU_JPBRANCH_B7: PREPB( Pjp, 7, BranchB);
319
+#endif
320
+ case cJU_JPBRANCH_B: PREPB_ROOT( BranchB);
321
+ {
322
+ Pjbb_t Pjbb;
323
+
324
+// Common code (state-independent) for all cases of bitmap branches:
325
+
326
+BranchB:
327
+ Pjbb = P_JBB(Pjp->jp_Addr);
328
+
329
+// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch:
330
+//
331
+// Note: BMPJP0 exists separately to support assertions.
332
+
333
+#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp)))
334
+#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum))
335
+
336
+
337
+// Common code for descending through a JP:
338
+//
339
+// Determine the digit for the expanse and save it in *PIndex; then "recurse".
340
+
341
+#define JBB_FOUNDEXPANSE \
342
+ { \
343
+ JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb,subexp), jpnum); \
344
+ JU_SETDIGIT(*PIndex, digit, state); \
345
+ Pjp = BMPJP(subexp, jpnum); \
346
+ goto SMByCount; \
347
+ }
348
+
349
+
350
+#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
351
+
352
+// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
353
+// in JPs upwards, or subtracting the pop1s in JPs downwards:
354
+//
355
+// See header comments about limitations of this for Judy*ByCount().
356
+
357
+#endif
358
+
359
+// COUNT UPWARD, adding each "below" JPs pop1:
360
+
361
+#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
362
+
363
+ if (LOWERHALF(Count0, pop1lower, pop1))
364
+ {
365
+#endif
366
+#ifdef SMARTMETRICS
367
+ ++jbb_upward;
368
+#endif
369
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
370
+ {
371
+ if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,subexp)))
372
+ && (BMPJP0(subexp) == (Pjp_t) NULL))
373
+ {
374
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
375
+ JUDY1CODE(return(JERRI );)
376
+ JUDYLCODE(return(PPJERR);)
377
+ }
378
+
379
+// Note: An empty subexpanse (jpcount == 0) is handled "for free":
380
+
381
+ for (jpnum = 0; jpnum < jpcount; ++jpnum)
382
+ {
383
+ if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
384
+ == cJU_ALLONES)
385
+ {
386
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
387
+ JUDY1CODE(return(JERRI );)
388
+ JUDYLCODE(return(PPJERR);)
389
+ }
390
+ assert(pop1 != 0);
391
+
392
+// Warning: pop1lower and pop1 are unsigned, see earlier comment:
393
+
394
+ if (pop1lower + pop1 > Count0)
395
+ JBB_FOUNDEXPANSE; // Index is in this expanse.
396
+
397
+ pop1lower += pop1; // add this JPs pop1.
398
+ }
399
+ }
400
+#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
401
+ }
402
+
403
+
404
+// COUNT DOWNWARD, subtracting each "above" JPs pop1 from the whole expanses
405
+// pop1:
406
+
407
+ else
408
+ {
409
+#ifdef SMARTMETRICS
410
+ ++jbb_downward;
411
+#endif
412
+ pop1lower += pop1; // add whole branch to start.
413
+
414
+ for (subexp = cJU_NUMSUBEXPB - 1; subexp >= 0; --subexp)
415
+ {
416
+ if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)))
417
+ && (BMPJP0(subexp) == (Pjp_t) NULL))
418
+ {
419
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
420
+ JUDY1CODE(return(JERRI );)
421
+ JUDYLCODE(return(PPJERR);)
422
+ }
423
+
424
+// Note: An empty subexpanse (jpcount == 0) is handled "for free":
425
+
426
+ for (jpnum = jpcount - 1; jpnum >= 0; --jpnum)
427
+ {
428
+ if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
429
+ == cJU_ALLONES)
430
+ {
431
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
432
+ JUDY1CODE(return(JERRI );)
433
+ JUDYLCODE(return(PPJERR);)
434
+ }
435
+ assert(pop1 != 0);
436
+
437
+// Warning: pop1lower and pop1 are unsigned, see earlier comment:
438
+
439
+ pop1lower -= pop1;
440
+
441
+// Beware unsigned math problems:
442
+
443
+ if ((pop1lower == 0) || (pop1lower - 1 < Count0))
444
+ JBB_FOUNDEXPANSE; // Index is in this expanse.
445
+ }
446
+ }
447
+ }
448
+#endif // NOSMARTJBB
449
+
450
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
451
+ JUDY1CODE(return(JERRI );)
452
+ JUDYLCODE(return(PPJERR);)
453
+
454
+ } // case cJU_JPBRANCH_B
455
+
456
+
457
+// ----------------------------------------------------------------------------
458
+// UNCOMPRESSED BRANCH; count populations in JPs in the JBU upwards or
459
+// downwards until finding the expanse (digit) containing Count, and "recurse".
460
+
461
+ case cJU_JPBRANCH_U2: PREPB_DCD(Pjp, 2, BranchU);
462
+#ifndef JU_64BIT
463
+ case cJU_JPBRANCH_U3: PREPB( Pjp, 3, BranchU);
464
+#else
465
+ case cJU_JPBRANCH_U3: PREPB_DCD(Pjp, 3, BranchU);
466
+ case cJU_JPBRANCH_U4: PREPB_DCD(Pjp, 4, BranchU);
467
+ case cJU_JPBRANCH_U5: PREPB_DCD(Pjp, 5, BranchU);
468
+ case cJU_JPBRANCH_U6: PREPB_DCD(Pjp, 6, BranchU);
469
+ case cJU_JPBRANCH_U7: PREPB( Pjp, 7, BranchU);
470
+#endif
471
+ case cJU_JPBRANCH_U: PREPB_ROOT( BranchU);
472
+ {
473
+ Pjbu_t Pjbu;
474
+
475
+// Common code (state-independent) for all cases of uncompressed branches:
476
+
477
+BranchU:
478
+ Pjbu = P_JBU(Pjp->jp_Addr);
479
+
480
+// Common code for descending through a JP:
481
+//
482
+// Save the digit for the expanse in *PIndex, then "recurse".
483
+
484
+#define JBU_FOUNDEXPANSE \
485
+ { \
486
+ JU_SETDIGIT(*PIndex, jpnum, state); \
487
+ Pjp = (Pjbu->jbu_jp) + jpnum; \
488
+ goto SMByCount; \
489
+ }
490
+
491
+
492
+#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
493
+
494
+// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
495
+// in JPs upwards, or subtracting the pop1s in JPs downwards:
496
+//
497
+// See header comments about limitations of this for Judy*ByCount().
498
+
499
+#endif
500
+
501
+// COUNT UPWARD, simply adding the pop1 of each JP:
502
+
503
+#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
504
+
505
+ if (LOWERHALF(Count0, pop1lower, pop1))
506
+ {
507
+#endif
508
+#ifdef SMARTMETRICS
509
+ ++jbu_upward;
510
+#endif
511
+
512
+ for (jpnum = 0; jpnum < cJU_BRANCHUNUMJPS; ++jpnum)
513
+ {
514
+ // shortcut, save a function call:
515
+
516
+ if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
517
+ continue;
518
+
519
+ if ((pop1 = j__udyJPPop1((Pjbu->jbu_jp) + jpnum))
520
+ == cJU_ALLONES)
521
+ {
522
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
523
+ JUDY1CODE(return(JERRI );)
524
+ JUDYLCODE(return(PPJERR);)
525
+ }
526
+ assert(pop1 != 0);
527
+
528
+// Warning: pop1lower and pop1 are unsigned, see earlier comment:
529
+
530
+ if (pop1lower + pop1 > Count0)
531
+ JBU_FOUNDEXPANSE; // Index is in this expanse.
532
+
533
+ pop1lower += pop1; // add this JPs pop1.
534
+ }
535
+#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
536
+ }
537
+
538
+
539
+// COUNT DOWNWARD, subtracting the pop1 of each JP above from the whole
540
+// expanses pop1:
541
+
542
+ else
543
+ {
544
+#ifdef SMARTMETRICS
545
+ ++jbu_downward;
546
+#endif
547
+ pop1lower += pop1; // add whole branch to start.
548
+
549
+ for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum >= 0; --jpnum)
550
+ {
551
+ // shortcut, save a function call:
552
+
553
+ if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
554
+ continue;
555
+
556
+ if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum))
557
+ == cJU_ALLONES)
558
+ {
559
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
560
+ JUDY1CODE(return(JERRI );)
561
+ JUDYLCODE(return(PPJERR);)
562
+ }
563
+ assert(pop1 != 0);
564
+
565
+// Warning: pop1lower and pop1 are unsigned, see earlier comment:
566
+
567
+ pop1lower -= pop1;
568
+
569
+// Beware unsigned math problems:
570
+
571
+ if ((pop1lower == 0) || (pop1lower - 1 < Count0))
572
+ JBU_FOUNDEXPANSE; // Index is in this expanse.
573
+ }
574
+ }
575
+#endif // NOSMARTJBU
576
+
577
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
578
+ JUDY1CODE(return(JERRI );)
579
+ JUDYLCODE(return(PPJERR);)
580
+
581
+ } // case cJU_JPBRANCH_U
582
+
583
+// ----------------------------------------------------------------------------
584
+// LINEAR LEAF:
585
+//
586
+// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf. First
587
+// copy Dcd bytes, if there are any (only if state < cJU_ROOTSTATE - 1), to
588
+// *PIndex.
589
+//
590
+// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
591
+// (linear leaf) as a side-effect, but dont depend on that (for JUDYL, which
592
+// is the only cases that need it anyway).
593
+
594
+#define PREPL_DCD(cState) \
595
+ JU_SETDCD(*PIndex, Pjp, cState); \
596
+ PREPL
597
+
598
+#ifdef JUDY1
599
+#define PREPL_SETPOP1 // not needed in any cases.
600
+#else
601
+#define PREPL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1
602
+#endif
603
+
604
+#define PREPL \
605
+ Pjll = P_JLL(Pjp->jp_Addr); \
606
+ PREPL_SETPOP1; \
607
+ SETOFFSET(offset, Count0, pop1lower, Pjp)
608
+
609
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
610
+ case cJU_JPLEAF1:
611
+
612
+ PREPL_DCD(1);
613
+ JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
614
+ JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
615
+#endif
616
+
617
+ case cJU_JPLEAF2:
618
+
619
+ PREPL_DCD(2);
620
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
621
+ | ((uint16_t *) Pjll)[offset];
622
+ JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
623
+
624
+#ifndef JU_64BIT
625
+ case cJU_JPLEAF3:
626
+ {
627
+ Word_t lsb;
628
+ PREPL;
629
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
630
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
631
+ JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
632
+ }
633
+
634
+#else
635
+ case cJU_JPLEAF3:
636
+ {
637
+ Word_t lsb;
638
+ PREPL_DCD(3);
639
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
640
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
641
+ JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
642
+ }
643
+
644
+ case cJU_JPLEAF4:
645
+
646
+ PREPL_DCD(4);
647
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
648
+ | ((uint32_t *) Pjll)[offset];
649
+ JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
650
+
651
+ case cJU_JPLEAF5:
652
+ {
653
+ Word_t lsb;
654
+ PREPL_DCD(5);
655
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
656
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
657
+ JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
658
+ }
659
+
660
+ case cJU_JPLEAF6:
661
+ {
662
+ Word_t lsb;
663
+ PREPL_DCD(6);
664
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
665
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
666
+ JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
667
+ }
668
+
669
+ case cJU_JPLEAF7:
670
+ {
671
+ Word_t lsb;
672
+ PREPL;
673
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
674
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
675
+ JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
676
+ }
677
+#endif
678
+
679
+
680
+// ----------------------------------------------------------------------------
681
+// BITMAP LEAF:
682
+//
683
+// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf by
684
+// counting bits. First copy Dcd bytes (always present since state 1 <
685
+// cJU_ROOTSTATE) to *PIndex.
686
+//
687
+// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
688
+// (bitmap leaf) as a side-effect, but dont depend on that.
689
+
690
+ case cJU_JPLEAF_B1:
691
+ {
692
+ Pjlb_t Pjlb;
693
+
694
+ JU_SETDCD(*PIndex, Pjp, 1);
695
+ Pjlb = P_JLB(Pjp->jp_Addr);
696
+ pop1 = JU_JPLEAF_POP0(Pjp) + 1;
697
+
698
+// COUNT UPWARD, adding the pop1 of each subexpanse:
699
+//
700
+// The entire bitmap should fit in one cache line, but still try to save some
701
+// CPU time by counting the fewest possible number of subexpanses from the
702
+// bitmap.
703
+//
704
+// See header comments about limitations of this for Judy*ByCount().
705
+
706
+#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
707
+
708
+ if (LOWERHALF(Count0, pop1lower, pop1))
709
+ {
710
+#endif
711
+#ifdef SMARTMETRICS
712
+ ++jlb_upward;
713
+#endif
714
+ for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
715
+ {
716
+ pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
717
+
718
+// Warning: pop1lower and pop1 are unsigned, see earlier comment:
719
+
720
+ if (pop1lower + pop1 > Count0)
721
+ goto LeafB1; // Index is in this subexpanse.
722
+
723
+ pop1lower += pop1; // add this subexpanses pop1.
724
+ }
725
+#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
726
+ }
727
+
728
+
729
+// COUNT DOWNWARD, subtracting each "above" subexpanses pop1 from the whole
730
+// expanses pop1:
731
+
732
+ else
733
+ {
734
+#ifdef SMARTMETRICS
735
+ ++jlb_downward;
736
+#endif
737
+ pop1lower += pop1; // add whole leaf to start.
738
+
739
+ for (subexp = cJU_NUMSUBEXPL - 1; subexp >= 0; --subexp)
740
+ {
741
+ pop1lower -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
742
+
743
+// Beware unsigned math problems:
744
+
745
+ if ((pop1lower == 0) || (pop1lower - 1 < Count0))
746
+ goto LeafB1; // Index is in this subexpanse.
747
+ }
748
+ }
749
+#endif // NOSMARTJLB
750
+
751
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
752
+ JUDY1CODE(return(JERRI );)
753
+ JUDYLCODE(return(PPJERR);)
754
+
755
+
756
+// RETURN INDEX FOUND:
757
+//
758
+// Come here with subexp set to the correct subexpanse, and pop1lower set to
759
+// the sum for all lower expanses and subexpanses in the Judy tree. Calculate
760
+// and save in *PIndex the digit corresponding to the ordinal in this
761
+// subexpanse.
762
+
763
+LeafB1:
764
+ SETOFFSET(offset, Count0, pop1lower, Pjp);
765
+ JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
766
+ JU_SETDIGIT1(*PIndex, digit);
767
+ JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
768
+// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + offset))
769
+
770
+ } // case cJU_JPLEAF_B1
771
+
772
+
773
+#ifdef JUDY1
774
+// ----------------------------------------------------------------------------
775
+// FULL POPULATION:
776
+//
777
+// Copy Dcd bytes (always present since state 1 < cJU_ROOTSTATE) to *PIndex,
778
+// then set the appropriate digit for the ordinal (see SETOFFSET()) in the leaf
779
+// as the LSB in *PIndex.
780
+
781
+ case cJ1_JPFULLPOPU1:
782
+
783
+ JU_SETDCD(*PIndex, Pjp, 1);
784
+ SETOFFSET(offset, Count0, pop1lower, Pjp);
785
+ assert(offset >= 0);
786
+ assert(offset <= cJU_JPFULLPOPU1_POP0);
787
+ JU_SETDIGIT1(*PIndex, offset);
788
+ JU_RET_FOUND_FULLPOPU1;
789
+#endif
790
+
791
+
792
+// ----------------------------------------------------------------------------
793
+// IMMEDIATE:
794
+//
795
+// Locate the Index with the proper ordinal (see SETOFFSET()) in the Immediate,
796
+// depending on leaf Index Size and pop1. Note: There are no Dcd bytes in an
797
+// Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the least bytes
798
+// of the immediate Index.
799
+
800
+#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState)
801
+
802
+ case cJU_JPIMMED_1_01: SET_01(1); goto Imm_01;
803
+ case cJU_JPIMMED_2_01: SET_01(2); goto Imm_01;
804
+ case cJU_JPIMMED_3_01: SET_01(3); goto Imm_01;
805
+#ifdef JU_64BIT
806
+ case cJU_JPIMMED_4_01: SET_01(4); goto Imm_01;
807
+ case cJU_JPIMMED_5_01: SET_01(5); goto Imm_01;
808
+ case cJU_JPIMMED_6_01: SET_01(6); goto Imm_01;
809
+ case cJU_JPIMMED_7_01: SET_01(7); goto Imm_01;
810
+#endif
811
+
812
+Imm_01:
813
+
814
+ DBGCODE(SETOFFSET_IMM_CK(offset, Count0, pop1lower, 1);)
815
+ JU_RET_FOUND_IMM_01(Pjp);
816
+
817
+// Shorthand for where to find start of Index bytes array:
818
+
819
+#ifdef JUDY1
820
+#define PJI (Pjp->jp_1Index)
821
+#else
822
+#define PJI (Pjp->jp_LIndex)
823
+#endif
824
+
825
+// Optional code to check the remaining ordinal (see SETOFFSET_IMM()) against
826
+// the Index Size of the Immediate:
827
+
828
+#ifndef DEBUG // simple placeholder:
829
+#define IMM(cPop1,Next) \
830
+ goto Next
831
+#else // extra pop1-specific checking:
832
+#define IMM(cPop1,Next) \
833
+ SETOFFSET_IMM_CK(offset, Count0, pop1lower, cPop1); \
834
+ goto Next
835
+#endif
836
+
837
+ case cJU_JPIMMED_1_02: IMM( 2, Imm1);
838
+ case cJU_JPIMMED_1_03: IMM( 3, Imm1);
839
+#if (defined(JUDY1) || defined(JU_64BIT))
840
+ case cJU_JPIMMED_1_04: IMM( 4, Imm1);
841
+ case cJU_JPIMMED_1_05: IMM( 5, Imm1);
842
+ case cJU_JPIMMED_1_06: IMM( 6, Imm1);
843
+ case cJU_JPIMMED_1_07: IMM( 7, Imm1);
844
+#endif
845
+#if (defined(JUDY1) && defined(JU_64BIT))
846
+ case cJ1_JPIMMED_1_08: IMM( 8, Imm1);
847
+ case cJ1_JPIMMED_1_09: IMM( 9, Imm1);
848
+ case cJ1_JPIMMED_1_10: IMM(10, Imm1);
849
+ case cJ1_JPIMMED_1_11: IMM(11, Imm1);
850
+ case cJ1_JPIMMED_1_12: IMM(12, Imm1);
851
+ case cJ1_JPIMMED_1_13: IMM(13, Imm1);
852
+ case cJ1_JPIMMED_1_14: IMM(14, Imm1);
853
+ case cJ1_JPIMMED_1_15: IMM(15, Imm1);
854
+#endif
855
+
856
+Imm1: SETOFFSET_IMM(offset, Count0, pop1lower);
857
+ JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
858
+ JU_RET_FOUND_IMM(Pjp, offset);
859
+
860
+#if (defined(JUDY1) || defined(JU_64BIT))
861
+ case cJU_JPIMMED_2_02: IMM(2, Imm2);
862
+ case cJU_JPIMMED_2_03: IMM(3, Imm2);
863
+#endif
864
+#if (defined(JUDY1) && defined(JU_64BIT))
865
+ case cJ1_JPIMMED_2_04: IMM(4, Imm2);
866
+ case cJ1_JPIMMED_2_05: IMM(5, Imm2);
867
+ case cJ1_JPIMMED_2_06: IMM(6, Imm2);
868
+ case cJ1_JPIMMED_2_07: IMM(7, Imm2);
869
+#endif
870
+
871
+#if (defined(JUDY1) || defined(JU_64BIT))
872
+Imm2: SETOFFSET_IMM(offset, Count0, pop1lower);
873
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
874
+ | ((uint16_t *) PJI)[offset];
875
+ JU_RET_FOUND_IMM(Pjp, offset);
876
+#endif
877
+
878
+#if (defined(JUDY1) || defined(JU_64BIT))
879
+ case cJU_JPIMMED_3_02: IMM(2, Imm3);
880
+#endif
881
+#if (defined(JUDY1) && defined(JU_64BIT))
882
+ case cJ1_JPIMMED_3_03: IMM(3, Imm3);
883
+ case cJ1_JPIMMED_3_04: IMM(4, Imm3);
884
+ case cJ1_JPIMMED_3_05: IMM(5, Imm3);
885
+#endif
886
+
887
+#if (defined(JUDY1) || defined(JU_64BIT))
888
+Imm3:
889
+ {
890
+ Word_t lsb;
891
+ SETOFFSET_IMM(offset, Count0, pop1lower);
892
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
893
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
894
+ JU_RET_FOUND_IMM(Pjp, offset);
895
+ }
896
+#endif
897
+
898
+#if (defined(JUDY1) && defined(JU_64BIT))
899
+ case cJ1_JPIMMED_4_02: IMM(2, Imm4);
900
+ case cJ1_JPIMMED_4_03: IMM(3, Imm4);
901
+
902
+Imm4: SETOFFSET_IMM(offset, Count0, pop1lower);
903
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
904
+ | ((uint32_t *) PJI)[offset];
905
+ JU_RET_FOUND_IMM(Pjp, offset);
906
+
907
+ case cJ1_JPIMMED_5_02: IMM(2, Imm5);
908
+ case cJ1_JPIMMED_5_03: IMM(3, Imm5);
909
+
910
+Imm5:
911
+ {
912
+ Word_t lsb;
913
+ SETOFFSET_IMM(offset, Count0, pop1lower);
914
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
915
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
916
+ JU_RET_FOUND_IMM(Pjp, offset);
917
+ }
918
+
919
+ case cJ1_JPIMMED_6_02: IMM(2, Imm6);
920
+
921
+Imm6:
922
+ {
923
+ Word_t lsb;
924
+ SETOFFSET_IMM(offset, Count0, pop1lower);
925
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
926
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
927
+ JU_RET_FOUND_IMM(Pjp, offset);
928
+ }
929
+
930
+ case cJ1_JPIMMED_7_02: IMM(2, Imm7);
931
+
932
+Imm7:
933
+ {
934
+ Word_t lsb;
935
+ SETOFFSET_IMM(offset, Count0, pop1lower);
936
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
937
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
938
+ JU_RET_FOUND_IMM(Pjp, offset);
939
+ }
940
+#endif // (JUDY1 && JU_64BIT)
941
+
942
+
943
+// ----------------------------------------------------------------------------
944
+// UNEXPECTED JP TYPES:
945
+
946
+ default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
947
+ JUDY1CODE(return(JERRI );)
948
+ JUDYLCODE(return(PPJERR);)
949
+
950
+ } // SMByCount switch.
951
+
952
+ /*NOTREACHED*/
953
+
954
+} // Judy1ByCount() / JudyLByCount()
libnetdata/libjudy/src/JudyL/JudyLCascade.c
new
+1942
@@ -0,0 +1,1942 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.38 $ $Source: /judy/src/JudyCommon/JudyCascade.c $
19
+
20
+#ifdef JUDY1
21
+#include "Judy1.h"
22
+#else
23
+#include "JudyL.h"
24
+#endif
25
+
26
+#include "JudyPrivate1L.h"
27
+
28
+extern int j__udyCreateBranchL(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
29
+extern int j__udyCreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
30
+
31
+DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);)
32
+
33
+static const jbb_t StageJBBZero; // zeroed versions of namesake struct.
34
+
35
+// TBD: There are multiple copies of (some of) these CopyWto3, Copy3toW,
36
+// CopyWto7 and Copy7toW functions in Judy1Cascade.c, JudyLCascade.c, and
37
+// JudyDecascade.c. These static functions should probably be moved to a
38
+// common place, made macros, or something to avoid having four copies.
39
+
40
+
41
+// ****************************************************************************
42
+// __ J U D Y C O P Y X T O W
43
+
44
+
45
+FUNCTION static void j__udyCopy3toW(
46
+ PWord_t PDest,
47
+ uint8_t * PSrc,
48
+ Word_t LeafIndexes)
49
+{
50
+ do
51
+ {
52
+ JU_COPY3_PINDEX_TO_LONG(*PDest, PSrc);
53
+ PSrc += 3;
54
+ PDest += 1;
55
+
56
+ } while(--LeafIndexes);
57
+
58
+} //j__udyCopy3toW()
59
+
60
+
61
+#ifdef JU_64BIT
62
+
63
+FUNCTION static void j__udyCopy4toW(
64
+ PWord_t PDest,
65
+ uint32_t * PSrc,
66
+ Word_t LeafIndexes)
67
+{
68
+ do { *PDest++ = *PSrc++;
69
+ } while(--LeafIndexes);
70
+
71
+} // j__udyCopy4toW()
72
+
73
+
74
+FUNCTION static void j__udyCopy5toW(
75
+ PWord_t PDest,
76
+ uint8_t * PSrc,
77
+ Word_t LeafIndexes)
78
+{
79
+ do
80
+ {
81
+ JU_COPY5_PINDEX_TO_LONG(*PDest, PSrc);
82
+ PSrc += 5;
83
+ PDest += 1;
84
+
85
+ } while(--LeafIndexes);
86
+
87
+} // j__udyCopy5toW()
88
+
89
+
90
+FUNCTION static void j__udyCopy6toW(
91
+ PWord_t PDest,
92
+ uint8_t * PSrc,
93
+ Word_t LeafIndexes)
94
+{
95
+ do
96
+ {
97
+ JU_COPY6_PINDEX_TO_LONG(*PDest, PSrc);
98
+ PSrc += 6;
99
+ PDest += 1;
100
+
101
+ } while(--LeafIndexes);
102
+
103
+} // j__udyCopy6toW()
104
+
105
+
106
+FUNCTION static void j__udyCopy7toW(
107
+ PWord_t PDest,
108
+ uint8_t * PSrc,
109
+ Word_t LeafIndexes)
110
+{
111
+ do
112
+ {
113
+ JU_COPY7_PINDEX_TO_LONG(*PDest, PSrc);
114
+ PSrc += 7;
115
+ PDest += 1;
116
+
117
+ } while(--LeafIndexes);
118
+
119
+} // j__udyCopy7toW()
120
+
121
+#endif // JU_64BIT
122
+
123
+
124
+// ****************************************************************************
125
+// __ J U D Y C O P Y W T O X
126
+
127
+
128
+FUNCTION static void j__udyCopyWto3(
129
+ uint8_t * PDest,
130
+ PWord_t PSrc,
131
+ Word_t LeafIndexes)
132
+{
133
+ do
134
+ {
135
+ JU_COPY3_LONG_TO_PINDEX(PDest, *PSrc);
136
+ PSrc += 1;
137
+ PDest += 3;
138
+
139
+ } while(--LeafIndexes);
140
+
141
+} // j__udyCopyWto3()
142
+
143
+
144
+#ifdef JU_64BIT
145
+
146
+FUNCTION static void j__udyCopyWto4(
147
+ uint8_t * PDest,
148
+ PWord_t PSrc,
149
+ Word_t LeafIndexes)
150
+{
151
+ uint32_t *PDest32 = (uint32_t *)PDest;
152
+
153
+ do
154
+ {
155
+ *PDest32 = *PSrc;
156
+ PSrc += 1;
157
+ PDest32 += 1;
158
+ } while(--LeafIndexes);
159
+
160
+} // j__udyCopyWto4()
161
+
162
+
163
+FUNCTION static void j__udyCopyWto5(
164
+ uint8_t * PDest,
165
+ PWord_t PSrc,
166
+ Word_t LeafIndexes)
167
+{
168
+ do
169
+ {
170
+ JU_COPY5_LONG_TO_PINDEX(PDest, *PSrc);
171
+ PSrc += 1;
172
+ PDest += 5;
173
+
174
+ } while(--LeafIndexes);
175
+
176
+} // j__udyCopyWto5()
177
+
178
+
179
+FUNCTION static void j__udyCopyWto6(
180
+ uint8_t * PDest,
181
+ PWord_t PSrc,
182
+ Word_t LeafIndexes)
183
+{
184
+ do
185
+ {
186
+ JU_COPY6_LONG_TO_PINDEX(PDest, *PSrc);
187
+ PSrc += 1;
188
+ PDest += 6;
189
+
190
+ } while(--LeafIndexes);
191
+
192
+} // j__udyCopyWto6()
193
+
194
+
195
+FUNCTION static void j__udyCopyWto7(
196
+ uint8_t * PDest,
197
+ PWord_t PSrc,
198
+ Word_t LeafIndexes)
199
+{
200
+ do
201
+ {
202
+ JU_COPY7_LONG_TO_PINDEX(PDest, *PSrc);
203
+ PSrc += 1;
204
+ PDest += 7;
205
+
206
+ } while(--LeafIndexes);
207
+
208
+} // j__udyCopyWto7()
209
+
210
+#endif // JU_64BIT
211
+
212
+
213
+// ****************************************************************************
214
+// COMMON CODE (MACROS):
215
+//
216
+// Free objects in an array of valid JPs, StageJP[ExpCnt] == last one may
217
+// include Immeds, which are ignored.
218
+
219
+#define FREEALLEXIT(ExpCnt,StageJP,Pjpm) \
220
+ { \
221
+ Word_t _expct = (ExpCnt); \
222
+ while (_expct--) j__udyFreeSM(&((StageJP)[_expct]), Pjpm); \
223
+ return(-1); \
224
+ }
225
+
226
+// Clear the array that keeps track of the number of JPs in a subexpanse:
227
+
228
+#define ZEROJP(SubJPCount) \
229
+ { \
230
+ int ii; \
231
+ for (ii = 0; ii < cJU_NUMSUBEXPB; ii++) (SubJPCount[ii]) = 0; \
232
+ }
233
+
234
+// ****************************************************************************
235
+// __ J U D Y S T A G E J B B T O J B B
236
+//
237
+// Create a mallocd BranchB (jbb_t) from a staged BranchB while "splaying" a
238
+// single old leaf. Return -1 if out of memory, otherwise 1.
239
+
240
+static int j__udyStageJBBtoJBB(
241
+ Pjp_t PjpLeaf, // JP of leaf being splayed.
242
+ Pjbb_t PStageJBB, // temp jbb_t on stack.
243
+ Pjp_t PjpArray, // array of JPs to splayed new leaves.
244
+ uint8_t * PSubCount, // count of JPs for each subexpanse.
245
+ Pjpm_t Pjpm) // the jpm_t for JudyAlloc*().
246
+{
247
+ Pjbb_t PjbbRaw; // pointer to new bitmap branch.
248
+ Pjbb_t Pjbb;
249
+ Word_t subexp;
250
+
251
+// Get memory for new BranchB:
252
+
253
+ if ((PjbbRaw = j__udyAllocJBB(Pjpm)) == (Pjbb_t) NULL) return(-1);
254
+ Pjbb = P_JBB(PjbbRaw);
255
+
256
+// Copy staged BranchB into just-allocated BranchB:
257
+
258
+ *Pjbb = *PStageJBB;
259
+
260
+// Allocate the JP subarrays (BJP) for the new BranchB:
261
+
262
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; subexp++)
263
+ {
264
+ Pjp_t PjpRaw;
265
+ Pjp_t Pjp;
266
+ Word_t NumJP; // number of JPs in each subexpanse.
267
+
268
+ if ((NumJP = PSubCount[subexp]) == 0) continue; // empty.
269
+
270
+// Out of memory, back out previous allocations:
271
+
272
+ if ((PjpRaw = j__udyAllocJBBJP(NumJP, Pjpm)) == (Pjp_t) NULL)
273
+ {
274
+ while(subexp--)
275
+ {
276
+ if ((NumJP = PSubCount[subexp]) == 0) continue;
277
+
278
+ PjpRaw = JU_JBB_PJP(Pjbb, subexp);
279
+ j__udyFreeJBBJP(PjpRaw, NumJP, Pjpm);
280
+ }
281
+ j__udyFreeJBB(PjbbRaw, Pjpm);
282
+ return(-1); // out of memory.
283
+ }
284
+ Pjp = P_JP(PjpRaw);
285
+
286
+// Place the JP subarray pointer in the new BranchB, copy subarray JPs, and
287
+// advance to the next subexpanse:
288
+
289
+ JU_JBB_PJP(Pjbb, subexp) = PjpRaw;
290
+ JU_COPYMEM(Pjp, PjpArray, NumJP);
291
+ PjpArray += NumJP;
292
+
293
+ } // for each subexpanse.
294
+
295
+// Change the PjpLeaf from Leaf to BranchB:
296
+
297
+ PjpLeaf->jp_Addr = (Word_t) PjbbRaw;
298
+ PjpLeaf->jp_Type += cJU_JPBRANCH_B2 - cJU_JPLEAF2; // Leaf to BranchB.
299
+
300
+ return(1);
301
+
302
+} // j__udyStageJBBtoJBB()
303
+
304
+
305
+// ****************************************************************************
306
+// __ J U D Y J L L 2 T O J L B 1
307
+//
308
+// Create a LeafB1 (jlb_t = JLB1) from a Leaf2 (2-byte Indexes and for JudyL,
309
+// Word_t Values). Return NULL if out of memory, else a pointer to the new
310
+// LeafB1.
311
+//
312
+// NOTE: Caller must release the Leaf2 that was passed in.
313
+
314
+FUNCTION static Pjlb_t j__udyJLL2toJLB1(
315
+ uint16_t * Pjll, // array of 16-bit indexes.
316
+#ifdef JUDYL
317
+ Pjv_t Pjv, // array of associated values.
318
+#endif
319
+ Word_t LeafPop1, // number of indexes/values.
320
+ Pvoid_t Pjpm) // jpm_t for JudyAlloc*()/JudyFree*().
321
+{
322
+ Pjlb_t PjlbRaw;
323
+ Pjlb_t Pjlb;
324
+ int offset;
325
+JUDYLCODE(int subexp;)
326
+
327
+// Allocate the LeafB1:
328
+
329
+ if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL)
330
+ return((Pjlb_t) NULL);
331
+ Pjlb = P_JLB(PjlbRaw);
332
+
333
+// Copy Leaf2 indexes to LeafB1:
334
+
335
+ for (offset = 0; offset < LeafPop1; ++offset)
336
+ JU_BITMAPSETL(Pjlb, Pjll[offset]);
337
+
338
+#ifdef JUDYL
339
+
340
+// Build LeafVs from bitmap:
341
+
342
+ for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
343
+ {
344
+ struct _POINTER_VALUES
345
+ {
346
+ Word_t pv_Pop1; // size of value area.
347
+ Pjv_t pv_Pjv; // raw pointer to value area.
348
+ } pv[cJU_NUMSUBEXPL];
349
+
350
+// Get the population of the subexpanse, and if any, allocate a LeafV:
351
+
352
+ pv[subexp].pv_Pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
353
+
354
+ if (pv[subexp].pv_Pop1)
355
+ {
356
+ Pjv_t Pjvnew;
357
+
358
+// TBD: There is an opportunity to put pop == 1 value in pointer:
359
+
360
+ pv[subexp].pv_Pjv = j__udyLAllocJV(pv[subexp].pv_Pop1, Pjpm);
361
+
362
+// Upon out of memory, free all previously allocated:
363
+
364
+ if (pv[subexp].pv_Pjv == (Pjv_t) NULL)
365
+ {
366
+ while(subexp--)
367
+ {
368
+ if (pv[subexp].pv_Pop1)
369
+ {
370
+ j__udyLFreeJV(pv[subexp].pv_Pjv, pv[subexp].pv_Pop1,
371
+ Pjpm);
372
+ }
373
+ }
374
+ j__udyFreeJLB1(PjlbRaw, Pjpm);
375
+ return((Pjlb_t) NULL);
376
+ }
377
+
378
+ Pjvnew = P_JV(pv[subexp].pv_Pjv);
379
+ JU_COPYMEM(Pjvnew, Pjv, pv[subexp].pv_Pop1);
380
+ Pjv += pv[subexp].pv_Pop1; // advance value pointer.
381
+
382
+// Place raw pointer to value array in bitmap subexpanse:
383
+
384
+ JL_JLB_PVALUE(Pjlb, subexp) = pv[subexp].pv_Pjv;
385
+
386
+ } // populated subexpanse.
387
+ } // each subexpanse.
388
+
389
+#endif // JUDYL
390
+
391
+ return(PjlbRaw); // pointer to LeafB1.
392
+
393
+} // j__udyJLL2toJLB1()
394
+
395
+
396
+// ****************************************************************************
397
+// __ J U D Y C A S C A D E 1
398
+//
399
+// Create bitmap leaf from 1-byte Indexes and Word_t Values.
400
+//
401
+// TBD: There must be a better way.
402
+//
403
+// Only for JudyL 32 bit: (note, unifdef disallows comment on next line)
404
+
405
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
406
+
407
+FUNCTION int j__udyCascade1(
408
+ Pjp_t Pjp,
409
+ Pvoid_t Pjpm)
410
+{
411
+ Word_t DcdP0;
412
+ uint8_t * PLeaf;
413
+ Pjlb_t PjlbRaw;
414
+ Pjlb_t Pjlb;
415
+ Word_t Pop1;
416
+ Word_t ii; // temp for loop counter
417
+JUDYLCODE(Pjv_t Pjv;)
418
+
419
+ assert(JU_JPTYPE(Pjp) == cJU_JPLEAF1);
420
+ assert((JU_JPDCDPOP0(Pjp) & 0xFF) == (cJU_LEAF1_MAXPOP1-1));
421
+
422
+ PjlbRaw = j__udyAllocJLB1(Pjpm);
423
+ if (PjlbRaw == (Pjlb_t) NULL) return(-1);
424
+
425
+ Pjlb = P_JLB(PjlbRaw);
426
+ PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr);
427
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
428
+
429
+ JUDYLCODE(Pjv = JL_LEAF1VALUEAREA(PLeaf, Pop1);)
430
+
431
+// Copy 1 byte index Leaf to bitmap Leaf
432
+ for (ii = 0; ii < Pop1; ii++) JU_BITMAPSETL(Pjlb, PLeaf[ii]);
433
+
434
+#ifdef JUDYL
435
+// Build 8 subexpanse Value leaves from bitmap
436
+ for (ii = 0; ii < cJU_NUMSUBEXPL; ii++)
437
+ {
438
+// Get number of Indexes in subexpanse
439
+ if ((Pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, ii))))
440
+ {
441
+ Pjv_t PjvnewRaw; // value area of new leaf.
442
+ Pjv_t Pjvnew;
443
+
444
+ PjvnewRaw = j__udyLAllocJV(Pop1, Pjpm);
445
+ if (PjvnewRaw == (Pjv_t) NULL) // out of memory.
446
+ {
447
+// Free prevously allocated LeafVs:
448
+ while(ii--)
449
+ {
450
+ if ((Pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, ii))))
451
+ {
452
+ PjvnewRaw = JL_JLB_PVALUE(Pjlb, ii);
453
+ j__udyLFreeJV(PjvnewRaw, Pop1, Pjpm);
454
+ }
455
+ }
456
+// Free the bitmap leaf
457
+ j__udyLFreeJLB1(PjlbRaw,Pjpm);
458
+ return(-1);
459
+ }
460
+ Pjvnew = P_JV(PjvnewRaw);
461
+ JU_COPYMEM(Pjvnew, Pjv, Pop1);
462
+
463
+ Pjv += Pop1;
464
+ JL_JLB_PVALUE(Pjlb, ii) = PjvnewRaw;
465
+ }
466
+ }
467
+#endif // JUDYL
468
+
469
+ DcdP0 = JU_JPDCDPOP0(Pjp) | (PLeaf[0] & cJU_DCDMASK(1));
470
+ JU_JPSETADT(Pjp, (Word_t)PjlbRaw, DcdP0, cJU_JPLEAF_B1);
471
+
472
+ return(1); // return success
473
+
474
+} // j__udyCascade1()
475
+
476
+#endif // (!(JUDY1 && JU_64BIT))
477
+
478
+
479
+// ****************************************************************************
480
+// __ J U D Y C A S C A D E 2
481
+//
482
+// Entry PLeaf of size LeafPop1 is either compressed or splayed with pointer
483
+// returned in Pjp. Entry Levels sizeof(Word_t) down to level 2.
484
+//
485
+// Splay or compress the 2-byte Index Leaf that Pjp point to. Return *Pjp as a
486
+// (compressed) cJU_LEAFB1 or a cJU_BRANCH_*2
487
+
488
+FUNCTION int j__udyCascade2(
489
+ Pjp_t Pjp,
490
+ Pvoid_t Pjpm)
491
+{
492
+ uint16_t * PLeaf; // pointer to leaf, explicit type.
493
+ Word_t End, Start; // temporaries.
494
+ Word_t ExpCnt; // count of expanses of splay.
495
+ Word_t CIndex; // current Index word.
496
+JUDYLCODE(Pjv_t Pjv;) // value area of leaf.
497
+
498
+// Temp staging for parts(Leaves) of newly splayed leaf
499
+ jp_t StageJP [cJU_LEAF2_MAXPOP1]; // JPs of new leaves
500
+ uint8_t StageExp [cJU_LEAF2_MAXPOP1]; // Expanses of new leaves
501
+ uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse
502
+ jbb_t StageJBB; // staged bitmap branch
503
+
504
+ assert(JU_JPTYPE(Pjp) == cJU_JPLEAF2);
505
+ assert((JU_JPDCDPOP0(Pjp) & 0xFFFF) == (cJU_LEAF2_MAXPOP1-1));
506
+
507
+// Get the address of the Leaf
508
+ PLeaf = (uint16_t *) P_JLL(Pjp->jp_Addr);
509
+
510
+// And its Value area
511
+ JUDYLCODE(Pjv = JL_LEAF2VALUEAREA(PLeaf, cJU_LEAF2_MAXPOP1);)
512
+
513
+// If Leaf is in 1 expanse -- just compress it to a Bitmap Leaf
514
+
515
+ CIndex = PLeaf[0];
516
+ if (!JU_DIGITATSTATE(CIndex ^ PLeaf[cJU_LEAF2_MAXPOP1-1], 2))
517
+ {
518
+// cJU_JPLEAF_B1
519
+ Word_t DcdP0;
520
+ Pjlb_t PjlbRaw;
521
+ PjlbRaw = j__udyJLL2toJLB1(PLeaf,
522
+#ifdef JUDYL
523
+ Pjv,
524
+#endif
525
+ cJU_LEAF2_MAXPOP1, Pjpm);
526
+ if (PjlbRaw == (Pjlb_t)NULL) return(-1); // out of memory
527
+
528
+// Merge in another Dcd byte because compressing
529
+ DcdP0 = (CIndex & cJU_DCDMASK(1)) | JU_JPDCDPOP0(Pjp);
530
+ JU_JPSETADT(Pjp, (Word_t)PjlbRaw, DcdP0, cJU_JPLEAF_B1);
531
+
532
+ return(1);
533
+ }
534
+
535
+// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression
536
+
537
+ StageJBB = StageJBBZero; // zero staged bitmap branch
538
+ ZEROJP(SubJPCount);
539
+
540
+// Splay the 2 byte index Leaf to 1 byte Index Leaves
541
+ for (ExpCnt = Start = 0, End = 1; ; End++)
542
+ {
543
+// Check if new expanse or last one
544
+ if ( (End == cJU_LEAF2_MAXPOP1)
545
+ ||
546
+ (JU_DIGITATSTATE(CIndex ^ PLeaf[End], 2))
547
+ )
548
+ {
549
+// Build a leaf below the previous expanse
550
+//
551
+ Pjp_t PjpJP = StageJP + ExpCnt;
552
+ Word_t Pop1 = End - Start;
553
+ Word_t expanse = JU_DIGITATSTATE(CIndex, 2);
554
+ Word_t subexp = expanse / cJU_BITSPERSUBEXPB;
555
+//
556
+// set the bit that is the current expanse
557
+ JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse);
558
+#ifdef SUBEXPCOUNTS
559
+ StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse
560
+#endif
561
+// count number of expanses in each subexpanse
562
+ SubJPCount[subexp]++;
563
+
564
+// Save byte expanse of leaf
565
+ StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 2);
566
+
567
+ if (Pop1 == 1) // cJU_JPIMMED_1_01
568
+ {
569
+ Word_t DcdP0;
570
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(1)) |
571
+ CIndex;
572
+#ifdef JUDY1
573
+ JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_1_01);
574
+#else // JUDYL
575
+ JU_JPSETADT(PjpJP, Pjv[Start], DcdP0,
576
+ cJL_JPIMMED_1_01);
577
+#endif // JUDYL
578
+ }
579
+ else if (Pop1 <= cJU_IMMED1_MAXPOP1) // bigger
580
+ {
581
+// cJL_JPIMMED_1_02..3: JudyL 32
582
+// cJ1_JPIMMED_1_02..7: Judy1 32
583
+// cJL_JPIMMED_1_02..7: JudyL 64
584
+// cJ1_JPIMMED_1_02..15: Judy1 64
585
+#ifdef JUDYL
586
+ Pjv_t PjvnewRaw; // value area of leaf.
587
+ Pjv_t Pjvnew;
588
+
589
+// Allocate Value area for Immediate Leaf
590
+ PjvnewRaw = j__udyLAllocJV(Pop1, Pjpm);
591
+ if (PjvnewRaw == (Pjv_t) NULL)
592
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
593
+
594
+ Pjvnew = P_JV(PjvnewRaw);
595
+
596
+// Copy to Values to Value Leaf
597
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
598
+ PjpJP->jp_Addr = (Word_t) PjvnewRaw;
599
+
600
+// Copy to JP as an immediate Leaf
601
+ JU_COPYMEM(PjpJP->jp_LIndex, PLeaf + Start,
602
+ Pop1);
603
+#else
604
+ JU_COPYMEM(PjpJP->jp_1Index, PLeaf + Start,
605
+ Pop1);
606
+#endif
607
+// Set Type, Population and Index size
608
+ PjpJP->jp_Type = cJU_JPIMMED_1_02 + Pop1 - 2;
609
+ }
610
+
611
+// 64Bit Judy1 does not have Leaf1: (note, unifdef disallows comment on next
612
+// line)
613
+
614
+#if (! (defined(JUDY1) && defined(JU_64BIT)))
615
+ else if (Pop1 <= cJU_LEAF1_MAXPOP1) // still bigger
616
+ {
617
+// cJU_JPLEAF1
618
+ Word_t DcdP0;
619
+ Pjll_t PjllRaw; // pointer to new leaf.
620
+ Pjll_t Pjll;
621
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
622
+
623
+// Get a new Leaf
624
+ PjllRaw = j__udyAllocJLL1(Pop1, Pjpm);
625
+ if (PjllRaw == (Pjll_t)NULL)
626
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
627
+
628
+ Pjll = P_JLL(PjllRaw);
629
+#ifdef JUDYL
630
+// Copy to Values to new Leaf
631
+ Pjvnew = JL_LEAF1VALUEAREA(Pjll, Pop1);
632
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
633
+#endif
634
+// Copy Indexes to new Leaf
635
+ JU_COPYMEM((uint8_t *)Pjll, PLeaf+Start, Pop1);
636
+
637
+ DBGCODE(JudyCheckSorted(Pjll, Pop1, 1);)
638
+
639
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(2))
640
+ |
641
+ (CIndex & cJU_DCDMASK(2-1))
642
+ |
643
+ (Pop1 - 1);
644
+
645
+ JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0,
646
+ cJU_JPLEAF1);
647
+ }
648
+#endif // (!(JUDY1 && JU_64BIT)) // Not 64Bit Judy1
649
+
650
+ else // biggest
651
+ {
652
+// cJU_JPLEAF_B1
653
+ Word_t DcdP0;
654
+ Pjlb_t PjlbRaw;
655
+ PjlbRaw = j__udyJLL2toJLB1(
656
+ PLeaf + Start,
657
+#ifdef JUDYL
658
+ Pjv + Start,
659
+#endif
660
+ Pop1, Pjpm);
661
+ if (PjlbRaw == (Pjlb_t)NULL)
662
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
663
+
664
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(2))
665
+ |
666
+ (CIndex & cJU_DCDMASK(2-1))
667
+ |
668
+ (Pop1 - 1);
669
+
670
+ JU_JPSETADT(PjpJP, (Word_t)PjlbRaw, DcdP0,
671
+ cJU_JPLEAF_B1);
672
+ }
673
+ ExpCnt++;
674
+// Done?
675
+ if (End == cJU_LEAF2_MAXPOP1) break;
676
+
677
+// New Expanse, Start and Count
678
+ CIndex = PLeaf[End];
679
+ Start = End;
680
+ }
681
+ }
682
+
683
+// Now put all the Leaves below a BranchL or BranchB:
684
+ if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL
685
+ {
686
+ if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt,
687
+ Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
688
+
689
+ Pjp->jp_Type = cJU_JPBRANCH_L2;
690
+ }
691
+ else
692
+ {
693
+ if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm)
694
+ == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
695
+ }
696
+ return(1);
697
+
698
+} // j__udyCascade2()
699
+
700
+
701
+// ****************************************************************************
702
+// __ J U D Y C A S C A D E 3
703
+//
704
+// Return *Pjp as a (compressed) cJU_LEAF2, cJU_BRANCH_L3, cJU_BRANCH_B3.
705
+
706
+FUNCTION int j__udyCascade3(
707
+ Pjp_t Pjp,
708
+ Pvoid_t Pjpm)
709
+{
710
+ uint8_t * PLeaf; // pointer to leaf, explicit type.
711
+ Word_t End, Start; // temporaries.
712
+ Word_t ExpCnt; // count of expanses of splay.
713
+ Word_t CIndex; // current Index word.
714
+JUDYLCODE(Pjv_t Pjv;) // value area of leaf.
715
+
716
+// Temp staging for parts(Leaves) of newly splayed leaf
717
+ jp_t StageJP [cJU_LEAF3_MAXPOP1]; // JPs of new leaves
718
+ Word_t StageA [cJU_LEAF3_MAXPOP1];
719
+ uint8_t StageExp [cJU_LEAF3_MAXPOP1]; // Expanses of new leaves
720
+ uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse
721
+ jbb_t StageJBB; // staged bitmap branch
722
+
723
+ assert(JU_JPTYPE(Pjp) == cJU_JPLEAF3);
724
+ assert((JU_JPDCDPOP0(Pjp) & 0xFFFFFF) == (cJU_LEAF3_MAXPOP1-1));
725
+
726
+// Get the address of the Leaf
727
+ PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr);
728
+
729
+// Extract leaf to Word_t and insert-sort Index into it
730
+ j__udyCopy3toW(StageA, PLeaf, cJU_LEAF3_MAXPOP1);
731
+
732
+// Get the address of the Leaf and Value area
733
+ JUDYLCODE(Pjv = JL_LEAF3VALUEAREA(PLeaf, cJU_LEAF3_MAXPOP1);)
734
+
735
+// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index)
736
+
737
+ CIndex = StageA[0];
738
+ if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF3_MAXPOP1-1], 3))
739
+ {
740
+ Word_t DcdP0;
741
+ Pjll_t PjllRaw; // pointer to new leaf.
742
+ Pjll_t Pjll;
743
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
744
+
745
+// Alloc a 2 byte Index Leaf
746
+ PjllRaw = j__udyAllocJLL2(cJU_LEAF3_MAXPOP1, Pjpm);
747
+ if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory
748
+
749
+ Pjll = P_JLL(PjllRaw);
750
+
751
+// Copy just 2 bytes Indexes to new Leaf
752
+// j__udyCopyWto2((uint16_t *) Pjll, StageA, cJU_LEAF3_MAXPOP1);
753
+ JU_COPYMEM ((uint16_t *) Pjll, StageA, cJU_LEAF3_MAXPOP1);
754
+#ifdef JUDYL
755
+// Copy Value area into new Leaf
756
+ Pjvnew = JL_LEAF2VALUEAREA(Pjll, cJU_LEAF3_MAXPOP1);
757
+ JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF3_MAXPOP1);
758
+#endif
759
+ DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF3_MAXPOP1, 2);)
760
+
761
+// Form new JP, Pop0 field is unchanged
762
+// Add in another Dcd byte because compressing
763
+ DcdP0 = (CIndex & cJU_DCDMASK(2)) | JU_JPDCDPOP0(Pjp);
764
+
765
+ JU_JPSETADT(Pjp, (Word_t) PjllRaw, DcdP0, cJU_JPLEAF2);
766
+
767
+ return(1); // Success
768
+ }
769
+
770
+// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression
771
+
772
+ StageJBB = StageJBBZero; // zero staged bitmap branch
773
+ ZEROJP(SubJPCount);
774
+
775
+// Splay the 3 byte index Leaf to 2 byte Index Leaves
776
+ for (ExpCnt = Start = 0, End = 1; ; End++)
777
+ {
778
+// Check if new expanse or last one
779
+ if ( (End == cJU_LEAF3_MAXPOP1)
780
+ ||
781
+ (JU_DIGITATSTATE(CIndex ^ StageA[End], 3))
782
+ )
783
+ {
784
+// Build a leaf below the previous expanse
785
+
786
+ Pjp_t PjpJP = StageJP + ExpCnt;
787
+ Word_t Pop1 = End - Start;
788
+ Word_t expanse = JU_DIGITATSTATE(CIndex, 3);
789
+ Word_t subexp = expanse / cJU_BITSPERSUBEXPB;
790
+//
791
+// set the bit that is the current expanse
792
+ JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse);
793
+#ifdef SUBEXPCOUNTS
794
+ StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse
795
+#endif
796
+// count number of expanses in each subexpanse
797
+ SubJPCount[subexp]++;
798
+
799
+// Save byte expanse of leaf
800
+ StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 3);
801
+
802
+ if (Pop1 == 1) // cJU_JPIMMED_2_01
803
+ {
804
+ Word_t DcdP0;
805
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(2)) |
806
+ CIndex;
807
+#ifdef JUDY1
808
+ JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_2_01);
809
+#else // JUDYL
810
+ JU_JPSETADT(PjpJP, Pjv[Start], DcdP0,
811
+ cJL_JPIMMED_2_01);
812
+#endif // JUDYL
813
+ }
814
+#if (defined(JUDY1) || defined(JU_64BIT))
815
+ else if (Pop1 <= cJU_IMMED2_MAXPOP1)
816
+ {
817
+// cJ1_JPIMMED_2_02..3: Judy1 32
818
+// cJL_JPIMMED_2_02..3: JudyL 64
819
+// cJ1_JPIMMED_2_02..7: Judy1 64
820
+#ifdef JUDYL
821
+// Alloc is 1st in case of malloc fail
822
+ Pjv_t PjvnewRaw; // value area of new leaf.
823
+ Pjv_t Pjvnew;
824
+
825
+// Allocate Value area for Immediate Leaf
826
+ PjvnewRaw = j__udyLAllocJV(Pop1, Pjpm);
827
+ if (PjvnewRaw == (Pjv_t) NULL)
828
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
829
+
830
+ Pjvnew = P_JV(PjvnewRaw);
831
+
832
+// Copy to Values to Value Leaf
833
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
834
+
835
+ PjpJP->jp_Addr = (Word_t) PjvnewRaw;
836
+
837
+// Copy to Index to JP as an immediate Leaf
838
+ JU_COPYMEM((uint16_t *) (PjpJP->jp_LIndex),
839
+ StageA + Start, Pop1);
840
+#else // JUDY1
841
+ JU_COPYMEM((uint16_t *) (PjpJP->jp_1Index),
842
+ StageA + Start, Pop1);
843
+#endif // JUDY1
844
+// Set Type, Population and Index size
845
+ PjpJP->jp_Type = cJU_JPIMMED_2_02 + Pop1 - 2;
846
+ }
847
+#endif // (JUDY1 || JU_64BIT)
848
+
849
+ else // Make a linear leaf2
850
+ {
851
+// cJU_JPLEAF2
852
+ Word_t DcdP0;
853
+ Pjll_t PjllRaw; // pointer to new leaf.
854
+ Pjll_t Pjll;
855
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
856
+
857
+ PjllRaw = j__udyAllocJLL2(Pop1, Pjpm);
858
+ if (PjllRaw == (Pjll_t) NULL)
859
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
860
+
861
+ Pjll = P_JLL(PjllRaw);
862
+#ifdef JUDYL
863
+// Copy to Values to new Leaf
864
+ Pjvnew = JL_LEAF2VALUEAREA(Pjll, Pop1);
865
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
866
+#endif
867
+// Copy least 2 bytes per Index of Leaf to new Leaf
868
+ JU_COPYMEM((uint16_t *) Pjll, StageA+Start,
869
+ Pop1);
870
+
871
+ DBGCODE(JudyCheckSorted(Pjll, Pop1, 2);)
872
+
873
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(3))
874
+ |
875
+ (CIndex & cJU_DCDMASK(3-1))
876
+ |
877
+ (Pop1 - 1);
878
+
879
+ JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0,
880
+ cJU_JPLEAF2);
881
+ }
882
+ ExpCnt++;
883
+// Done?
884
+ if (End == cJU_LEAF3_MAXPOP1) break;
885
+
886
+// New Expanse, Start and Count
887
+ CIndex = StageA[End];
888
+ Start = End;
889
+ }
890
+ }
891
+
892
+// Now put all the Leaves below a BranchL or BranchB:
893
+ if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL
894
+ {
895
+ if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt,
896
+ Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
897
+
898
+ Pjp->jp_Type = cJU_JPBRANCH_L3;
899
+ }
900
+ else
901
+ {
902
+ if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm)
903
+ == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
904
+ }
905
+ return(1);
906
+
907
+} // j__udyCascade3()
908
+
909
+
910
+#ifdef JU_64BIT // JudyCascade[4567]
911
+
912
+// ****************************************************************************
913
+// __ J U D Y C A S C A D E 4
914
+//
915
+// Cascade from a cJU_JPLEAF4 to one of the following:
916
+// 1. if leaf is in 1 expanse:
917
+// compress it into a JPLEAF3
918
+// 2. if leaf contains multiple expanses:
919
+// create linear or bitmap branch containing
920
+// each new expanse is either a:
921
+// JPIMMED_3_01 branch
922
+// JPIMMED_3_02 branch
923
+// JPLEAF3
924
+
925
+FUNCTION int j__udyCascade4(
926
+ Pjp_t Pjp,
927
+ Pvoid_t Pjpm)
928
+{
929
+ uint32_t * PLeaf; // pointer to leaf, explicit type.
930
+ Word_t End, Start; // temporaries.
931
+ Word_t ExpCnt; // count of expanses of splay.
932
+ Word_t CIndex; // current Index word.
933
+JUDYLCODE(Pjv_t Pjv;) // value area of leaf.
934
+
935
+// Temp staging for parts(Leaves) of newly splayed leaf
936
+ jp_t StageJP [cJU_LEAF4_MAXPOP1]; // JPs of new leaves
937
+ Word_t StageA [cJU_LEAF4_MAXPOP1];
938
+ uint8_t StageExp [cJU_LEAF4_MAXPOP1]; // Expanses of new leaves
939
+ uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse
940
+ jbb_t StageJBB; // staged bitmap branch
941
+
942
+ assert(JU_JPTYPE(Pjp) == cJU_JPLEAF4);
943
+ assert((JU_JPDCDPOP0(Pjp) & 0xFFFFFFFF) == (cJU_LEAF4_MAXPOP1-1));
944
+
945
+// Get the address of the Leaf
946
+ PLeaf = (uint32_t *) P_JLL(Pjp->jp_Addr);
947
+
948
+// Extract 4 byte index Leaf to Word_t
949
+ j__udyCopy4toW(StageA, PLeaf, cJU_LEAF4_MAXPOP1);
950
+
951
+// Get the address of the Leaf and Value area
952
+ JUDYLCODE(Pjv = JL_LEAF4VALUEAREA(PLeaf, cJU_LEAF4_MAXPOP1);)
953
+
954
+// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index)
955
+
956
+ CIndex = StageA[0];
957
+ if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF4_MAXPOP1-1], 4))
958
+ {
959
+ Word_t DcdP0;
960
+ Pjll_t PjllRaw; // pointer to new leaf.
961
+ Pjll_t Pjll;
962
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new Leaf.
963
+
964
+// Alloc a 3 byte Index Leaf
965
+ PjllRaw = j__udyAllocJLL3(cJU_LEAF4_MAXPOP1, Pjpm);
966
+ if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory
967
+
968
+ Pjll = P_JLL(PjllRaw);
969
+
970
+// Copy Index area into new Leaf
971
+ j__udyCopyWto3((uint8_t *) Pjll, StageA, cJU_LEAF4_MAXPOP1);
972
+#ifdef JUDYL
973
+// Copy Value area into new Leaf
974
+ Pjvnew = JL_LEAF3VALUEAREA(Pjll, cJU_LEAF4_MAXPOP1);
975
+ JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF4_MAXPOP1);
976
+#endif
977
+ DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF4_MAXPOP1, 3);)
978
+
979
+ DcdP0 = JU_JPDCDPOP0(Pjp) | (CIndex & cJU_DCDMASK(3));
980
+ JU_JPSETADT(Pjp, (Word_t)PjllRaw, DcdP0, cJU_JPLEAF3);
981
+
982
+ return(1);
983
+ }
984
+
985
+// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression
986
+
987
+ StageJBB = StageJBBZero; // zero staged bitmap branch
988
+ ZEROJP(SubJPCount);
989
+
990
+// Splay the 4 byte index Leaf to 3 byte Index Leaves
991
+ for (ExpCnt = Start = 0, End = 1; ; End++)
992
+ {
993
+// Check if new expanse or last one
994
+ if ( (End == cJU_LEAF4_MAXPOP1)
995
+ ||
996
+ (JU_DIGITATSTATE(CIndex ^ StageA[End], 4))
997
+ )
998
+ {
999
+// Build a leaf below the previous expanse
1000
+
1001
+ Pjp_t PjpJP = StageJP + ExpCnt;
1002
+ Word_t Pop1 = End - Start;
1003
+ Word_t expanse = JU_DIGITATSTATE(CIndex, 4);
1004
+ Word_t subexp = expanse / cJU_BITSPERSUBEXPB;
1005
+//
1006
+// set the bit that is the current expanse
1007
+ JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse);
1008
+#ifdef SUBEXPCOUNTS
1009
+ StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse
1010
+#endif
1011
+// count number of expanses in each subexpanse
1012
+ SubJPCount[subexp]++;
1013
+
1014
+// Save byte expanse of leaf
1015
+ StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 4);
1016
+
1017
+ if (Pop1 == 1) // cJU_JPIMMED_3_01
1018
+ {
1019
+ Word_t DcdP0;
1020
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(3)) |
1021
+ CIndex;
1022
+#ifdef JUDY1
1023
+ JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_3_01);
1024
+#else // JUDYL
1025
+ JU_JPSETADT(PjpJP, Pjv[Start], DcdP0,
1026
+ cJL_JPIMMED_3_01);
1027
+#endif // JUDYL
1028
+ }
1029
+ else if (Pop1 <= cJU_IMMED3_MAXPOP1)
1030
+ {
1031
+// cJ1_JPIMMED_3_02 : Judy1 32
1032
+// cJL_JPIMMED_3_02 : JudyL 64
1033
+// cJ1_JPIMMED_3_02..5: Judy1 64
1034
+
1035
+#ifdef JUDYL
1036
+// Alloc is 1st in case of malloc fail
1037
+ Pjv_t PjvnewRaw; // value area of new leaf.
1038
+ Pjv_t Pjvnew;
1039
+
1040
+// Allocate Value area for Immediate Leaf
1041
+ PjvnewRaw = j__udyLAllocJV(Pop1, Pjpm);
1042
+ if (PjvnewRaw == (Pjv_t) NULL)
1043
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1044
+
1045
+ Pjvnew = P_JV(PjvnewRaw);
1046
+
1047
+// Copy to Values to Value Leaf
1048
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
1049
+ PjpJP->jp_Addr = (Word_t) PjvnewRaw;
1050
+
1051
+// Copy to Index to JP as an immediate Leaf
1052
+ j__udyCopyWto3(PjpJP->jp_LIndex,
1053
+ StageA + Start, Pop1);
1054
+#else
1055
+ j__udyCopyWto3(PjpJP->jp_1Index,
1056
+ StageA + Start, Pop1);
1057
+#endif
1058
+// Set type, population and Index size
1059
+ PjpJP->jp_Type = cJU_JPIMMED_3_02 + Pop1 - 2;
1060
+ }
1061
+ else
1062
+ {
1063
+// cJU_JPLEAF3
1064
+ Word_t DcdP0;
1065
+ Pjll_t PjllRaw; // pointer to new leaf.
1066
+ Pjll_t Pjll;
1067
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1068
+
1069
+ PjllRaw = j__udyAllocJLL3(Pop1, Pjpm);
1070
+ if (PjllRaw == (Pjll_t)NULL)
1071
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1072
+
1073
+ Pjll = P_JLL(PjllRaw);
1074
+
1075
+// Copy Indexes to new Leaf
1076
+ j__udyCopyWto3((uint8_t *) Pjll, StageA + Start,
1077
+ Pop1);
1078
+#ifdef JUDYL
1079
+// Copy to Values to new Leaf
1080
+ Pjvnew = JL_LEAF3VALUEAREA(Pjll, Pop1);
1081
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
1082
+#endif
1083
+ DBGCODE(JudyCheckSorted(Pjll, Pop1, 3);)
1084
+
1085
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(4))
1086
+ |
1087
+ (CIndex & cJU_DCDMASK(4-1))
1088
+ |
1089
+ (Pop1 - 1);
1090
+
1091
+ JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0,
1092
+ cJU_JPLEAF3);
1093
+ }
1094
+ ExpCnt++;
1095
+// Done?
1096
+ if (End == cJU_LEAF4_MAXPOP1) break;
1097
+
1098
+// New Expanse, Start and Count
1099
+ CIndex = StageA[End];
1100
+ Start = End;
1101
+ }
1102
+ }
1103
+
1104
+// Now put all the Leaves below a BranchL or BranchB:
1105
+ if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL
1106
+ {
1107
+ if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt,
1108
+ Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1109
+
1110
+ Pjp->jp_Type = cJU_JPBRANCH_L4;
1111
+ }
1112
+ else
1113
+ {
1114
+ if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm)
1115
+ == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1116
+ }
1117
+ return(1);
1118
+
1119
+} // j__udyCascade4()
1120
+
1121
+
1122
+// ****************************************************************************
1123
+// __ J U D Y C A S C A D E 5
1124
+//
1125
+// Cascade from a cJU_JPLEAF5 to one of the following:
1126
+// 1. if leaf is in 1 expanse:
1127
+// compress it into a JPLEAF4
1128
+// 2. if leaf contains multiple expanses:
1129
+// create linear or bitmap branch containing
1130
+// each new expanse is either a:
1131
+// JPIMMED_4_01 branch
1132
+// JPLEAF4
1133
+
1134
+FUNCTION int j__udyCascade5(
1135
+ Pjp_t Pjp,
1136
+ Pvoid_t Pjpm)
1137
+{
1138
+ uint8_t * PLeaf; // pointer to leaf, explicit type.
1139
+ Word_t End, Start; // temporaries.
1140
+ Word_t ExpCnt; // count of expanses of splay.
1141
+ Word_t CIndex; // current Index word.
1142
+JUDYLCODE(Pjv_t Pjv;) // value area of leaf.
1143
+
1144
+// Temp staging for parts(Leaves) of newly splayed leaf
1145
+ jp_t StageJP [cJU_LEAF5_MAXPOP1]; // JPs of new leaves
1146
+ Word_t StageA [cJU_LEAF5_MAXPOP1];
1147
+ uint8_t StageExp [cJU_LEAF5_MAXPOP1]; // Expanses of new leaves
1148
+ uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse
1149
+ jbb_t StageJBB; // staged bitmap branch
1150
+
1151
+ assert(JU_JPTYPE(Pjp) == cJU_JPLEAF5);
1152
+ assert((JU_JPDCDPOP0(Pjp) & 0xFFFFFFFFFF) == (cJU_LEAF5_MAXPOP1-1));
1153
+
1154
+// Get the address of the Leaf
1155
+ PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr);
1156
+
1157
+// Extract 5 byte index Leaf to Word_t
1158
+ j__udyCopy5toW(StageA, PLeaf, cJU_LEAF5_MAXPOP1);
1159
+
1160
+// Get the address of the Leaf and Value area
1161
+ JUDYLCODE(Pjv = JL_LEAF5VALUEAREA(PLeaf, cJU_LEAF5_MAXPOP1);)
1162
+
1163
+// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index)
1164
+
1165
+ CIndex = StageA[0];
1166
+ if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF5_MAXPOP1-1], 5))
1167
+ {
1168
+ Word_t DcdP0;
1169
+ Pjll_t PjllRaw; // pointer to new leaf.
1170
+ Pjll_t Pjll;
1171
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1172
+
1173
+// Alloc a 4 byte Index Leaf
1174
+ PjllRaw = j__udyAllocJLL4(cJU_LEAF5_MAXPOP1, Pjpm);
1175
+ if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory
1176
+
1177
+ Pjll = P_JLL(PjllRaw);
1178
+
1179
+// Copy Index area into new Leaf
1180
+ j__udyCopyWto4((uint8_t *) Pjll, StageA, cJU_LEAF5_MAXPOP1);
1181
+#ifdef JUDYL
1182
+// Copy Value area into new Leaf
1183
+ Pjvnew = JL_LEAF4VALUEAREA(Pjll, cJU_LEAF5_MAXPOP1);
1184
+ JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF5_MAXPOP1);
1185
+#endif
1186
+ DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF5_MAXPOP1, 4);)
1187
+
1188
+ DcdP0 = JU_JPDCDPOP0(Pjp) | (CIndex & cJU_DCDMASK(4));
1189
+ JU_JPSETADT(Pjp, (Word_t)PjllRaw, DcdP0, cJU_JPLEAF4);
1190
+
1191
+ return(1);
1192
+ }
1193
+
1194
+// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression
1195
+
1196
+ StageJBB = StageJBBZero; // zero staged bitmap branch
1197
+ ZEROJP(SubJPCount);
1198
+
1199
+// Splay the 5 byte index Leaf to 4 byte Index Leaves
1200
+ for (ExpCnt = Start = 0, End = 1; ; End++)
1201
+ {
1202
+// Check if new expanse or last one
1203
+ if ( (End == cJU_LEAF5_MAXPOP1)
1204
+ ||
1205
+ (JU_DIGITATSTATE(CIndex ^ StageA[End], 5))
1206
+ )
1207
+ {
1208
+// Build a leaf below the previous expanse
1209
+
1210
+ Pjp_t PjpJP = StageJP + ExpCnt;
1211
+ Word_t Pop1 = End - Start;
1212
+ Word_t expanse = JU_DIGITATSTATE(CIndex, 5);
1213
+ Word_t subexp = expanse / cJU_BITSPERSUBEXPB;
1214
+//
1215
+// set the bit that is the current expanse
1216
+ JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse);
1217
+#ifdef SUBEXPCOUNTS
1218
+ StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse
1219
+#endif
1220
+// count number of expanses in each subexpanse
1221
+ SubJPCount[subexp]++;
1222
+
1223
+// Save byte expanse of leaf
1224
+ StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 5);
1225
+
1226
+ if (Pop1 == 1) // cJU_JPIMMED_4_01
1227
+ {
1228
+ Word_t DcdP0;
1229
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(4)) |
1230
+ CIndex;
1231
+#ifdef JUDY1
1232
+ JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_4_01);
1233
+#else // JUDYL
1234
+ JU_JPSETADT(PjpJP, Pjv[Start], DcdP0,
1235
+ cJL_JPIMMED_4_01);
1236
+#endif // JUDYL
1237
+ }
1238
+#ifdef JUDY1
1239
+ else if (Pop1 <= cJ1_IMMED4_MAXPOP1)
1240
+ {
1241
+// cJ1_JPIMMED_4_02..3: Judy1 64
1242
+
1243
+// Copy to Index to JP as an immediate Leaf
1244
+ j__udyCopyWto4(PjpJP->jp_1Index,
1245
+ StageA + Start, Pop1);
1246
+
1247
+// Set pointer, type, population and Index size
1248
+ PjpJP->jp_Type = cJ1_JPIMMED_4_02 + Pop1 - 2;
1249
+ }
1250
+#endif
1251
+ else
1252
+ {
1253
+// cJU_JPLEAF4
1254
+ Word_t DcdP0;
1255
+ Pjll_t PjllRaw; // pointer to new leaf.
1256
+ Pjll_t Pjll;
1257
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1258
+
1259
+// Get a new Leaf
1260
+ PjllRaw = j__udyAllocJLL4(Pop1, Pjpm);
1261
+ if (PjllRaw == (Pjll_t)NULL)
1262
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1263
+
1264
+ Pjll = P_JLL(PjllRaw);
1265
+
1266
+// Copy Indexes to new Leaf
1267
+ j__udyCopyWto4((uint8_t *) Pjll, StageA + Start,
1268
+ Pop1);
1269
+#ifdef JUDYL
1270
+// Copy to Values to new Leaf
1271
+ Pjvnew = JL_LEAF4VALUEAREA(Pjll, Pop1);
1272
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
1273
+#endif
1274
+ DBGCODE(JudyCheckSorted(Pjll, Pop1, 4);)
1275
+
1276
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(5))
1277
+ |
1278
+ (CIndex & cJU_DCDMASK(5-1))
1279
+ |
1280
+ (Pop1 - 1);
1281
+
1282
+ JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0,
1283
+ cJU_JPLEAF4);
1284
+ }
1285
+ ExpCnt++;
1286
+// Done?
1287
+ if (End == cJU_LEAF5_MAXPOP1) break;
1288
+
1289
+// New Expanse, Start and Count
1290
+ CIndex = StageA[End];
1291
+ Start = End;
1292
+ }
1293
+ }
1294
+
1295
+// Now put all the Leaves below a BranchL or BranchB:
1296
+ if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL
1297
+ {
1298
+ if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt,
1299
+ Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1300
+
1301
+ Pjp->jp_Type = cJU_JPBRANCH_L5;
1302
+ }
1303
+ else
1304
+ {
1305
+ if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm)
1306
+ == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1307
+ }
1308
+ return(1);
1309
+
1310
+} // j__udyCascade5()
1311
+
1312
+
1313
+// ****************************************************************************
1314
+// __ J U D Y C A S C A D E 6
1315
+//
1316
+// Cascade from a cJU_JPLEAF6 to one of the following:
1317
+// 1. if leaf is in 1 expanse:
1318
+// compress it into a JPLEAF5
1319
+// 2. if leaf contains multiple expanses:
1320
+// create linear or bitmap branch containing
1321
+// each new expanse is either a:
1322
+// JPIMMED_5_01 ... JPIMMED_5_03 branch
1323
+// JPIMMED_5_01 branch
1324
+// JPLEAF5
1325
+
1326
+FUNCTION int j__udyCascade6(
1327
+ Pjp_t Pjp,
1328
+ Pvoid_t Pjpm)
1329
+{
1330
+ uint8_t * PLeaf; // pointer to leaf, explicit type.
1331
+ Word_t End, Start; // temporaries.
1332
+ Word_t ExpCnt; // count of expanses of splay.
1333
+ Word_t CIndex; // current Index word.
1334
+JUDYLCODE(Pjv_t Pjv;) // value area of leaf.
1335
+
1336
+// Temp staging for parts(Leaves) of newly splayed leaf
1337
+ jp_t StageJP [cJU_LEAF6_MAXPOP1]; // JPs of new leaves
1338
+ Word_t StageA [cJU_LEAF6_MAXPOP1];
1339
+ uint8_t StageExp [cJU_LEAF6_MAXPOP1]; // Expanses of new leaves
1340
+ uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse
1341
+ jbb_t StageJBB; // staged bitmap branch
1342
+
1343
+ assert(JU_JPTYPE(Pjp) == cJU_JPLEAF6);
1344
+ assert((JU_JPDCDPOP0(Pjp) & 0xFFFFFFFFFFFF) == (cJU_LEAF6_MAXPOP1-1));
1345
+
1346
+// Get the address of the Leaf
1347
+ PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr);
1348
+
1349
+// Extract 6 byte index Leaf to Word_t
1350
+ j__udyCopy6toW(StageA, PLeaf, cJU_LEAF6_MAXPOP1);
1351
+
1352
+// Get the address of the Leaf and Value area
1353
+ JUDYLCODE(Pjv = JL_LEAF6VALUEAREA(PLeaf, cJU_LEAF6_MAXPOP1);)
1354
+
1355
+// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index)
1356
+
1357
+ CIndex = StageA[0];
1358
+ if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF6_MAXPOP1-1], 6))
1359
+ {
1360
+ Word_t DcdP0;
1361
+ Pjll_t PjllRaw; // pointer to new leaf.
1362
+ Pjll_t Pjll;
1363
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1364
+
1365
+// Alloc a 5 byte Index Leaf
1366
+ PjllRaw = j__udyAllocJLL5(cJU_LEAF6_MAXPOP1, Pjpm);
1367
+ if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory
1368
+
1369
+ Pjll = P_JLL(PjllRaw);
1370
+
1371
+// Copy Index area into new Leaf
1372
+ j__udyCopyWto5((uint8_t *) Pjll, StageA, cJU_LEAF6_MAXPOP1);
1373
+#ifdef JUDYL
1374
+// Copy Value area into new Leaf
1375
+ Pjvnew = JL_LEAF5VALUEAREA(Pjll, cJU_LEAF6_MAXPOP1);
1376
+ JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF6_MAXPOP1);
1377
+#endif
1378
+ DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF6_MAXPOP1, 5);)
1379
+
1380
+ DcdP0 = JU_JPDCDPOP0(Pjp) | (CIndex & cJU_DCDMASK(5));
1381
+ JU_JPSETADT(Pjp, (Word_t)PjllRaw, DcdP0, cJU_JPLEAF5);
1382
+
1383
+ return(1);
1384
+ }
1385
+
1386
+// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression
1387
+
1388
+ StageJBB = StageJBBZero; // zero staged bitmap branch
1389
+ ZEROJP(SubJPCount);
1390
+
1391
+// Splay the 6 byte index Leaf to 5 byte Index Leaves
1392
+ for (ExpCnt = Start = 0, End = 1; ; End++)
1393
+ {
1394
+// Check if new expanse or last one
1395
+ if ( (End == cJU_LEAF6_MAXPOP1)
1396
+ ||
1397
+ (JU_DIGITATSTATE(CIndex ^ StageA[End], 6))
1398
+ )
1399
+ {
1400
+// Build a leaf below the previous expanse
1401
+
1402
+ Pjp_t PjpJP = StageJP + ExpCnt;
1403
+ Word_t Pop1 = End - Start;
1404
+ Word_t expanse = JU_DIGITATSTATE(CIndex, 6);
1405
+ Word_t subexp = expanse / cJU_BITSPERSUBEXPB;
1406
+//
1407
+// set the bit that is the current expanse
1408
+ JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse);
1409
+#ifdef SUBEXPCOUNTS
1410
+ StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse
1411
+#endif
1412
+// count number of expanses in each subexpanse
1413
+ SubJPCount[subexp]++;
1414
+
1415
+// Save byte expanse of leaf
1416
+ StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 6);
1417
+
1418
+ if (Pop1 == 1) // cJU_JPIMMED_5_01
1419
+ {
1420
+ Word_t DcdP0;
1421
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(5)) |
1422
+ CIndex;
1423
+#ifdef JUDY1
1424
+ JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_5_01);
1425
+#else // JUDYL
1426
+ JU_JPSETADT(PjpJP, Pjv[Start], DcdP0,
1427
+ cJL_JPIMMED_5_01);
1428
+#endif // JUDYL
1429
+ }
1430
+#ifdef JUDY1
1431
+ else if (Pop1 <= cJ1_IMMED5_MAXPOP1)
1432
+ {
1433
+// cJ1_JPIMMED_5_02..3: Judy1 64
1434
+
1435
+// Copy to Index to JP as an immediate Leaf
1436
+ j__udyCopyWto5(PjpJP->jp_1Index,
1437
+ StageA + Start, Pop1);
1438
+
1439
+// Set pointer, type, population and Index size
1440
+ PjpJP->jp_Type = cJ1_JPIMMED_5_02 + Pop1 - 2;
1441
+ }
1442
+#endif
1443
+ else
1444
+ {
1445
+// cJU_JPLEAF5
1446
+ Word_t DcdP0;
1447
+ Pjll_t PjllRaw; // pointer to new leaf.
1448
+ Pjll_t Pjll;
1449
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1450
+
1451
+// Get a new Leaf
1452
+ PjllRaw = j__udyAllocJLL5(Pop1, Pjpm);
1453
+ if (PjllRaw == (Pjll_t)NULL)
1454
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1455
+
1456
+ Pjll = P_JLL(PjllRaw);
1457
+
1458
+// Copy Indexes to new Leaf
1459
+ j__udyCopyWto5((uint8_t *) Pjll, StageA + Start,
1460
+ Pop1);
1461
+
1462
+// Copy to Values to new Leaf
1463
+#ifdef JUDYL
1464
+ Pjvnew = JL_LEAF5VALUEAREA(Pjll, Pop1);
1465
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
1466
+#endif
1467
+ DBGCODE(JudyCheckSorted(Pjll, Pop1, 5);)
1468
+
1469
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(6))
1470
+ |
1471
+ (CIndex & cJU_DCDMASK(6-1))
1472
+ |
1473
+ (Pop1 - 1);
1474
+
1475
+ JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0,
1476
+ cJU_JPLEAF5);
1477
+ }
1478
+ ExpCnt++;
1479
+// Done?
1480
+ if (End == cJU_LEAF6_MAXPOP1) break;
1481
+
1482
+// New Expanse, Start and Count
1483
+ CIndex = StageA[End];
1484
+ Start = End;
1485
+ }
1486
+ }
1487
+
1488
+// Now put all the Leaves below a BranchL or BranchB:
1489
+ if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL
1490
+ {
1491
+ if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt,
1492
+ Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1493
+
1494
+ Pjp->jp_Type = cJU_JPBRANCH_L6;
1495
+ }
1496
+ else
1497
+ {
1498
+ if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm)
1499
+ == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1500
+ }
1501
+ return(1);
1502
+
1503
+} // j__udyCascade6()
1504
+
1505
+
1506
+// ****************************************************************************
1507
+// __ J U D Y C A S C A D E 7
1508
+//
1509
+// Cascade from a cJU_JPLEAF7 to one of the following:
1510
+// 1. if leaf is in 1 expanse:
1511
+// compress it into a JPLEAF6
1512
+// 2. if leaf contains multiple expanses:
1513
+// create linear or bitmap branch containing
1514
+// each new expanse is either a:
1515
+// JPIMMED_6_01 ... JPIMMED_6_02 branch
1516
+// JPIMMED_6_01 branch
1517
+// JPLEAF6
1518
+
1519
+FUNCTION int j__udyCascade7(
1520
+ Pjp_t Pjp,
1521
+ Pvoid_t Pjpm)
1522
+{
1523
+ uint8_t * PLeaf; // pointer to leaf, explicit type.
1524
+ Word_t End, Start; // temporaries.
1525
+ Word_t ExpCnt; // count of expanses of splay.
1526
+ Word_t CIndex; // current Index word.
1527
+JUDYLCODE(Pjv_t Pjv;) // value area of leaf.
1528
+
1529
+// Temp staging for parts(Leaves) of newly splayed leaf
1530
+ jp_t StageJP [cJU_LEAF7_MAXPOP1]; // JPs of new leaves
1531
+ Word_t StageA [cJU_LEAF7_MAXPOP1];
1532
+ uint8_t StageExp [cJU_LEAF7_MAXPOP1]; // Expanses of new leaves
1533
+ uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse
1534
+ jbb_t StageJBB; // staged bitmap branch
1535
+
1536
+ assert(JU_JPTYPE(Pjp) == cJU_JPLEAF7);
1537
+ assert(JU_JPDCDPOP0(Pjp) == (cJU_LEAF7_MAXPOP1-1));
1538
+
1539
+// Get the address of the Leaf
1540
+ PLeaf = (uint8_t *) P_JLL(Pjp->jp_Addr);
1541
+
1542
+// Extract 7 byte index Leaf to Word_t
1543
+ j__udyCopy7toW(StageA, PLeaf, cJU_LEAF7_MAXPOP1);
1544
+
1545
+// Get the address of the Leaf and Value area
1546
+ JUDYLCODE(Pjv = JL_LEAF7VALUEAREA(PLeaf, cJU_LEAF7_MAXPOP1);)
1547
+
1548
+// If Leaf is in 1 expanse -- just compress it (compare 1st, last & Index)
1549
+
1550
+ CIndex = StageA[0];
1551
+ if (!JU_DIGITATSTATE(CIndex ^ StageA[cJU_LEAF7_MAXPOP1-1], 7))
1552
+ {
1553
+ Word_t DcdP0;
1554
+ Pjll_t PjllRaw; // pointer to new leaf.
1555
+ Pjll_t Pjll;
1556
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1557
+
1558
+// Alloc a 6 byte Index Leaf
1559
+ PjllRaw = j__udyAllocJLL6(cJU_LEAF7_MAXPOP1, Pjpm);
1560
+ if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory
1561
+
1562
+ Pjll = P_JLL(PjllRaw);
1563
+
1564
+// Copy Index area into new Leaf
1565
+ j__udyCopyWto6((uint8_t *) Pjll, StageA, cJU_LEAF7_MAXPOP1);
1566
+#ifdef JUDYL
1567
+// Copy Value area into new Leaf
1568
+ Pjvnew = JL_LEAF6VALUEAREA(Pjll, cJU_LEAF7_MAXPOP1);
1569
+ JU_COPYMEM(Pjvnew, Pjv, cJU_LEAF7_MAXPOP1);
1570
+#endif
1571
+ DBGCODE(JudyCheckSorted(Pjll, cJU_LEAF7_MAXPOP1, 6);)
1572
+
1573
+ DcdP0 = JU_JPDCDPOP0(Pjp) | (CIndex & cJU_DCDMASK(6));
1574
+ JU_JPSETADT(Pjp, (Word_t)PjllRaw, DcdP0, cJU_JPLEAF6);
1575
+
1576
+ return(1);
1577
+ }
1578
+
1579
+// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression
1580
+
1581
+ StageJBB = StageJBBZero; // zero staged bitmap branch
1582
+ ZEROJP(SubJPCount);
1583
+
1584
+// Splay the 7 byte index Leaf to 6 byte Index Leaves
1585
+ for (ExpCnt = Start = 0, End = 1; ; End++)
1586
+ {
1587
+// Check if new expanse or last one
1588
+ if ( (End == cJU_LEAF7_MAXPOP1)
1589
+ ||
1590
+ (JU_DIGITATSTATE(CIndex ^ StageA[End], 7))
1591
+ )
1592
+ {
1593
+// Build a leaf below the previous expanse
1594
+
1595
+ Pjp_t PjpJP = StageJP + ExpCnt;
1596
+ Word_t Pop1 = End - Start;
1597
+ Word_t expanse = JU_DIGITATSTATE(CIndex, 7);
1598
+ Word_t subexp = expanse / cJU_BITSPERSUBEXPB;
1599
+//
1600
+// set the bit that is the current expanse
1601
+ JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse);
1602
+#ifdef SUBEXPCOUNTS
1603
+ StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse
1604
+#endif
1605
+// count number of expanses in each subexpanse
1606
+ SubJPCount[subexp]++;
1607
+
1608
+// Save byte expanse of leaf
1609
+ StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex, 7);
1610
+
1611
+ if (Pop1 == 1) // cJU_JPIMMED_6_01
1612
+ {
1613
+ Word_t DcdP0;
1614
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(6)) |
1615
+ CIndex;
1616
+#ifdef JUDY1
1617
+ JU_JPSETADT(PjpJP, 0, DcdP0, cJ1_JPIMMED_6_01);
1618
+#else // JUDYL
1619
+ JU_JPSETADT(PjpJP, Pjv[Start], DcdP0,
1620
+ cJL_JPIMMED_6_01);
1621
+#endif // JUDYL
1622
+ }
1623
+#ifdef JUDY1
1624
+ else if (Pop1 == cJ1_IMMED6_MAXPOP1)
1625
+ {
1626
+// cJ1_JPIMMED_6_02: Judy1 64
1627
+
1628
+// Copy to Index to JP as an immediate Leaf
1629
+ j__udyCopyWto6(PjpJP->jp_1Index,
1630
+ StageA + Start, 2);
1631
+
1632
+// Set pointer, type, population and Index size
1633
+ PjpJP->jp_Type = cJ1_JPIMMED_6_02;
1634
+ }
1635
+#endif
1636
+ else
1637
+ {
1638
+// cJU_JPLEAF6
1639
+ Word_t DcdP0;
1640
+ Pjll_t PjllRaw; // pointer to new leaf.
1641
+ Pjll_t Pjll;
1642
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1643
+
1644
+// Get a new Leaf
1645
+ PjllRaw = j__udyAllocJLL6(Pop1, Pjpm);
1646
+ if (PjllRaw == (Pjll_t)NULL)
1647
+ FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1648
+ Pjll = P_JLL(PjllRaw);
1649
+
1650
+// Copy Indexes to new Leaf
1651
+ j__udyCopyWto6((uint8_t *) Pjll, StageA + Start,
1652
+ Pop1);
1653
+#ifdef JUDYL
1654
+// Copy to Values to new Leaf
1655
+ Pjvnew = JL_LEAF6VALUEAREA(Pjll, Pop1);
1656
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
1657
+#endif
1658
+ DBGCODE(JudyCheckSorted(Pjll, Pop1, 6);)
1659
+
1660
+ DcdP0 = (JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(7))
1661
+ |
1662
+ (CIndex & cJU_DCDMASK(7-1))
1663
+ |
1664
+ (Pop1 - 1);
1665
+
1666
+ JU_JPSETADT(PjpJP, (Word_t)PjllRaw, DcdP0,
1667
+ cJU_JPLEAF6);
1668
+ }
1669
+ ExpCnt++;
1670
+// Done?
1671
+ if (End == cJU_LEAF7_MAXPOP1) break;
1672
+
1673
+// New Expanse, Start and Count
1674
+ CIndex = StageA[End];
1675
+ Start = End;
1676
+ }
1677
+ }
1678
+
1679
+// Now put all the Leaves below a BranchL or BranchB:
1680
+ if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL
1681
+ {
1682
+ if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt,
1683
+ Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1684
+
1685
+ Pjp->jp_Type = cJU_JPBRANCH_L7;
1686
+ }
1687
+ else
1688
+ {
1689
+ if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm)
1690
+ == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1691
+ }
1692
+ return(1);
1693
+
1694
+} // j__udyCascade7()
1695
+
1696
+#endif // JU_64BIT
1697
+
1698
+
1699
+// ****************************************************************************
1700
+// __ J U D Y C A S C A D E L
1701
+//
1702
+// (Compressed) cJU_LEAF3[7], cJ1_JPBRANCH_L.
1703
+//
1704
+// Cascade from a LEAFW (under Pjp) to one of the following:
1705
+// 1. if LEAFW is in 1 expanse:
1706
+// create linear branch with a JPLEAF3[7] under it
1707
+// 2. LEAFW contains multiple expanses:
1708
+// create linear or bitmap branch containing new expanses
1709
+// each new expanse is either a: 32 64
1710
+// JPIMMED_3_01 branch Y N
1711
+// JPIMMED_7_01 branch N Y
1712
+// JPLEAF3 Y N
1713
+// JPLEAF7 N Y
1714
+
1715
+FUNCTION int j__udyCascadeL(
1716
+ Pjp_t Pjp,
1717
+ Pvoid_t Pjpm)
1718
+{
1719
+ Pjlw_t Pjlw; // leaf to work on.
1720
+ Word_t End, Start; // temporaries.
1721
+ Word_t ExpCnt; // count of expanses of splay.
1722
+ Word_t CIndex; // current Index word.
1723
+JUDYLCODE(Pjv_t Pjv;) // value area of leaf.
1724
+
1725
+// Temp staging for parts(Leaves) of newly splayed leaf
1726
+ jp_t StageJP [cJU_LEAFW_MAXPOP1];
1727
+ uint8_t StageExp[cJU_LEAFW_MAXPOP1];
1728
+ uint8_t SubJPCount[cJU_NUMSUBEXPB]; // JPs in each subexpanse
1729
+ jbb_t StageJBB; // staged bitmap branch
1730
+
1731
+// Get the address of the Leaf
1732
+ Pjlw = P_JLW(Pjp->jp_Addr);
1733
+
1734
+ assert(Pjlw[0] == (cJU_LEAFW_MAXPOP1 - 1));
1735
+
1736
+// Get pointer to Value area of old Leaf
1737
+ JUDYLCODE(Pjv = JL_LEAFWVALUEAREA(Pjlw, cJU_LEAFW_MAXPOP1);)
1738
+
1739
+ Pjlw++; // Now point to Index area
1740
+
1741
+// If Leaf is in 1 expanse -- first compress it (compare 1st, last & Index):
1742
+
1743
+ CIndex = Pjlw[0]; // also used far below
1744
+ if (!JU_DIGITATSTATE(CIndex ^ Pjlw[cJU_LEAFW_MAXPOP1 - 1],
1745
+ cJU_ROOTSTATE))
1746
+ {
1747
+ Pjll_t PjllRaw; // pointer to new leaf.
1748
+ Pjll_t Pjll;
1749
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1750
+
1751
+// Get the common expanse to all elements in Leaf
1752
+ StageExp[0] = JU_DIGITATSTATE(CIndex, cJU_ROOTSTATE);
1753
+
1754
+// Alloc a 3[7] byte Index Leaf
1755
+#ifdef JU_64BIT
1756
+ PjllRaw = j__udyAllocJLL7(cJU_LEAFW_MAXPOP1, Pjpm);
1757
+ if (PjllRaw == (Pjlb_t)NULL) return(-1); // out of memory
1758
+
1759
+ Pjll = P_JLL(PjllRaw);
1760
+
1761
+// Copy LEAFW to a cJU_JPLEAF7
1762
+ j__udyCopyWto7((uint8_t *) Pjll, Pjlw, cJU_LEAFW_MAXPOP1);
1763
+#ifdef JUDYL
1764
+// Get the Value area of new Leaf
1765
+ Pjvnew = JL_LEAF7VALUEAREA(Pjll, cJU_LEAFW_MAXPOP1);
1766
+ JU_COPYMEM(Pjvnew, Pjv, cJU_LEAFW_MAXPOP1);
1767
+#endif
1768
+ DBGCODE(JudyCheckSorted(Pjll, cJU_LEAFW_MAXPOP1, 7);)
1769
+#else // 32 Bit
1770
+ PjllRaw = j__udyAllocJLL3(cJU_LEAFW_MAXPOP1, Pjpm);
1771
+ if (PjllRaw == (Pjll_t) NULL) return(-1);
1772
+
1773
+ Pjll = P_JLL(PjllRaw);
1774
+
1775
+// Copy LEAFW to a cJU_JPLEAF3
1776
+ j__udyCopyWto3((uint8_t *) Pjll, Pjlw, cJU_LEAFW_MAXPOP1);
1777
+#ifdef JUDYL
1778
+// Get the Value area of new Leaf
1779
+ Pjvnew = JL_LEAF3VALUEAREA(Pjll, cJU_LEAFW_MAXPOP1);
1780
+ JU_COPYMEM(Pjvnew, Pjv, cJU_LEAFW_MAXPOP1);
1781
+#endif
1782
+ DBGCODE(JudyCheckSorted(Pjll, cJU_LEAFW_MAXPOP1, 3);)
1783
+#endif // 32 Bit
1784
+
1785
+// Following not needed because cJU_DCDMASK(3[7]) is == 0
1786
+////// StageJP[0].jp_DcdPopO |= (CIndex & cJU_DCDMASK(3[7]));
1787
+#ifdef JU_64BIT
1788
+ JU_JPSETADT(&(StageJP[0]), (Word_t)PjllRaw, cJU_LEAFW_MAXPOP1-1,
1789
+ cJU_JPLEAF7);
1790
+#else // 32BIT
1791
+ JU_JPSETADT(&(StageJP[0]), (Word_t)PjllRaw, cJU_LEAFW_MAXPOP1-1,
1792
+ cJU_JPLEAF3);
1793
+#endif // 32BIT
1794
+// Create a 1 element Linear branch
1795
+ if (j__udyCreateBranchL(Pjp, StageJP, StageExp, 1, Pjpm) == -1)
1796
+ return(-1);
1797
+
1798
+// Change the type of callers JP
1799
+ Pjp->jp_Type = cJU_JPBRANCH_L;
1800
+
1801
+ return(1);
1802
+ }
1803
+
1804
+// Else in 2+ expanses, splay Leaf into smaller leaves at higher compression
1805
+
1806
+ StageJBB = StageJBBZero; // zero staged bitmap branch
1807
+ ZEROJP(SubJPCount);
1808
+
1809
+// Splay the 4[8] byte Index Leaf to 3[7] byte Index Leaves
1810
+ for (ExpCnt = Start = 0, End = 1; ; End++)
1811
+ {
1812
+// Check if new expanse or last one
1813
+ if ( (End == cJU_LEAFW_MAXPOP1)
1814
+ ||
1815
+ (JU_DIGITATSTATE(CIndex ^ Pjlw[End], cJU_ROOTSTATE))
1816
+ )
1817
+ {
1818
+// Build a leaf below the previous expanse
1819
+
1820
+ Pjp_t PjpJP = StageJP + ExpCnt;
1821
+ Word_t Pop1 = End - Start;
1822
+ Word_t expanse = JU_DIGITATSTATE(CIndex, cJU_ROOTSTATE);
1823
+ Word_t subexp = expanse / cJU_BITSPERSUBEXPB;
1824
+//
1825
+// set the bit that is the current expanse
1826
+ JU_JBB_BITMAP(&StageJBB, subexp) |= JU_BITPOSMASKB(expanse);
1827
+#ifdef SUBEXPCOUNTS
1828
+ StageJBB.jbb_subPop1[subexp] += Pop1; // pop of subexpanse
1829
+#endif
1830
+// count number of expanses in each subexpanse
1831
+ SubJPCount[subexp]++;
1832
+
1833
+// Save byte expanse of leaf
1834
+ StageExp[ExpCnt] = JU_DIGITATSTATE(CIndex,
1835
+ cJU_ROOTSTATE);
1836
+
1837
+ if (Pop1 == 1) // cJU_JPIMMED_3[7]_01
1838
+ {
1839
+#ifdef JU_64BIT
1840
+#ifdef JUDY1
1841
+ JU_JPSETADT(PjpJP, 0, CIndex, cJ1_JPIMMED_7_01);
1842
+#else // JUDYL
1843
+ JU_JPSETADT(PjpJP, Pjv[Start], CIndex,
1844
+ cJL_JPIMMED_7_01);
1845
+#endif // JUDYL
1846
+
1847
+#else // JU_32BIT
1848
+#ifdef JUDY1
1849
+ JU_JPSETADT(PjpJP, 0, CIndex, cJ1_JPIMMED_3_01);
1850
+#else // JUDYL
1851
+ JU_JPSETADT(PjpJP, Pjv[Start], CIndex,
1852
+ cJL_JPIMMED_3_01);
1853
+#endif // JUDYL
1854
+#endif // JU_32BIT
1855
+ }
1856
+#ifdef JUDY1
1857
+#ifdef JU_64BIT
1858
+ else if (Pop1 <= cJ1_IMMED7_MAXPOP1)
1859
+#else
1860
+ else if (Pop1 <= cJ1_IMMED3_MAXPOP1)
1861
+#endif
1862
+ {
1863
+// cJ1_JPIMMED_3_02 : Judy1 32
1864
+// cJ1_JPIMMED_7_02 : Judy1 64
1865
+// Copy to JP as an immediate Leaf
1866
+#ifdef JU_64BIT
1867
+ j__udyCopyWto7(PjpJP->jp_1Index, Pjlw+Start, 2);
1868
+ PjpJP->jp_Type = cJ1_JPIMMED_7_02;
1869
+#else
1870
+ j__udyCopyWto3(PjpJP->jp_1Index, Pjlw+Start, 2);
1871
+ PjpJP->jp_Type = cJ1_JPIMMED_3_02;
1872
+#endif // 32 Bit
1873
+ }
1874
+#endif // JUDY1
1875
+ else // Linear Leaf JPLEAF3[7]
1876
+ {
1877
+// cJU_JPLEAF3[7]
1878
+ Pjll_t PjllRaw; // pointer to new leaf.
1879
+ Pjll_t Pjll;
1880
+ JUDYLCODE(Pjv_t Pjvnew;) // value area of new leaf.
1881
+#ifdef JU_64BIT
1882
+ PjllRaw = j__udyAllocJLL7(Pop1, Pjpm);
1883
+ if (PjllRaw == (Pjll_t) NULL) return(-1);
1884
+ Pjll = P_JLL(PjllRaw);
1885
+
1886
+ j__udyCopyWto7((uint8_t *) Pjll, Pjlw + Start,
1887
+ Pop1);
1888
+#ifdef JUDYL
1889
+ Pjvnew = JL_LEAF7VALUEAREA(Pjll, Pop1);
1890
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
1891
+#endif // JUDYL
1892
+ DBGCODE(JudyCheckSorted(Pjll, Pop1, 7);)
1893
+#else // JU_64BIT - 32 Bit
1894
+ PjllRaw = j__udyAllocJLL3(Pop1, Pjpm);
1895
+ if (PjllRaw == (Pjll_t) NULL) return(-1);
1896
+ Pjll = P_JLL(PjllRaw);
1897
+
1898
+ j__udyCopyWto3((uint8_t *) Pjll, Pjlw + Start,
1899
+ Pop1);
1900
+#ifdef JUDYL
1901
+ Pjvnew = JL_LEAF3VALUEAREA(Pjll, Pop1);
1902
+ JU_COPYMEM(Pjvnew, Pjv + Start, Pop1);
1903
+#endif // JUDYL
1904
+ DBGCODE(JudyCheckSorted(Pjll, Pop1, 3);)
1905
+#endif // 32 Bit
1906
+
1907
+#ifdef JU_64BIT
1908
+ JU_JPSETADT(PjpJP, (Word_t)PjllRaw, Pop1 - 1,
1909
+ cJU_JPLEAF7);
1910
+#else // JU_64BIT - 32 Bit
1911
+ JU_JPSETADT(PjpJP, (Word_t)PjllRaw, Pop1 - 1,
1912
+ cJU_JPLEAF3);
1913
+#endif // 32 Bit
1914
+ }
1915
+ ExpCnt++;
1916
+// Done?
1917
+ if (End == cJU_LEAFW_MAXPOP1) break;
1918
+
1919
+// New Expanse, Start and Count
1920
+ CIndex = Pjlw[End];
1921
+ Start = End;
1922
+ }
1923
+ }
1924
+
1925
+// Now put all the Leaves below a BranchL or BranchB:
1926
+ if (ExpCnt <= cJU_BRANCHLMAXJPS) // put the Leaves below a BranchL
1927
+ {
1928
+ if (j__udyCreateBranchL(Pjp, StageJP, StageExp, ExpCnt,
1929
+ Pjpm) == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1930
+
1931
+ Pjp->jp_Type = cJU_JPBRANCH_L;
1932
+ }
1933
+ else
1934
+ {
1935
+ if (j__udyStageJBBtoJBB(Pjp, &StageJBB, StageJP, SubJPCount, Pjpm)
1936
+ == -1) FREEALLEXIT(ExpCnt, StageJP, Pjpm);
1937
+
1938
+ Pjp->jp_Type = cJU_JPBRANCH_B; // cJU_LEAFW is out of sequence
1939
+ }
1940
+ return(1);
1941
+
1942
+} // j__udyCascadeL()
libnetdata/libjudy/src/JudyL/JudyLCount.c
new
+1195
@@ -0,0 +1,1195 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.78 $ $Source: /judy/src/JudyCommon/JudyCount.c $
19
+//
20
+// Judy*Count() function for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a
24
+// version with cache line optimizations deleted, for testing.
25
+//
26
+// Compile with -DSMARTMETRICS to obtain global variables containing smart
27
+// cache line metrics. Note: Dont turn this on simultaneously for this file
28
+// and JudyByCount.c because they export the same globals.
29
+//
30
+// Judy*Count() returns the "count of Indexes" (inclusive) between the two
31
+// specified limits (Indexes). This code is remarkably fast. It traverses the
32
+// "Judy array" data structure.
33
+//
34
+// This count code is the GENERIC untuned version (minimum code size). It
35
+// might be possible to tuned to a specific architecture to be faster.
36
+// However, in real applications, with a modern machine, it is expected that
37
+// the instruction times will be swamped by cache line fills.
38
+// ****************************************************************************
39
+
40
+#if (! (defined(JUDY1) || defined(JUDYL)))
41
+#error: One of -DJUDY1 or -DJUDYL must be specified.
42
+#endif
43
+
44
+#ifdef JUDY1
45
+#include "Judy1.h"
46
+#else
47
+#include "JudyL.h"
48
+#endif
49
+
50
+#include "JudyPrivate1L.h"
51
+
52
+
53
+// define a phoney that is for sure
54
+
55
+#define cJU_LEAFW cJU_JPIMMED_CAP
56
+
57
+// Avoid duplicate symbols since this file is multi-compiled:
58
+
59
+#ifdef SMARTMETRICS
60
+#ifdef JUDY1
61
+Word_t jbb_upward = 0; // counts of directions taken:
62
+Word_t jbb_downward = 0;
63
+Word_t jbu_upward = 0;
64
+Word_t jbu_downward = 0;
65
+Word_t jlb_upward = 0;
66
+Word_t jlb_downward = 0;
67
+#else
68
+extern Word_t jbb_upward;
69
+extern Word_t jbb_downward;
70
+extern Word_t jbu_upward;
71
+extern Word_t jbu_downward;
72
+extern Word_t jlb_upward;
73
+extern Word_t jlb_downward;
74
+#endif
75
+#endif
76
+
77
+
78
+// FORWARD DECLARATIONS (prototypes):
79
+
80
+static Word_t j__udy1LCountSM(const Pjp_t Pjp, const Word_t Index,
81
+ const Pjpm_t Pjpm);
82
+
83
+// Each of Judy1 and JudyL get their own private (static) version of this
84
+// function:
85
+
86
+static int j__udyCountLeafB1(const Pjll_t Pjll, const Word_t Pop1,
87
+ const Word_t Index);
88
+
89
+// These functions are not static because they are exported to Judy*ByCount():
90
+//
91
+// TBD: Should be made static for performance reasons? And thus duplicated?
92
+//
93
+// Note: There really are two different functions, but for convenience they
94
+// are referred to here with a generic name.
95
+
96
+#ifdef JUDY1
97
+#define j__udyJPPop1 j__udy1JPPop1
98
+#else
99
+#define j__udyJPPop1 j__udyLJPPop1
100
+#endif
101
+
102
+Word_t j__udyJPPop1(const Pjp_t Pjp);
103
+
104
+
105
+// LOCAL ERROR HANDLING:
106
+//
107
+// The Judy*Count() functions are unusual because they return 0 instead of JERR
108
+// for an error. In this source file, define C_JERR for clarity.
109
+
110
+#define C_JERR 0
111
+
112
+
113
+// ****************************************************************************
114
+// J U D Y 1 C O U N T
115
+// J U D Y L C O U N T
116
+//
117
+// See the manual entry for details.
118
+//
119
+// This code is written recursively, at least at first, because thats much
120
+// simpler; hope its fast enough.
121
+
122
+#ifdef JUDY1
123
+FUNCTION Word_t Judy1Count
124
+#else
125
+FUNCTION Word_t JudyLCount
126
+#endif
127
+ (
128
+ Pcvoid_t PArray, // JRP to first branch/leaf in SM.
129
+ Word_t Index1, // starting Index.
130
+ Word_t Index2, // ending Index.
131
+ PJError_t PJError // optional, for returning error info.
132
+ )
133
+{
134
+ jpm_t fakejpm; // local temporary for small arrays.
135
+ Pjpm_t Pjpm; // top JPM or local temporary for error info.
136
+ jp_t fakejp; // constructed for calling j__udy1LCountSM().
137
+ Pjp_t Pjp; // JP to pass to j__udy1LCountSM().
138
+ Word_t pop1; // total for the array.
139
+ Word_t pop1above1; // indexes at or above Index1, inclusive.
140
+ Word_t pop1above2; // indexes at or above Index2, exclusive.
141
+ int retcode; // from Judy*First() calls.
142
+JUDYLCODE(PPvoid_t PPvalue); // from JudyLFirst() calls.
143
+
144
+
145
+// CHECK FOR SHORTCUTS:
146
+//
147
+// As documented, return C_JERR if the Judy array is empty or Index1 > Index2.
148
+
149
+ if ((PArray == (Pvoid_t) NULL) || (Index1 > Index2))
150
+ {
151
+ JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
152
+ return(C_JERR);
153
+ }
154
+
155
+// If Index1 == Index2, simply check if the specified Index is set; pass
156
+// through the return value from Judy1Test() or JudyLGet() with appropriate
157
+// translations.
158
+
159
+ if (Index1 == Index2)
160
+ {
161
+#ifdef JUDY1
162
+ retcode = Judy1Test(PArray, Index1, PJError);
163
+
164
+ if (retcode == JERRI) return(C_JERR); // pass through error.
165
+
166
+ if (retcode == 0)
167
+ {
168
+ JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
169
+ return(C_JERR);
170
+ }
171
+#else
172
+ PPvalue = JudyLGet(PArray, Index1, PJError);
173
+
174
+ if (PPvalue == PPJERR) return(C_JERR); // pass through error.
175
+
176
+ if (PPvalue == (PPvoid_t) NULL) // Index is not set.
177
+ {
178
+ JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
179
+ return(C_JERR);
180
+ }
181
+#endif
182
+ return(1); // single index is set.
183
+ }
184
+
185
+
186
+// CHECK JRP TYPE:
187
+//
188
+// Use an if/then for speed rather than a switch, and put the most common cases
189
+// first.
190
+//
191
+// Note: Since even cJU_LEAFW types require counting between two Indexes,
192
+// prepare them here for common code below that calls j__udy1LCountSM(), rather
193
+// than handling them even more specially here.
194
+
195
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
196
+ {
197
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
198
+ Pjpm = & fakejpm;
199
+ Pjp = & fakejp;
200
+ Pjp->jp_Addr = (Word_t) Pjlw;
201
+ Pjp->jp_Type = cJU_LEAFW;
202
+ Pjpm->jpm_Pop0 = Pjlw[0]; // from first word of leaf.
203
+ pop1 = Pjpm->jpm_Pop0 + 1;
204
+ }
205
+ else
206
+ {
207
+ Pjpm = P_JPM(PArray);
208
+ Pjp = &(Pjpm->jpm_JP);
209
+ pop1 = (Pjpm->jpm_Pop0) + 1; // note: can roll over to 0.
210
+
211
+#if (defined(JUDY1) && (! defined(JU_64BIT)))
212
+ if (pop1 == 0) // rare special case of full array:
213
+ {
214
+ Word_t count = Index2 - Index1 + 1; // can roll over again.
215
+
216
+ if (count == 0)
217
+ {
218
+ JU_SET_ERRNO(PJError, JU_ERRNO_FULL);
219
+ return(C_JERR);
220
+ }
221
+ return(count);
222
+ }
223
+#else
224
+ assert(pop1); // JudyL or 64-bit cannot create a full array!
225
+#endif
226
+ }
227
+
228
+
229
+// COUNT POP1 ABOVE INDEX1, INCLUSIVE:
230
+
231
+ assert(pop1); // just to be safe.
232
+
233
+ if (Index1 == 0) // shortcut, pop1above1 is entire population:
234
+ {
235
+ pop1above1 = pop1;
236
+ }
237
+ else // find first valid Index above Index1, if any:
238
+ {
239
+#ifdef JUDY1
240
+ if ((retcode = Judy1First(PArray, & Index1, PJError)) == JERRI)
241
+ return(C_JERR); // pass through error.
242
+#else
243
+ if ((PPvalue = JudyLFirst(PArray, & Index1, PJError)) == PPJERR)
244
+ return(C_JERR); // pass through error.
245
+
246
+ retcode = (PPvalue != (PPvoid_t) NULL); // found a next Index.
247
+#endif
248
+
249
+// If theres no Index at or above Index1, just return C_JERR (early exit):
250
+
251
+ if (retcode == 0)
252
+ {
253
+ JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
254
+ return(C_JERR);
255
+ }
256
+
257
+// If a first/next Index was found, call the counting motor starting with that
258
+// known valid Index, meaning the return should be positive, not C_JERR except
259
+// in case of a real error:
260
+
261
+ if ((pop1above1 = j__udy1LCountSM(Pjp, Index1, Pjpm)) == C_JERR)
262
+ {
263
+ JU_COPY_ERRNO(PJError, Pjpm); // pass through error.
264
+ return(C_JERR);
265
+ }
266
+ }
267
+
268
+
269
+// COUNT POP1 ABOVE INDEX2, EXCLUSIVE, AND RETURN THE DIFFERENCE:
270
+//
271
+// In principle, calculate the ordinal of each Index and take the difference,
272
+// with caution about off-by-one errors due to the specified Indexes being set
273
+// or unset. In practice:
274
+//
275
+// - The ordinals computed here are inverse ordinals, that is, the populations
276
+// ABOVE the specified Indexes (Index1 inclusive, Index2 exclusive), so
277
+// subtract pop1above2 from pop1above1, rather than vice-versa.
278
+//
279
+// - Index1s result already includes a count for Index1 and/or Index2 if
280
+// either is set, so calculate pop1above2 exclusive of Index2.
281
+//
282
+// TBD: If Index1 and Index2 fall in the same expanse in the top-state
283
+// branch(es), would it be faster to walk the SM only once, to their divergence
284
+// point, before calling j__udy1LCountSM() or equivalent? Possibly a non-issue
285
+// if a top-state pop1 becomes stored with each Judy1 array. Also, consider
286
+// whether the first call of j__udy1LCountSM() fills the cache, for common tree
287
+// branches, for the second call.
288
+//
289
+// As for pop1above1, look for shortcuts for special cases when pop1above2 is
290
+// zero. Otherwise call the counting "motor".
291
+
292
+ assert(pop1above1); // just to be safe.
293
+
294
+ if (Index2++ == cJU_ALLONES) return(pop1above1); // Index2 at limit.
295
+
296
+#ifdef JUDY1
297
+ if ((retcode = Judy1First(PArray, & Index2, PJError)) == JERRI)
298
+ return(C_JERR);
299
+#else
300
+ if ((PPvalue = JudyLFirst(PArray, & Index2, PJError)) == PPJERR)
301
+ return(C_JERR);
302
+
303
+ retcode = (PPvalue != (PPvoid_t) NULL); // found a next Index.
304
+#endif
305
+ if (retcode == 0) return(pop1above1); // no Index above Index2.
306
+
307
+// Just as for Index1, j__udy1LCountSM() cannot return 0 (locally == C_JERR)
308
+// except in case of a real error:
309
+
310
+ if ((pop1above2 = j__udy1LCountSM(Pjp, Index2, Pjpm)) == C_JERR)
311
+ {
312
+ JU_COPY_ERRNO(PJError, Pjpm); // pass through error.
313
+ return(C_JERR);
314
+ }
315
+
316
+ if (pop1above1 == pop1above2)
317
+ {
318
+ JU_SET_ERRNO(PJError, JU_ERRNO_NONE);
319
+ return(C_JERR);
320
+ }
321
+
322
+ return(pop1above1 - pop1above2);
323
+
324
+} // Judy1Count() / JudyLCount()
325
+
326
+
327
+// ****************************************************************************
328
+// __ J U D Y 1 L C O U N T S M
329
+//
330
+// Given a pointer to a JP (with invalid jp_DcdPopO at cJU_ROOTSTATE), a known
331
+// valid Index, and a Pjpm for returning error info, recursively visit a Judy
332
+// array state machine (SM) and return the count of Indexes, including Index,
333
+// through the end of the Judy array at this state or below. In case of error
334
+// or a count of 0 (should never happen), return C_JERR with appropriate
335
+// JU_ERRNO in the Pjpm.
336
+//
337
+// Note: This function is not told the current state because its encoded in
338
+// the JP Type.
339
+//
340
+// Method: To minimize cache line fills, while studying each branch, if Index
341
+// resides above the midpoint of the branch (which often consists of multiple
342
+// cache lines), ADD the populations at or above Index; otherwise, SUBTRACT
343
+// from the population of the WHOLE branch (available from the JP) the
344
+// populations at or above Index. This is especially tricky for bitmap
345
+// branches.
346
+//
347
+// Note: Unlike, say, the Ins and Del walk routines, this function returns the
348
+// same type of returns as Judy*Count(), so it can use *_SET_ERRNO*() macros
349
+// the same way.
350
+
351
+FUNCTION static Word_t j__udy1LCountSM(
352
+const Pjp_t Pjp, // top of Judy (sub)SM.
353
+const Word_t Index, // count at or above this Index.
354
+const Pjpm_t Pjpm) // for returning error info.
355
+{
356
+ Pjbl_t Pjbl; // Pjp->jp_Addr masked and cast to types:
357
+ Pjbb_t Pjbb;
358
+ Pjbu_t Pjbu;
359
+ Pjll_t Pjll; // a Judy lower-level linear leaf.
360
+
361
+ Word_t digit; // next digit to decode from Index.
362
+ long jpnum; // JP number in a branch (base 0).
363
+ int offset; // index ordinal within a leaf, base 0.
364
+ Word_t pop1; // total population of an expanse.
365
+ Word_t pop1above; // to return.
366
+
367
+// Common code to check Decode bits in a JP against the equivalent portion of
368
+// Index; XOR together, then mask bits of interest; must be all 0:
369
+//
370
+// Note: Why does this code only assert() compliance rather than actively
371
+// checking for outliers? Its because Index is supposed to be valid, hence
372
+// always match any Dcd bits traversed.
373
+//
374
+// Note: This assertion turns out to be always true for cState = 3 on 32-bit
375
+// and 7 on 64-bit, but its harmless, probably removed by the compiler.
376
+
377
+#define CHECKDCD(Pjp,cState) \
378
+ assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cState))
379
+
380
+// Common code to prepare to handle a root-level or lower-level branch:
381
+// Extract a state-dependent digit from Index in a "constant" way, obtain the
382
+// total population for the branch in a state-dependent way, and then branch to
383
+// common code for multiple cases:
384
+//
385
+// For root-level branches, the state is always cJU_ROOTSTATE, and the
386
+// population is received in Pjpm->jpm_Pop0.
387
+//
388
+// Note: The total population is only needed in cases where the common code
389
+// "counts up" instead of down to minimize cache line fills. However, its
390
+// available cheaply, and its better to do it with a constant shift (constant
391
+// state value) instead of a variable shift later "when needed".
392
+
393
+#define PREPB_ROOT(Pjp,Next) \
394
+ digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE); \
395
+ pop1 = (Pjpm->jpm_Pop0) + 1; \
396
+ goto Next
397
+
398
+#define PREPB(Pjp,cState,Next) \
399
+ digit = JU_DIGITATSTATE(Index, cState); \
400
+ pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \
401
+ goto Next
402
+
403
+
404
+// SWITCH ON JP TYPE:
405
+//
406
+// WARNING: For run-time efficiency the following cases replicate code with
407
+// varying constants, rather than using common code with variable values!
408
+
409
+ switch (JU_JPTYPE(Pjp))
410
+ {
411
+
412
+
413
+// ----------------------------------------------------------------------------
414
+// ROOT-STATE LEAF that starts with a Pop0 word; just count within the leaf:
415
+
416
+ case cJU_LEAFW:
417
+ {
418
+ Pjlw_t Pjlw = P_JLW(Pjp->jp_Addr); // first word of leaf.
419
+
420
+ assert((Pjpm->jpm_Pop0) + 1 == Pjlw[0] + 1); // sent correctly.
421
+ offset = j__udySearchLeafW(Pjlw + 1, Pjpm->jpm_Pop0 + 1, Index);
422
+ assert(offset >= 0); // Index must exist.
423
+ assert(offset < (Pjpm->jpm_Pop0) + 1); // Index be in range.
424
+ return((Pjpm->jpm_Pop0) + 1 - offset); // INCLUSIVE of Index.
425
+ }
426
+
427
+// ----------------------------------------------------------------------------
428
+// LINEAR BRANCH; count populations in JPs in the JBL ABOVE the next digit in
429
+// Index, and recurse for the next digit in Index:
430
+//
431
+// Note: There are no null JPs in a JBL; watch out for pop1 == 0.
432
+//
433
+// Note: A JBL should always fit in one cache line => no need to count up
434
+// versus down to save cache line fills. (PREPB() sets pop1 for no reason.)
435
+
436
+ case cJU_JPBRANCH_L2: CHECKDCD(Pjp, 2); PREPB(Pjp, 2, BranchL);
437
+ case cJU_JPBRANCH_L3: CHECKDCD(Pjp, 3); PREPB(Pjp, 3, BranchL);
438
+
439
+#ifdef JU_64BIT
440
+ case cJU_JPBRANCH_L4: CHECKDCD(Pjp, 4); PREPB(Pjp, 4, BranchL);
441
+ case cJU_JPBRANCH_L5: CHECKDCD(Pjp, 5); PREPB(Pjp, 5, BranchL);
442
+ case cJU_JPBRANCH_L6: CHECKDCD(Pjp, 6); PREPB(Pjp, 6, BranchL);
443
+ case cJU_JPBRANCH_L7: CHECKDCD(Pjp, 7); PREPB(Pjp, 7, BranchL);
444
+#endif
445
+ case cJU_JPBRANCH_L: PREPB_ROOT(Pjp, BranchL);
446
+
447
+// Common code (state-independent) for all cases of linear branches:
448
+
449
+BranchL:
450
+
451
+ Pjbl = P_JBL(Pjp->jp_Addr);
452
+ jpnum = Pjbl->jbl_NumJPs; // above last JP.
453
+ pop1above = 0;
454
+
455
+ while (digit < (Pjbl->jbl_Expanse[--jpnum])) // still ABOVE digit.
456
+ {
457
+ if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum)) == cJU_ALLONES)
458
+ {
459
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
460
+ return(C_JERR);
461
+ }
462
+
463
+ pop1above += pop1;
464
+ assert(jpnum > 0); // should find digit.
465
+ }
466
+
467
+ assert(digit == (Pjbl->jbl_Expanse[jpnum])); // should find digit.
468
+
469
+ pop1 = j__udy1LCountSM((Pjbl->jbl_jp) + jpnum, Index, Pjpm);
470
+ if (pop1 == C_JERR) return(C_JERR); // pass error up.
471
+
472
+ assert(pop1above + pop1);
473
+ return(pop1above + pop1);
474
+
475
+
476
+// ----------------------------------------------------------------------------
477
+// BITMAP BRANCH; count populations in JPs in the JBB ABOVE the next digit in
478
+// Index, and recurse for the next digit in Index:
479
+//
480
+// Note: There are no null JPs in a JBB; watch out for pop1 == 0.
481
+
482
+ case cJU_JPBRANCH_B2: CHECKDCD(Pjp, 2); PREPB(Pjp, 2, BranchB);
483
+ case cJU_JPBRANCH_B3: CHECKDCD(Pjp, 3); PREPB(Pjp, 3, BranchB);
484
+#ifdef JU_64BIT
485
+ case cJU_JPBRANCH_B4: CHECKDCD(Pjp, 4); PREPB(Pjp, 4, BranchB);
486
+ case cJU_JPBRANCH_B5: CHECKDCD(Pjp, 5); PREPB(Pjp, 5, BranchB);
487
+ case cJU_JPBRANCH_B6: CHECKDCD(Pjp, 6); PREPB(Pjp, 6, BranchB);
488
+ case cJU_JPBRANCH_B7: CHECKDCD(Pjp, 7); PREPB(Pjp, 7, BranchB);
489
+#endif
490
+ case cJU_JPBRANCH_B: PREPB_ROOT(Pjp, BranchB);
491
+
492
+// Common code (state-independent) for all cases of bitmap branches:
493
+
494
+BranchB:
495
+ {
496
+ long subexp; // for stepping through layer 1 (subexpanses).
497
+ long findsub; // subexpanse containing Index (digit).
498
+ Word_t findbit; // bit representing Index (digit).
499
+ Word_t lowermask; // bits for indexes at or below Index.
500
+ Word_t jpcount; // JPs in a subexpanse.
501
+ Word_t clbelow; // cache lines below digits cache line.
502
+ Word_t clabove; // cache lines above digits cache line.
503
+
504
+ Pjbb = P_JBB(Pjp->jp_Addr);
505
+ findsub = digit / cJU_BITSPERSUBEXPB;
506
+ findbit = digit % cJU_BITSPERSUBEXPB;
507
+ lowermask = JU_MASKLOWERINC(JU_BITPOSMASKB(findbit));
508
+ clbelow = clabove = 0; // initial/default => always downward.
509
+
510
+ assert(JU_BITMAPTESTB(Pjbb, digit)); // digit must have a JP.
511
+ assert(findsub < cJU_NUMSUBEXPB); // falls in expected range.
512
+
513
+// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch:
514
+//
515
+// Note: BMPJP0 exists separately to support assertions.
516
+
517
+#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp)))
518
+#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum))
519
+
520
+#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
521
+
522
+// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
523
+// in JPs above Indexs JP, or subtracting the pop1s in JPs below Indexs JP.
524
+//
525
+// This is tricky because, while each set bit in the bitmap represents a JP,
526
+// the JPs are scattered over cJU_NUMSUBEXPB subexpanses, each of which can
527
+// contain JPs packed into multiple cache lines, and this code must visit every
528
+// JP either BELOW or ABOVE the JP for Index.
529
+//
530
+// Number of cache lines required to hold a linear list of the given number of
531
+// JPs, assuming the first JP is at the start of a cache line or the JPs in
532
+// jpcount fit wholly within a single cache line, which is ensured by
533
+// JudyMalloc():
534
+
535
+#define CLPERJPS(jpcount) \
536
+ ((((jpcount) * cJU_WORDSPERJP) + cJU_WORDSPERCL - 1) / cJU_WORDSPERCL)
537
+
538
+// Count cache lines below/above for each subexpanse:
539
+
540
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
541
+ {
542
+ jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
543
+
544
+// When at the subexpanse containing Index (digit), add cache lines
545
+// below/above appropriately, excluding the cache line containing the JP for
546
+// Index itself:
547
+
548
+ if (subexp < findsub) clbelow += CLPERJPS(jpcount);
549
+ else if (subexp > findsub) clabove += CLPERJPS(jpcount);
550
+ else // (subexp == findsub)
551
+ {
552
+ Word_t clfind; // cache line containing Index (digit).
553
+
554
+ clfind = CLPERJPS(j__udyCountBitsB(
555
+ JU_JBB_BITMAP(Pjbb, subexp) & lowermask));
556
+
557
+ assert(clfind > 0); // digit itself should have 1 CL.
558
+ clbelow += clfind - 1;
559
+ clabove += CLPERJPS(jpcount) - clfind;
560
+ }
561
+ }
562
+#endif // ! NOSMARTJBB
563
+
564
+// Note: Its impossible to get through the following "if" without setting
565
+// jpnum -- see some of the assertions below -- but gcc -Wall doesnt know
566
+// this, so preset jpnum to make it happy:
567
+
568
+ jpnum = 0;
569
+
570
+
571
+// COUNT POPULATION FOR A BITMAP BRANCH, in whichever direction should result
572
+// in fewer cache line fills:
573
+//
574
+// Note: If the remainder of Index is zero, pop1above is the pop1 of the
575
+// entire expanse and theres no point in recursing to lower levels; but this
576
+// should be so rare that its not worth checking for;
577
+// Judy1Count()/JudyLCount() never even calls the motor for Index == 0 (all
578
+// bytes).
579
+
580
+
581
+// COUNT UPWARD, subtracting each "below or at" JPs pop1 from the whole
582
+// expanses pop1:
583
+//
584
+// Note: If this causes clbelow + 1 cache line fills including JPs cache
585
+// line, thats OK; at worst this is the same as clabove.
586
+
587
+ if (clbelow < clabove)
588
+ {
589
+#ifdef SMARTMETRICS
590
+ ++jbb_upward;
591
+#endif
592
+ pop1above = pop1; // subtract JPs at/below Index.
593
+
594
+// Count JPs for which to accrue pop1s in this subexpanse:
595
+//
596
+// TBD: If JU_JBB_BITMAP is cJU_FULLBITMAPB, dont bother counting.
597
+
598
+ for (subexp = 0; subexp <= findsub; ++subexp)
599
+ {
600
+ jpcount = j__udyCountBitsB((subexp < findsub) ?
601
+ JU_JBB_BITMAP(Pjbb, subexp) :
602
+ JU_JBB_BITMAP(Pjbb, subexp) & lowermask);
603
+
604
+ // should always find findbit:
605
+ assert((subexp < findsub) || jpcount);
606
+
607
+// Subtract pop1s from JPs BELOW OR AT Index (digit):
608
+//
609
+// Note: The pop1 for Indexs JP itself is partially added back later at a
610
+// lower state.
611
+//
612
+// Note: An empty subexpanse (jpcount == 0) is handled "for free".
613
+//
614
+// Note: Must be null JP subexp pointer in empty subexpanse and non-empty in
615
+// non-empty subexpanse:
616
+
617
+ assert( jpcount || (BMPJP0(subexp) == (Pjp_t) NULL));
618
+ assert((! jpcount) || (BMPJP0(subexp) != (Pjp_t) NULL));
619
+
620
+ for (jpnum = 0; jpnum < jpcount; ++jpnum)
621
+ {
622
+ if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
623
+ == cJU_ALLONES)
624
+ {
625
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
626
+ return(C_JERR);
627
+ }
628
+
629
+ pop1above -= pop1;
630
+ }
631
+
632
+ jpnum = jpcount - 1; // make correct for digit.
633
+ }
634
+ }
635
+
636
+// COUNT DOWNWARD, adding each "above" JPs pop1:
637
+
638
+ else
639
+ {
640
+ long jpcountbf; // below findbit, inclusive.
641
+#ifdef SMARTMETRICS
642
+ ++jbb_downward;
643
+#endif
644
+ pop1above = 0; // add JPs above Index.
645
+ jpcountbf = 0; // until subexp == findsub.
646
+
647
+// Count JPs for which to accrue pop1s in this subexpanse:
648
+//
649
+// This is more complicated than counting upward because the scan of digits
650
+// subexpanse must count ALL JPs, to know where to START counting down, and
651
+// ALSO note the offset of digits JP to know where to STOP counting down.
652
+
653
+ for (subexp = cJU_NUMSUBEXPB - 1; subexp >= findsub; --subexp)
654
+ {
655
+ jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
656
+
657
+ // should always find findbit:
658
+ assert((subexp > findsub) || jpcount);
659
+
660
+ if (! jpcount) continue; // empty subexpanse, save time.
661
+
662
+// Count JPs below digit, inclusive:
663
+
664
+ if (subexp == findsub)
665
+ {
666
+ jpcountbf = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)
667
+ & lowermask);
668
+ }
669
+
670
+ // should always find findbit:
671
+ assert((subexp > findsub) || jpcountbf);
672
+ assert(jpcount >= jpcountbf); // proper relationship.
673
+
674
+// Add pop1s from JPs ABOVE Index (digit):
675
+
676
+ // no null JP subexp pointers:
677
+ assert(BMPJP0(subexp) != (Pjp_t) NULL);
678
+
679
+ for (jpnum = jpcount - 1; jpnum >= jpcountbf; --jpnum)
680
+ {
681
+ if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
682
+ == cJU_ALLONES)
683
+ {
684
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
685
+ return(C_JERR);
686
+ }
687
+
688
+ pop1above += pop1;
689
+ }
690
+ // jpnum is now correct for digit.
691
+ }
692
+ } // else.
693
+
694
+// Return the net population ABOVE the digits JP at this state (in this JBB)
695
+// plus the population AT OR ABOVE Index in the SM under the digits JP:
696
+
697
+ pop1 = j__udy1LCountSM(BMPJP(findsub, jpnum), Index, Pjpm);
698
+ if (pop1 == C_JERR) return(C_JERR); // pass error up.
699
+
700
+ assert(pop1above + pop1);
701
+ return(pop1above + pop1);
702
+
703
+ } // case.
704
+
705
+
706
+// ----------------------------------------------------------------------------
707
+// UNCOMPRESSED BRANCH; count populations in JPs in the JBU ABOVE the next
708
+// digit in Index, and recurse for the next digit in Index:
709
+//
710
+// Note: If the remainder of Index is zero, pop1above is the pop1 of the
711
+// entire expanse and theres no point in recursing to lower levels; but this
712
+// should be so rare that its not worth checking for;
713
+// Judy1Count()/JudyLCount() never even calls the motor for Index == 0 (all
714
+// bytes).
715
+
716
+ case cJU_JPBRANCH_U2: CHECKDCD(Pjp, 2); PREPB(Pjp, 2, BranchU);
717
+ case cJU_JPBRANCH_U3: CHECKDCD(Pjp, 3); PREPB(Pjp, 3, BranchU);
718
+#ifdef JU_64BIT
719
+ case cJU_JPBRANCH_U4: CHECKDCD(Pjp, 4); PREPB(Pjp, 4, BranchU);
720
+ case cJU_JPBRANCH_U5: CHECKDCD(Pjp, 5); PREPB(Pjp, 5, BranchU);
721
+ case cJU_JPBRANCH_U6: CHECKDCD(Pjp, 6); PREPB(Pjp, 6, BranchU);
722
+ case cJU_JPBRANCH_U7: CHECKDCD(Pjp, 7); PREPB(Pjp, 7, BranchU);
723
+#endif
724
+ case cJU_JPBRANCH_U: PREPB_ROOT(Pjp, BranchU);
725
+
726
+// Common code (state-independent) for all cases of uncompressed branches:
727
+
728
+BranchU:
729
+ Pjbu = P_JBU(Pjp->jp_Addr);
730
+
731
+#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
732
+
733
+// FIGURE OUT WHICH WAY CAUSES FEWER CACHE LINE FILLS; adding the JPs above
734
+// Indexs JP, or subtracting the JPs below Indexs JP.
735
+//
736
+// COUNT UPWARD, subtracting the pop1 of each JP BELOW OR AT Index, from the
737
+// whole expanses pop1:
738
+
739
+ if (digit < (cJU_BRANCHUNUMJPS / 2))
740
+ {
741
+ pop1above = pop1; // subtract JPs below Index.
742
+#ifdef SMARTMETRICS
743
+ ++jbu_upward;
744
+#endif
745
+ for (jpnum = 0; jpnum <= digit; ++jpnum)
746
+ {
747
+ if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
748
+ continue; // shortcut, save a function call.
749
+
750
+ if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum))
751
+ == cJU_ALLONES)
752
+ {
753
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
754
+ return(C_JERR);
755
+ }
756
+
757
+ pop1above -= pop1;
758
+ }
759
+ }
760
+
761
+// COUNT DOWNWARD, simply adding the pop1 of each JP ABOVE Index:
762
+
763
+ else
764
+#endif // NOSMARTJBU
765
+ {
766
+ assert(digit < cJU_BRANCHUNUMJPS);
767
+#ifdef SMARTMETRICS
768
+ ++jbu_downward;
769
+#endif
770
+ pop1above = 0; // add JPs above Index.
771
+
772
+ for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum > digit; --jpnum)
773
+ {
774
+ if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
775
+ continue; // shortcut, save a function call.
776
+
777
+ if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum))
778
+ == cJU_ALLONES)
779
+ {
780
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
781
+ return(C_JERR);
782
+ }
783
+
784
+ pop1above += pop1;
785
+ }
786
+ }
787
+
788
+ if ((pop1 = j__udy1LCountSM(Pjbu->jbu_jp + digit, Index, Pjpm))
789
+ == C_JERR) return(C_JERR); // pass error up.
790
+
791
+ assert(pop1above + pop1);
792
+ return(pop1above + pop1);
793
+
794
+
795
+// ----------------------------------------------------------------------------
796
+// LEAF COUNT MACROS:
797
+//
798
+// LEAF*ABOVE() are common code for different JP types (linear leaves, bitmap
799
+// leaves, and immediates) and different leaf Index Sizes, which result in
800
+// calling different leaf search functions. Linear leaves get the leaf address
801
+// from jp_Addr and the Population from jp_DcdPopO, while immediates use Pjp
802
+// itself as the leaf address and get Population from jp_Type.
803
+
804
+#define LEAFLABOVE(Func) \
805
+ Pjll = P_JLL(Pjp->jp_Addr); \
806
+ pop1 = JU_JPLEAF_POP0(Pjp) + 1; \
807
+ LEAFABOVE(Func, Pjll, pop1)
808
+
809
+#define LEAFB1ABOVE(Func) LEAFLABOVE(Func) // different Func, otherwise same.
810
+
811
+#ifdef JUDY1
812
+#define IMMABOVE(Func,Pop1) \
813
+ Pjll = (Pjll_t) Pjp; \
814
+ LEAFABOVE(Func, Pjll, Pop1)
815
+#else
816
+// Note: For JudyL immediates with >= 2 Indexes, the index bytes are in a
817
+// different place than for Judy1:
818
+
819
+#define IMMABOVE(Func,Pop1) \
820
+ LEAFABOVE(Func, (Pjll_t) (Pjp->jp_LIndex), Pop1)
821
+#endif
822
+
823
+// For all leaf types, the population AT OR ABOVE is the total pop1 less the
824
+// offset of Index; and Index should always be found:
825
+
826
+#define LEAFABOVE(Func,Pjll,Pop1) \
827
+ offset = Func(Pjll, Pop1, Index); \
828
+ assert(offset >= 0); \
829
+ assert(offset < (Pop1)); \
830
+ return((Pop1) - offset)
831
+
832
+// IMMABOVE_01 handles the special case of an immediate JP with 1 index, which
833
+// the search functions arent used for anyway:
834
+//
835
+// The target Index should be the one in this Immediate, in which case the
836
+// count above (inclusive) is always 1.
837
+
838
+#define IMMABOVE_01 \
839
+ assert((JU_JPDCDPOP0(Pjp)) == JU_TRIMTODCDSIZE(Index)); \
840
+ return(1)
841
+
842
+
843
+// ----------------------------------------------------------------------------
844
+// LINEAR LEAF; search the leaf for Index; size is computed from jp_Type:
845
+
846
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
847
+ case cJU_JPLEAF1: LEAFLABOVE(j__udySearchLeaf1);
848
+#endif
849
+ case cJU_JPLEAF2: LEAFLABOVE(j__udySearchLeaf2);
850
+ case cJU_JPLEAF3: LEAFLABOVE(j__udySearchLeaf3);
851
+
852
+#ifdef JU_64BIT
853
+ case cJU_JPLEAF4: LEAFLABOVE(j__udySearchLeaf4);
854
+ case cJU_JPLEAF5: LEAFLABOVE(j__udySearchLeaf5);
855
+ case cJU_JPLEAF6: LEAFLABOVE(j__udySearchLeaf6);
856
+ case cJU_JPLEAF7: LEAFLABOVE(j__udySearchLeaf7);
857
+#endif
858
+
859
+
860
+// ----------------------------------------------------------------------------
861
+// BITMAP LEAF; search the leaf for Index:
862
+//
863
+// Since the bitmap describes Indexes digitally rather than linearly, this is
864
+// not really a search, but just a count.
865
+
866
+ case cJU_JPLEAF_B1: LEAFB1ABOVE(j__udyCountLeafB1);
867
+
868
+
869
+#ifdef JUDY1
870
+// ----------------------------------------------------------------------------
871
+// FULL POPULATION:
872
+//
873
+// Return the count of Indexes AT OR ABOVE Index, which is the total population
874
+// of the expanse (a constant) less the value of the undecoded digit remaining
875
+// in Index (its base-0 offset in the expanse), which yields an inclusive count
876
+// above.
877
+//
878
+// TBD: This only supports a 1-byte full expanse. Should this extract a
879
+// stored value for pop0 and possibly more LSBs of Index, to handle larger full
880
+// expanses?
881
+
882
+ case cJ1_JPFULLPOPU1:
883
+ return(cJU_JPFULLPOPU1_POP0 + 1 - JU_DIGITATSTATE(Index, 1));
884
+#endif
885
+
886
+
887
+// ----------------------------------------------------------------------------
888
+// IMMEDIATE:
889
+
890
+ case cJU_JPIMMED_1_01: IMMABOVE_01;
891
+ case cJU_JPIMMED_2_01: IMMABOVE_01;
892
+ case cJU_JPIMMED_3_01: IMMABOVE_01;
893
+#ifdef JU_64BIT
894
+ case cJU_JPIMMED_4_01: IMMABOVE_01;
895
+ case cJU_JPIMMED_5_01: IMMABOVE_01;
896
+ case cJU_JPIMMED_6_01: IMMABOVE_01;
897
+ case cJU_JPIMMED_7_01: IMMABOVE_01;
898
+#endif
899
+
900
+ case cJU_JPIMMED_1_02: IMMABOVE(j__udySearchLeaf1, 2);
901
+ case cJU_JPIMMED_1_03: IMMABOVE(j__udySearchLeaf1, 3);
902
+#if (defined(JUDY1) || defined(JU_64BIT))
903
+ case cJU_JPIMMED_1_04: IMMABOVE(j__udySearchLeaf1, 4);
904
+ case cJU_JPIMMED_1_05: IMMABOVE(j__udySearchLeaf1, 5);
905
+ case cJU_JPIMMED_1_06: IMMABOVE(j__udySearchLeaf1, 6);
906
+ case cJU_JPIMMED_1_07: IMMABOVE(j__udySearchLeaf1, 7);
907
+#endif
908
+#if (defined(JUDY1) && defined(JU_64BIT))
909
+ case cJ1_JPIMMED_1_08: IMMABOVE(j__udySearchLeaf1, 8);
910
+ case cJ1_JPIMMED_1_09: IMMABOVE(j__udySearchLeaf1, 9);
911
+ case cJ1_JPIMMED_1_10: IMMABOVE(j__udySearchLeaf1, 10);
912
+ case cJ1_JPIMMED_1_11: IMMABOVE(j__udySearchLeaf1, 11);
913
+ case cJ1_JPIMMED_1_12: IMMABOVE(j__udySearchLeaf1, 12);
914
+ case cJ1_JPIMMED_1_13: IMMABOVE(j__udySearchLeaf1, 13);
915
+ case cJ1_JPIMMED_1_14: IMMABOVE(j__udySearchLeaf1, 14);
916
+ case cJ1_JPIMMED_1_15: IMMABOVE(j__udySearchLeaf1, 15);
917
+#endif
918
+
919
+#if (defined(JUDY1) || defined(JU_64BIT))
920
+ case cJU_JPIMMED_2_02: IMMABOVE(j__udySearchLeaf2, 2);
921
+ case cJU_JPIMMED_2_03: IMMABOVE(j__udySearchLeaf2, 3);
922
+#endif
923
+#if (defined(JUDY1) && defined(JU_64BIT))
924
+ case cJ1_JPIMMED_2_04: IMMABOVE(j__udySearchLeaf2, 4);
925
+ case cJ1_JPIMMED_2_05: IMMABOVE(j__udySearchLeaf2, 5);
926
+ case cJ1_JPIMMED_2_06: IMMABOVE(j__udySearchLeaf2, 6);
927
+ case cJ1_JPIMMED_2_07: IMMABOVE(j__udySearchLeaf2, 7);
928
+#endif
929
+
930
+#if (defined(JUDY1) || defined(JU_64BIT))
931
+ case cJU_JPIMMED_3_02: IMMABOVE(j__udySearchLeaf3, 2);
932
+#endif
933
+#if (defined(JUDY1) && defined(JU_64BIT))
934
+ case cJ1_JPIMMED_3_03: IMMABOVE(j__udySearchLeaf3, 3);
935
+ case cJ1_JPIMMED_3_04: IMMABOVE(j__udySearchLeaf3, 4);
936
+ case cJ1_JPIMMED_3_05: IMMABOVE(j__udySearchLeaf3, 5);
937
+
938
+ case cJ1_JPIMMED_4_02: IMMABOVE(j__udySearchLeaf4, 2);
939
+ case cJ1_JPIMMED_4_03: IMMABOVE(j__udySearchLeaf4, 3);
940
+
941
+ case cJ1_JPIMMED_5_02: IMMABOVE(j__udySearchLeaf5, 2);
942
+ case cJ1_JPIMMED_5_03: IMMABOVE(j__udySearchLeaf5, 3);
943
+
944
+ case cJ1_JPIMMED_6_02: IMMABOVE(j__udySearchLeaf6, 2);
945
+
946
+ case cJ1_JPIMMED_7_02: IMMABOVE(j__udySearchLeaf7, 2);
947
+#endif
948
+
949
+
950
+// ----------------------------------------------------------------------------
951
+// OTHER CASES:
952
+
953
+ default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); return(C_JERR);
954
+
955
+ } // switch on JP type
956
+
957
+ /*NOTREACHED*/
958
+
959
+} // j__udy1LCountSM()
960
+
961
+
962
+// ****************************************************************************
963
+// J U D Y C O U N T L E A F B 1
964
+//
965
+// This is a private analog of the j__udySearchLeaf*() functions for counting
966
+// in bitmap 1-byte leaves. Since a bitmap leaf describes Indexes digitally
967
+// rather than linearly, this is not really a search, but just a count of the
968
+// valid Indexes == set bits below or including Index, which should be valid.
969
+// Return the "offset" (really the ordinal), 0 .. Pop1 - 1, of Index in Pjll;
970
+// if Indexs bit is not set (which should never happen, so this is DEBUG-mode
971
+// only), return the 1s-complement equivalent (== negative offset minus 1).
972
+//
973
+// Note: The source code for this function looks identical for both Judy1 and
974
+// JudyL, but the JU_JLB_BITMAP macro varies.
975
+//
976
+// Note: For simpler calling, the first arg is of type Pjll_t but then cast to
977
+// Pjlb_t.
978
+
979
+FUNCTION static int j__udyCountLeafB1(
980
+const Pjll_t Pjll, // bitmap leaf, as Pjll_t for consistency.
981
+const Word_t Pop1, // Population of whole leaf.
982
+const Word_t Index) // to which to count.
983
+{
984
+ Pjlb_t Pjlb = (Pjlb_t) Pjll; // to proper type.
985
+ Word_t digit = Index & cJU_MASKATSTATE(1);
986
+ Word_t findsub = digit / cJU_BITSPERSUBEXPL;
987
+ Word_t findbit = digit % cJU_BITSPERSUBEXPL;
988
+ int count; // in leaf through Index.
989
+ long subexp; // for stepping through subexpanses.
990
+
991
+
992
+// COUNT UPWARD:
993
+//
994
+// The entire bitmap should fit in one cache line, but still try to save some
995
+// CPU time by counting the fewest possible number of subexpanses from the
996
+// bitmap.
997
+
998
+#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
999
+
1000
+ if (findsub < (cJU_NUMSUBEXPL / 2))
1001
+ {
1002
+#ifdef SMARTMETRICS
1003
+ ++jlb_upward;
1004
+#endif
1005
+ count = 0;
1006
+
1007
+ for (subexp = 0; subexp < findsub; ++subexp)
1008
+ {
1009
+ count += ((JU_JLB_BITMAP(Pjlb, subexp) == cJU_FULLBITMAPL) ?
1010
+ cJU_BITSPERSUBEXPL :
1011
+ j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp)));
1012
+ }
1013
+
1014
+// This count includes findbit, which should be set, resulting in a base-1
1015
+// offset:
1016
+
1017
+ count += j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, findsub)
1018
+ & JU_MASKLOWERINC(JU_BITPOSMASKL(findbit)));
1019
+
1020
+ DBGCODE(if (! JU_BITMAPTESTL(Pjlb, digit)) return(~count);)
1021
+ assert(count >= 1);
1022
+ return(count - 1); // convert to base-0 offset.
1023
+ }
1024
+#endif // NOSMARTJLB
1025
+
1026
+
1027
+// COUNT DOWNWARD:
1028
+//
1029
+// Count the valid Indexes above or at Index, and subtract from Pop1.
1030
+
1031
+#ifdef SMARTMETRICS
1032
+ ++jlb_downward;
1033
+#endif
1034
+ count = Pop1; // base-1 for now.
1035
+
1036
+ for (subexp = cJU_NUMSUBEXPL - 1; subexp > findsub; --subexp)
1037
+ {
1038
+ count -= ((JU_JLB_BITMAP(Pjlb, subexp) == cJU_FULLBITMAPL) ?
1039
+ cJU_BITSPERSUBEXPL :
1040
+ j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp)));
1041
+ }
1042
+
1043
+// This count includes findbit, which should be set, resulting in a base-0
1044
+// offset:
1045
+
1046
+ count -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, findsub)
1047
+ & JU_MASKHIGHERINC(JU_BITPOSMASKL(findbit)));
1048
+
1049
+ DBGCODE(if (! JU_BITMAPTESTL(Pjlb, digit)) return(~count);)
1050
+ assert(count >= 0); // should find Index itself.
1051
+ return(count); // is already a base-0 offset.
1052
+
1053
+} // j__udyCountLeafB1()
1054
+
1055
+
1056
+// ****************************************************************************
1057
+// J U D Y J P P O P 1
1058
+//
1059
+// This function takes any type of JP other than a root-level JP (cJU_LEAFW* or
1060
+// cJU_JPBRANCH* with no number suffix) and extracts the Pop1 from it. In some
1061
+// sense this is a wrapper around the JU_JP*_POP0 macros. Why write it as a
1062
+// function instead of a complex macro containing a trinary? (See version
1063
+// Judy1.h version 4.17.) We think its cheaper to call a function containing
1064
+// a switch statement with "constant" cases than to do the variable
1065
+// calculations in a trinary.
1066
+//
1067
+// For invalid JP Types return cJU_ALLONES. Note that this is an impossibly
1068
+// high Pop1 for any JP below a top level branch.
1069
+
1070
+FUNCTION Word_t j__udyJPPop1(
1071
+const Pjp_t Pjp) // JP to count.
1072
+{
1073
+ switch (JU_JPTYPE(Pjp))
1074
+ {
1075
+#ifdef notdef // caller should shortcut and not even call with these:
1076
+
1077
+ case cJU_JPNULL1:
1078
+ case cJU_JPNULL2:
1079
+ case cJU_JPNULL3: return(0);
1080
+#ifdef JU_64BIT
1081
+ case cJU_JPNULL4:
1082
+ case cJU_JPNULL5:
1083
+ case cJU_JPNULL6:
1084
+ case cJU_JPNULL7: return(0);
1085
+#endif
1086
+#endif // notdef
1087
+
1088
+ case cJU_JPBRANCH_L2:
1089
+ case cJU_JPBRANCH_B2:
1090
+ case cJU_JPBRANCH_U2: return(JU_JPBRANCH_POP0(Pjp,2) + 1);
1091
+
1092
+ case cJU_JPBRANCH_L3:
1093
+ case cJU_JPBRANCH_B3:
1094
+ case cJU_JPBRANCH_U3: return(JU_JPBRANCH_POP0(Pjp,3) + 1);
1095
+
1096
+#ifdef JU_64BIT
1097
+ case cJU_JPBRANCH_L4:
1098
+ case cJU_JPBRANCH_B4:
1099
+ case cJU_JPBRANCH_U4: return(JU_JPBRANCH_POP0(Pjp,4) + 1);
1100
+
1101
+ case cJU_JPBRANCH_L5:
1102
+ case cJU_JPBRANCH_B5:
1103
+ case cJU_JPBRANCH_U5: return(JU_JPBRANCH_POP0(Pjp,5) + 1);
1104
+
1105
+ case cJU_JPBRANCH_L6:
1106
+ case cJU_JPBRANCH_B6:
1107
+ case cJU_JPBRANCH_U6: return(JU_JPBRANCH_POP0(Pjp,6) + 1);
1108
+
1109
+ case cJU_JPBRANCH_L7:
1110
+ case cJU_JPBRANCH_B7:
1111
+ case cJU_JPBRANCH_U7: return(JU_JPBRANCH_POP0(Pjp,7) + 1);
1112
+#endif
1113
+
1114
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
1115
+ case cJU_JPLEAF1:
1116
+#endif
1117
+ case cJU_JPLEAF2:
1118
+ case cJU_JPLEAF3:
1119
+#ifdef JU_64BIT
1120
+ case cJU_JPLEAF4:
1121
+ case cJU_JPLEAF5:
1122
+ case cJU_JPLEAF6:
1123
+ case cJU_JPLEAF7:
1124
+#endif
1125
+ case cJU_JPLEAF_B1: return(JU_JPLEAF_POP0(Pjp) + 1);
1126
+
1127
+#ifdef JUDY1
1128
+ case cJ1_JPFULLPOPU1: return(cJU_JPFULLPOPU1_POP0 + 1);
1129
+#endif
1130
+
1131
+ case cJU_JPIMMED_1_01:
1132
+ case cJU_JPIMMED_2_01:
1133
+ case cJU_JPIMMED_3_01: return(1);
1134
+#ifdef JU_64BIT
1135
+ case cJU_JPIMMED_4_01:
1136
+ case cJU_JPIMMED_5_01:
1137
+ case cJU_JPIMMED_6_01:
1138
+ case cJU_JPIMMED_7_01: return(1);
1139
+#endif
1140
+
1141
+ case cJU_JPIMMED_1_02: return(2);
1142
+ case cJU_JPIMMED_1_03: return(3);
1143
+#if (defined(JUDY1) || defined(JU_64BIT))
1144
+ case cJU_JPIMMED_1_04: return(4);
1145
+ case cJU_JPIMMED_1_05: return(5);
1146
+ case cJU_JPIMMED_1_06: return(6);
1147
+ case cJU_JPIMMED_1_07: return(7);
1148
+#endif
1149
+#if (defined(JUDY1) && defined(JU_64BIT))
1150
+ case cJ1_JPIMMED_1_08: return(8);
1151
+ case cJ1_JPIMMED_1_09: return(9);
1152
+ case cJ1_JPIMMED_1_10: return(10);
1153
+ case cJ1_JPIMMED_1_11: return(11);
1154
+ case cJ1_JPIMMED_1_12: return(12);
1155
+ case cJ1_JPIMMED_1_13: return(13);
1156
+ case cJ1_JPIMMED_1_14: return(14);
1157
+ case cJ1_JPIMMED_1_15: return(15);
1158
+#endif
1159
+
1160
+#if (defined(JUDY1) || defined(JU_64BIT))
1161
+ case cJU_JPIMMED_2_02: return(2);
1162
+ case cJU_JPIMMED_2_03: return(3);
1163
+#endif
1164
+#if (defined(JUDY1) && defined(JU_64BIT))
1165
+ case cJ1_JPIMMED_2_04: return(4);
1166
+ case cJ1_JPIMMED_2_05: return(5);
1167
+ case cJ1_JPIMMED_2_06: return(6);
1168
+ case cJ1_JPIMMED_2_07: return(7);
1169
+#endif
1170
+
1171
+#if (defined(JUDY1) || defined(JU_64BIT))
1172
+ case cJU_JPIMMED_3_02: return(2);
1173
+#endif
1174
+#if (defined(JUDY1) && defined(JU_64BIT))
1175
+ case cJ1_JPIMMED_3_03: return(3);
1176
+ case cJ1_JPIMMED_3_04: return(4);
1177
+ case cJ1_JPIMMED_3_05: return(5);
1178
+
1179
+ case cJ1_JPIMMED_4_02: return(2);
1180
+ case cJ1_JPIMMED_4_03: return(3);
1181
+
1182
+ case cJ1_JPIMMED_5_02: return(2);
1183
+ case cJ1_JPIMMED_5_03: return(3);
1184
+
1185
+ case cJ1_JPIMMED_6_02: return(2);
1186
+
1187
+ case cJ1_JPIMMED_7_02: return(2);
1188
+#endif
1189
+
1190
+ default: return(cJU_ALLONES);
1191
+ }
1192
+
1193
+ /*NOTREACHED*/
1194
+
1195
+} // j__udyJPPop1()
libnetdata/libjudy/src/JudyL/JudyLCreateBranch.c
new
+314
@@ -0,0 +1,314 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.26 $ $Source: /judy/src/JudyCommon/JudyCreateBranch.c $
19
+
20
+// Branch creation functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+
23
+#if (! (defined(JUDY1) || defined(JUDYL)))
24
+#error: One of -DJUDY1 or -DJUDYL must be specified.
25
+#endif
26
+
27
+#ifdef JUDY1
28
+#include "Judy1.h"
29
+#else
30
+#include "JudyL.h"
31
+#endif
32
+
33
+#include "JudyPrivate1L.h"
34
+
35
+
36
+// ****************************************************************************
37
+// J U D Y C R E A T E B R A N C H L
38
+//
39
+// Build a BranchL from an array of JPs and associated 1 byte digits
40
+// (expanses). Return with Pjp pointing to the BranchL. Caller must
41
+// deallocate passed arrays, if necessary.
42
+//
43
+// We have no idea what kind of BranchL it is, so caller must set the jp_Type.
44
+//
45
+// Return -1 if error (details in Pjpm), otherwise return 1.
46
+
47
+FUNCTION int j__udyCreateBranchL(
48
+ Pjp_t Pjp, // Build JPs from this place
49
+ Pjp_t PJPs, // Array of JPs to put into Bitmap branch
50
+ uint8_t Exp[], // Array of expanses to put into bitmap
51
+ Word_t ExpCnt, // Number of above JPs and Expanses
52
+ Pvoid_t Pjpm)
53
+{
54
+ Pjbl_t PjblRaw; // pointer to linear branch.
55
+ Pjbl_t Pjbl;
56
+
57
+ assert(ExpCnt <= cJU_BRANCHLMAXJPS);
58
+
59
+ PjblRaw = j__udyAllocJBL(Pjpm);
60
+ if (PjblRaw == (Pjbl_t) NULL) return(-1);
61
+ Pjbl = P_JBL(PjblRaw);
62
+
63
+// Build a Linear Branch
64
+ Pjbl->jbl_NumJPs = ExpCnt;
65
+
66
+// Copy from the Linear branch from splayed leaves
67
+ JU_COPYMEM(Pjbl->jbl_Expanse, Exp, ExpCnt);
68
+ JU_COPYMEM(Pjbl->jbl_jp, PJPs, ExpCnt);
69
+
70
+// Pass back new pointer to the Linear branch in JP
71
+ Pjp->jp_Addr = (Word_t) PjblRaw;
72
+
73
+ return(1);
74
+
75
+} // j__udyCreateBranchL()
76
+
77
+
78
+// ****************************************************************************
79
+// J U D Y C R E A T E B R A N C H B
80
+//
81
+// Build a BranchB from an array of JPs and associated 1 byte digits
82
+// (expanses). Return with Pjp pointing to the BranchB. Caller must
83
+// deallocate passed arrays, if necessary.
84
+//
85
+// We have no idea what kind of BranchB it is, so caller must set the jp_Type.
86
+//
87
+// Return -1 if error (details in Pjpm), otherwise return 1.
88
+
89
+FUNCTION int j__udyCreateBranchB(
90
+ Pjp_t Pjp, // Build JPs from this place
91
+ Pjp_t PJPs, // Array of JPs to put into Bitmap branch
92
+ uint8_t Exp[], // Array of expanses to put into bitmap
93
+ Word_t ExpCnt, // Number of above JPs and Expanses
94
+ Pvoid_t Pjpm)
95
+{
96
+ Pjbb_t PjbbRaw; // pointer to bitmap branch.
97
+ Pjbb_t Pjbb;
98
+ Word_t ii, jj; // Temps
99
+ uint8_t CurrSubExp; // Current sub expanse for BM
100
+
101
+// This assertion says the number of populated subexpanses is not too large.
102
+// This function is only called when a BranchL overflows to a BranchB or when a
103
+// cascade occurs, meaning a leaf overflows. Either way ExpCnt cant be very
104
+// large, in fact a lot smaller than cJU_BRANCHBMAXJPS. (Otherwise a BranchU
105
+// would be used.) Popping this assertion means something (unspecified) has
106
+// gone very wrong, or else Judys design criteria have changed, although in
107
+// fact there should be no HARM in creating a BranchB with higher actual
108
+// fanout.
109
+
110
+ assert(ExpCnt <= cJU_BRANCHBMAXJPS);
111
+
112
+// Get memory for a Bitmap branch
113
+ PjbbRaw = j__udyAllocJBB(Pjpm);
114
+ if (PjbbRaw == (Pjbb_t) NULL) return(-1);
115
+ Pjbb = P_JBB(PjbbRaw);
116
+
117
+// Get 1st "sub" expanse (0..7) of bitmap branch
118
+ CurrSubExp = Exp[0] / cJU_BITSPERSUBEXPB;
119
+
120
+// Index thru all 1 byte sized expanses:
121
+
122
+ for (jj = ii = 0; ii <= ExpCnt; ii++)
123
+ {
124
+ Word_t SubExp; // Cannot be a uint8_t
125
+
126
+// Make sure we cover the last one
127
+ if (ii == ExpCnt)
128
+ {
129
+ SubExp = cJU_ALLONES; // Force last one
130
+ }
131
+ else
132
+ {
133
+// Calculate the "sub" expanse of the byte expanse
134
+ SubExp = Exp[ii] / cJU_BITSPERSUBEXPB; // Bits 5..7.
135
+
136
+// Set the bit that represents the expanse in Exp[]
137
+ JU_JBB_BITMAP(Pjbb, SubExp) |= JU_BITPOSMASKB(Exp[ii]);
138
+ }
139
+// Check if a new "sub" expanse range needed
140
+ if (SubExp != CurrSubExp)
141
+ {
142
+// Get number of JPs in this sub expanse
143
+ Word_t NumJP = ii - jj;
144
+ Pjp_t PjpRaw;
145
+ Pjp_t Pjp;
146
+
147
+ PjpRaw = j__udyAllocJBBJP(NumJP, Pjpm);
148
+ Pjp = P_JP(PjpRaw);
149
+
150
+ if (PjpRaw == (Pjp_t) NULL) // out of memory.
151
+ {
152
+
153
+// Free any previous allocations:
154
+
155
+ while(CurrSubExp--)
156
+ {
157
+ NumJP = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,
158
+ CurrSubExp));
159
+ if (NumJP)
160
+ {
161
+ j__udyFreeJBBJP(JU_JBB_PJP(Pjbb,
162
+ CurrSubExp), NumJP, Pjpm);
163
+ }
164
+ }
165
+ j__udyFreeJBB(PjbbRaw, Pjpm);
166
+ return(-1);
167
+ }
168
+
169
+// Place the array of JPs in bitmap branch:
170
+
171
+ JU_JBB_PJP(Pjbb, CurrSubExp) = PjpRaw;
172
+
173
+// Copy the JPs to new leaf:
174
+
175
+ JU_COPYMEM(Pjp, PJPs + jj, NumJP);
176
+
177
+// On to the next bitmap branch "sub" expanse:
178
+
179
+ jj = ii;
180
+ CurrSubExp = SubExp;
181
+ }
182
+ } // for each 1-byte expanse
183
+
184
+// Pass back some of the JP to the new Bitmap branch:
185
+
186
+ Pjp->jp_Addr = (Word_t) PjbbRaw;
187
+
188
+ return(1);
189
+
190
+} // j__udyCreateBranchB()
191
+
192
+
193
+// ****************************************************************************
194
+// J U D Y C R E A T E B R A N C H U
195
+//
196
+// Build a BranchU from a BranchB. Return with Pjp pointing to the BranchU.
197
+// Free the BranchB and its JP subarrays.
198
+//
199
+// Return -1 if error (details in Pjpm), otherwise return 1.
200
+
201
+FUNCTION int j__udyCreateBranchU(
202
+ Pjp_t Pjp,
203
+ Pvoid_t Pjpm)
204
+{
205
+ jp_t JPNull;
206
+ Pjbu_t PjbuRaw;
207
+ Pjbu_t Pjbu;
208
+ Pjbb_t PjbbRaw;
209
+ Pjbb_t Pjbb;
210
+ Word_t ii, jj;
211
+ BITMAPB_t BitMap;
212
+ Pjp_t PDstJP;
213
+#ifdef JU_STAGED_EXP
214
+ jbu_t BranchU; // Staged uncompressed branch
215
+#else
216
+
217
+// Allocate memory for a BranchU:
218
+
219
+ PjbuRaw = j__udyAllocJBU(Pjpm);
220
+ if (PjbuRaw == (Pjbu_t) NULL) return(-1);
221
+ Pjbu = P_JBU(PjbuRaw);
222
+#endif
223
+ JU_JPSETADT(&JPNull, 0, 0, JU_JPTYPE(Pjp) - cJU_JPBRANCH_B2 + cJU_JPNULL1);
224
+
225
+// Get the pointer to the BranchB:
226
+
227
+ PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
228
+ Pjbb = P_JBB(PjbbRaw);
229
+
230
+// Set the pointer to the Uncompressed branch
231
+#ifdef JU_STAGED_EXP
232
+ PDstJP = BranchU.jbu_jp;
233
+#else
234
+ PDstJP = Pjbu->jbu_jp;
235
+#endif
236
+ for (ii = 0; ii < cJU_NUMSUBEXPB; ii++)
237
+ {
238
+ Pjp_t PjpA;
239
+ Pjp_t PjpB;
240
+
241
+ PjpB = PjpA = P_JP(JU_JBB_PJP(Pjbb, ii));
242
+
243
+// Get the bitmap for this subexpanse
244
+ BitMap = JU_JBB_BITMAP(Pjbb, ii);
245
+
246
+// NULL empty subexpanses
247
+ if (BitMap == 0)
248
+ {
249
+// But, fill with NULLs
250
+ for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
251
+ {
252
+ PDstJP[jj] = JPNull;
253
+ }
254
+ PDstJP += cJU_BITSPERSUBEXPB;
255
+ continue;
256
+ }
257
+// Check if Uncompressed subexpanse
258
+ if (BitMap == cJU_FULLBITMAPB)
259
+ {
260
+// Copy subexpanse to the Uncompressed branch intact
261
+ JU_COPYMEM(PDstJP, PjpA, cJU_BITSPERSUBEXPB);
262
+
263
+// Bump to next subexpanse
264
+ PDstJP += cJU_BITSPERSUBEXPB;
265
+
266
+// Set length of subexpanse
267
+ jj = cJU_BITSPERSUBEXPB;
268
+ }
269
+ else
270
+ {
271
+ for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
272
+ {
273
+// Copy JP or NULLJP depending on bit
274
+ if (BitMap & 1) { *PDstJP = *PjpA++; }
275
+ else { *PDstJP = JPNull; }
276
+
277
+ PDstJP++; // advance to next JP
278
+ BitMap >>= 1;
279
+ }
280
+ jj = PjpA - PjpB;
281
+ }
282
+
283
+// Free the subexpanse:
284
+
285
+ j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, ii), jj, Pjpm);
286
+
287
+ } // for each JP in BranchU
288
+
289
+#ifdef JU_STAGED_EXP
290
+
291
+// Allocate memory for a BranchU:
292
+
293
+ PjbuRaw = j__udyAllocJBU(Pjpm);
294
+ if (PjbuRaw == (Pjbu_t) NULL) return(-1);
295
+ Pjbu = P_JBU(PjbuRaw);
296
+
297
+// Copy staged branch to newly allocated branch:
298
+//
299
+// TBD: I think this code is broken.
300
+
301
+ *Pjbu = BranchU;
302
+
303
+#endif // JU_STAGED_EXP
304
+
305
+// Finally free the BranchB and put the BranchU in its place:
306
+
307
+ j__udyFreeJBB(PjbbRaw, Pjpm);
308
+
309
+ Pjp->jp_Addr = (Word_t) PjbuRaw;
310
+ Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_B;
311
+
312
+ return(1);
313
+
314
+} // j__udyCreateBranchU()
libnetdata/libjudy/src/JudyL/JudyLDecascade.c
new
+1206
@@ -0,0 +1,1206 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.25 $ $Source: /judy/src/JudyCommon/JudyDecascade.c $
19
+//
20
+// "Decascade" support functions for JudyDel.c: These functions convert
21
+// smaller-index-size leaves to larger-index-size leaves, and also, bitmap
22
+// leaves (LeafB1s) to Leaf1s, and some types of branches to smaller branches
23
+// at the same index size. Some "decascading" occurs explicitly in JudyDel.c,
24
+// but rare or large subroutines appear as functions here, and the overhead to
25
+// call them is negligible.
26
+//
27
+// Compile with one of -DJUDY1 or -DJUDYL. Note: Function names are converted
28
+// to Judy1 or JudyL specific values by external #defines.
29
+
30
+#if (! (defined(JUDY1) || defined(JUDYL)))
31
+#error: One of -DJUDY1 or -DJUDYL must be specified.
32
+#endif
33
+
34
+#ifdef JUDY1
35
+#include "Judy1.h"
36
+#endif
37
+#ifdef JUDYL
38
+#include "JudyL.h"
39
+#endif
40
+
41
+#include "JudyPrivate1L.h"
42
+
43
+DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);)
44
+
45
+
46
+// ****************************************************************************
47
+// __ J U D Y C O P Y 2 T O 3
48
+//
49
+// Copy one or more 2-byte Indexes to a series of 3-byte Indexes.
50
+
51
+FUNCTION static void j__udyCopy2to3(
52
+ uint8_t * PDest, // to where to copy 3-byte Indexes.
53
+ uint16_t * PSrc, // from where to copy 2-byte indexes.
54
+ Word_t Pop1, // number of Indexes to copy.
55
+ Word_t MSByte) // most-significant byte, prefix to each Index.
56
+{
57
+ Word_t Temp; // for building 3-byte Index.
58
+
59
+ assert(Pop1);
60
+
61
+ do {
62
+ Temp = MSByte | *PSrc++;
63
+ JU_COPY3_LONG_TO_PINDEX(PDest, Temp);
64
+ PDest += 3;
65
+ } while (--Pop1);
66
+
67
+} // j__udyCopy2to3()
68
+
69
+
70
+#ifdef JU_64BIT
71
+
72
+// ****************************************************************************
73
+// __ J U D Y C O P Y 3 T O 4
74
+//
75
+// Copy one or more 3-byte Indexes to a series of 4-byte Indexes.
76
+
77
+FUNCTION static void j__udyCopy3to4(
78
+ uint32_t * PDest, // to where to copy 4-byte Indexes.
79
+ uint8_t * PSrc, // from where to copy 3-byte indexes.
80
+ Word_t Pop1, // number of Indexes to copy.
81
+ Word_t MSByte) // most-significant byte, prefix to each Index.
82
+{
83
+ Word_t Temp; // for building 4-byte Index.
84
+
85
+ assert(Pop1);
86
+
87
+ do {
88
+ JU_COPY3_PINDEX_TO_LONG(Temp, PSrc);
89
+ Temp |= MSByte;
90
+ PSrc += 3;
91
+ *PDest++ = Temp; // truncates to uint32_t.
92
+ } while (--Pop1);
93
+
94
+} // j__udyCopy3to4()
95
+
96
+
97
+// ****************************************************************************
98
+// __ J U D Y C O P Y 4 T O 5
99
+//
100
+// Copy one or more 4-byte Indexes to a series of 5-byte Indexes.
101
+
102
+FUNCTION static void j__udyCopy4to5(
103
+ uint8_t * PDest, // to where to copy 4-byte Indexes.
104
+ uint32_t * PSrc, // from where to copy 4-byte indexes.
105
+ Word_t Pop1, // number of Indexes to copy.
106
+ Word_t MSByte) // most-significant byte, prefix to each Index.
107
+{
108
+ Word_t Temp; // for building 5-byte Index.
109
+
110
+ assert(Pop1);
111
+
112
+ do {
113
+ Temp = MSByte | *PSrc++;
114
+ JU_COPY5_LONG_TO_PINDEX(PDest, Temp);
115
+ PDest += 5;
116
+ } while (--Pop1);
117
+
118
+} // j__udyCopy4to5()
119
+
120
+
121
+// ****************************************************************************
122
+// __ J U D Y C O P Y 5 T O 6
123
+//
124
+// Copy one or more 5-byte Indexes to a series of 6-byte Indexes.
125
+
126
+FUNCTION static void j__udyCopy5to6(
127
+ uint8_t * PDest, // to where to copy 6-byte Indexes.
128
+ uint8_t * PSrc, // from where to copy 5-byte indexes.
129
+ Word_t Pop1, // number of Indexes to copy.
130
+ Word_t MSByte) // most-significant byte, prefix to each Index.
131
+{
132
+ Word_t Temp; // for building 6-byte Index.
133
+
134
+ assert(Pop1);
135
+
136
+ do {
137
+ JU_COPY5_PINDEX_TO_LONG(Temp, PSrc);
138
+ Temp |= MSByte;
139
+ JU_COPY6_LONG_TO_PINDEX(PDest, Temp);
140
+ PSrc += 5;
141
+ PDest += 6;
142
+ } while (--Pop1);
143
+
144
+} // j__udyCopy5to6()
145
+
146
+
147
+// ****************************************************************************
148
+// __ J U D Y C O P Y 6 T O 7
149
+//
150
+// Copy one or more 6-byte Indexes to a series of 7-byte Indexes.
151
+
152
+FUNCTION static void j__udyCopy6to7(
153
+ uint8_t * PDest, // to where to copy 6-byte Indexes.
154
+ uint8_t * PSrc, // from where to copy 5-byte indexes.
155
+ Word_t Pop1, // number of Indexes to copy.
156
+ Word_t MSByte) // most-significant byte, prefix to each Index.
157
+{
158
+ Word_t Temp; // for building 6-byte Index.
159
+
160
+ assert(Pop1);
161
+
162
+ do {
163
+ JU_COPY6_PINDEX_TO_LONG(Temp, PSrc);
164
+ Temp |= MSByte;
165
+ JU_COPY7_LONG_TO_PINDEX(PDest, Temp);
166
+ PSrc += 6;
167
+ PDest += 7;
168
+ } while (--Pop1);
169
+
170
+} // j__udyCopy6to7()
171
+
172
+#endif // JU_64BIT
173
+
174
+
175
+#ifndef JU_64BIT // 32-bit
176
+
177
+// ****************************************************************************
178
+// __ J U D Y C O P Y 3 T O W
179
+//
180
+// Copy one or more 3-byte Indexes to a series of longs (words, always 4-byte).
181
+
182
+FUNCTION static void j__udyCopy3toW(
183
+ PWord_t PDest, // to where to copy full-word Indexes.
184
+ uint8_t * PSrc, // from where to copy 3-byte indexes.
185
+ Word_t Pop1, // number of Indexes to copy.
186
+ Word_t MSByte) // most-significant byte, prefix to each Index.
187
+{
188
+ assert(Pop1);
189
+
190
+ do {
191
+ JU_COPY3_PINDEX_TO_LONG(*PDest, PSrc);
192
+ *PDest++ |= MSByte;
193
+ PSrc += 3;
194
+ } while (--Pop1);
195
+
196
+} // j__udyCopy3toW()
197
+
198
+
199
+#else // JU_64BIT
200
+
201
+// ****************************************************************************
202
+// __ J U D Y C O P Y 7 T O W
203
+//
204
+// Copy one or more 7-byte Indexes to a series of longs (words, always 8-byte).
205
+
206
+FUNCTION static void j__udyCopy7toW(
207
+ PWord_t PDest, // to where to copy full-word Indexes.
208
+ uint8_t * PSrc, // from where to copy 7-byte indexes.
209
+ Word_t Pop1, // number of Indexes to copy.
210
+ Word_t MSByte) // most-significant byte, prefix to each Index.
211
+{
212
+ assert(Pop1);
213
+
214
+ do {
215
+ JU_COPY7_PINDEX_TO_LONG(*PDest, PSrc);
216
+ *PDest++ |= MSByte;
217
+ PSrc += 7;
218
+ } while (--Pop1);
219
+
220
+} // j__udyCopy7toW()
221
+
222
+#endif // JU_64BIT
223
+
224
+
225
+// ****************************************************************************
226
+// __ J U D Y B R A N C H B T O B R A N C H L
227
+//
228
+// When a BranchB shrinks to have few enough JPs, call this function to convert
229
+// it to a BranchL. Return 1 for success, or -1 for failure (with details in
230
+// Pjpm).
231
+
232
+FUNCTION int j__udyBranchBToBranchL(
233
+ Pjp_t Pjp, // points to BranchB to shrink.
234
+ Pvoid_t Pjpm) // for global accounting.
235
+{
236
+ Pjbb_t PjbbRaw; // old BranchB to shrink.
237
+ Pjbb_t Pjbb;
238
+ Pjbl_t PjblRaw; // new BranchL to create.
239
+ Pjbl_t Pjbl;
240
+ Word_t Digit; // in BranchB.
241
+ Word_t NumJPs; // non-null JPs in BranchB.
242
+ uint8_t Expanse[cJU_BRANCHLMAXJPS]; // for building jbl_Expanse[].
243
+ Pjp_t Pjpjbl; // current JP in BranchL.
244
+ Word_t SubExp; // in BranchB.
245
+
246
+ assert(JU_JPTYPE(Pjp) >= cJU_JPBRANCH_B2);
247
+ assert(JU_JPTYPE(Pjp) <= cJU_JPBRANCH_B);
248
+
249
+ PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
250
+ Pjbb = P_JBB(PjbbRaw);
251
+
252
+// Copy 1-byte subexpanse digits from BranchB to temporary buffer for BranchL,
253
+// for each bit set in the BranchB:
254
+//
255
+// TBD: The following supports variable-sized linear branches, but they are no
256
+// longer variable; this could be simplified to save the copying.
257
+//
258
+// TBD: Since cJU_BRANCHLMAXJP == 7 now, and cJU_BRANCHUNUMJPS == 256, the
259
+// following might be inefficient; is there a faster way to do it? At least
260
+// skip wholly empty subexpanses?
261
+
262
+ for (NumJPs = Digit = 0; Digit < cJU_BRANCHUNUMJPS; ++Digit)
263
+ {
264
+ if (JU_BITMAPTESTB(Pjbb, Digit))
265
+ {
266
+ Expanse[NumJPs++] = Digit;
267
+ assert(NumJPs <= cJU_BRANCHLMAXJPS); // required of caller.
268
+ }
269
+ }
270
+
271
+// Allocate and populate the BranchL:
272
+
273
+ if ((PjblRaw = j__udyAllocJBL(Pjpm)) == (Pjbl_t) NULL) return(-1);
274
+ Pjbl = P_JBL(PjblRaw);
275
+
276
+ JU_COPYMEM(Pjbl->jbl_Expanse, Expanse, NumJPs);
277
+
278
+ Pjbl->jbl_NumJPs = NumJPs;
279
+ DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse), NumJPs, 1);)
280
+
281
+// Copy JPs from each BranchB subexpanse subarray:
282
+
283
+ Pjpjbl = P_JP(Pjbl->jbl_jp); // start at first JP in array.
284
+
285
+ for (SubExp = 0; SubExp < cJU_NUMSUBEXPB; ++SubExp)
286
+ {
287
+ Pjp_t PjpRaw = JU_JBB_PJP(Pjbb, SubExp); // current Pjp.
288
+ Pjp_t Pjp;
289
+
290
+ if (PjpRaw == (Pjp_t) NULL) continue; // skip empty subexpanse.
291
+ Pjp = P_JP(PjpRaw);
292
+
293
+ NumJPs = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, SubExp));
294
+ assert(NumJPs);
295
+ JU_COPYMEM(Pjpjbl, Pjp, NumJPs); // one subarray at a time.
296
+
297
+ Pjpjbl += NumJPs;
298
+ j__udyFreeJBBJP(PjpRaw, NumJPs, Pjpm); // subarray.
299
+ }
300
+ j__udyFreeJBB(PjbbRaw, Pjpm); // BranchB itself.
301
+
302
+// Finish up: Calculate new JP type (same index size = level in new class),
303
+// and tie new BranchB into parent JP:
304
+
305
+ Pjp->jp_Type += cJU_JPBRANCH_L - cJU_JPBRANCH_B;
306
+ Pjp->jp_Addr = (Word_t) PjblRaw;
307
+
308
+ return(1);
309
+
310
+} // j__udyBranchBToBranchL()
311
+
312
+
313
+#ifdef notdef
314
+
315
+// ****************************************************************************
316
+// __ J U D Y B R A N C H U T O B R A N C H B
317
+//
318
+// When a BranchU shrinks to need little enough memory, call this function to
319
+// convert it to a BranchB to save memory (at the cost of some speed). Return
320
+// 1 for success, or -1 for failure (with details in Pjpm).
321
+//
322
+// TBD: Fill out if/when needed. Not currently used in JudyDel.c for reasons
323
+// explained there.
324
+
325
+FUNCTION int j__udyBranchUToBranchB(
326
+ Pjp_t Pjp, // points to BranchU to shrink.
327
+ Pvoid_t Pjpm) // for global accounting.
328
+{
329
+ assert(FALSE);
330
+ return(1);
331
+}
332
+#endif // notdef
333
+
334
+
335
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
336
+
337
+// ****************************************************************************
338
+// __ J U D Y L E A F B 1 T O L E A F 1
339
+//
340
+// Shrink a bitmap leaf (cJU_LEAFB1) to linear leaf (cJU_JPLEAF1).
341
+// Return 1 for success, or -1 for failure (with details in Pjpm).
342
+//
343
+// Note: This function is different than the other JudyLeaf*ToLeaf*()
344
+// functions because it receives a Pjp, not just a leaf, and handles its own
345
+// allocation and free, in order to allow the caller to continue with a LeafB1
346
+// if allocation fails.
347
+
348
+FUNCTION int j__udyLeafB1ToLeaf1(
349
+ Pjp_t Pjp, // points to LeafB1 to shrink.
350
+ Pvoid_t Pjpm) // for global accounting.
351
+{
352
+ Pjlb_t PjlbRaw; // bitmap in old leaf.
353
+ Pjlb_t Pjlb;
354
+ Pjll_t PjllRaw; // new Leaf1.
355
+ uint8_t * Pleaf1; // Leaf1 pointer type.
356
+ Word_t Digit; // in LeafB1 bitmap.
357
+#ifdef JUDYL
358
+ Pjv_t PjvNew; // value area in new Leaf1.
359
+ Word_t Pop1;
360
+ Word_t SubExp;
361
+#endif
362
+
363
+ assert(JU_JPTYPE(Pjp) == cJU_JPLEAF_B1);
364
+ assert(((JU_JPDCDPOP0(Pjp) & 0xFF) + 1) == cJU_LEAF1_MAXPOP1);
365
+
366
+// Allocate JPLEAF1 and prepare pointers:
367
+
368
+ if ((PjllRaw = j__udyAllocJLL1(cJU_LEAF1_MAXPOP1, Pjpm)) == 0)
369
+ return(-1);
370
+
371
+ Pleaf1 = (uint8_t *) P_JLL(PjllRaw);
372
+ PjlbRaw = (Pjlb_t) (Pjp->jp_Addr);
373
+ Pjlb = P_JLB(PjlbRaw);
374
+ JUDYLCODE(PjvNew = JL_LEAF1VALUEAREA(Pleaf1, cJL_LEAF1_MAXPOP1);)
375
+
376
+// Copy 1-byte indexes from old LeafB1 to new Leaf1:
377
+
378
+ for (Digit = 0; Digit < cJU_BRANCHUNUMJPS; ++Digit)
379
+ if (JU_BITMAPTESTL(Pjlb, Digit))
380
+ *Pleaf1++ = Digit;
381
+
382
+#ifdef JUDYL
383
+
384
+// Copy all old-LeafB1 value areas from value subarrays to new Leaf1:
385
+
386
+ for (SubExp = 0; SubExp < cJU_NUMSUBEXPL; ++SubExp)
387
+ {
388
+ Pjv_t PjvRaw = JL_JLB_PVALUE(Pjlb, SubExp);
389
+ Pjv_t Pjv = P_JV(PjvRaw);
390
+
391
+ if (Pjv == (Pjv_t) NULL) continue; // skip empty subarray.
392
+
393
+ Pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, SubExp)); // subarray.
394
+ assert(Pop1);
395
+
396
+ JU_COPYMEM(PjvNew, Pjv, Pop1); // copy value areas.
397
+ j__udyLFreeJV(PjvRaw, Pop1, Pjpm);
398
+ PjvNew += Pop1; // advance through new.
399
+ }
400
+
401
+ assert((((Word_t) Pleaf1) - (Word_t) P_JLL(PjllRaw))
402
+ == (PjvNew - JL_LEAF1VALUEAREA(P_JLL(PjllRaw), cJL_LEAF1_MAXPOP1)));
403
+#endif // JUDYL
404
+
405
+ DBGCODE(JudyCheckSorted((Pjll_t) P_JLL(PjllRaw),
406
+ (((Word_t) Pleaf1) - (Word_t) P_JLL(PjllRaw)), 1);)
407
+
408
+// Finish up: Free the old LeafB1 and plug the new Leaf1 into the JP:
409
+//
410
+// Note: jp_DcdPopO does not change here.
411
+
412
+ j__udyFreeJLB1(PjlbRaw, Pjpm);
413
+
414
+ Pjp->jp_Addr = (Word_t) PjllRaw;
415
+ Pjp->jp_Type = cJU_JPLEAF1;
416
+
417
+ return(1);
418
+
419
+} // j__udyLeafB1ToLeaf1()
420
+
421
+#endif // (JUDYL || (! JU_64BIT))
422
+
423
+
424
+// ****************************************************************************
425
+// __ J U D Y L E A F 1 T O L E A F 2
426
+//
427
+// Copy 1-byte Indexes from a LeafB1 or Leaf1 to 2-byte Indexes in a Leaf2.
428
+// Pjp MUST be one of: cJU_JPLEAF_B1, cJU_JPLEAF1, or cJU_JPIMMED_1_*.
429
+// Return number of Indexes copied.
430
+//
431
+// TBD: In this and all following functions, the caller should already be able
432
+// to compute the Pop1 return value, so why return it?
433
+
434
+FUNCTION Word_t j__udyLeaf1ToLeaf2(
435
+ uint16_t * PLeaf2, // destination uint16_t * Index portion of leaf.
436
+#ifdef JUDYL
437
+ Pjv_t Pjv2, // destination value part of leaf.
438
+#endif
439
+ Pjp_t Pjp, // 1-byte-index object from which to copy.
440
+ Word_t MSByte, // most-significant byte, prefix to each Index.
441
+ Pvoid_t Pjpm) // for global accounting.
442
+{
443
+ Word_t Pop1; // Indexes in leaf.
444
+ Word_t Offset; // in linear leaf list.
445
+JUDYLCODE(Pjv_t Pjv1Raw;) // source object value area.
446
+JUDYLCODE(Pjv_t Pjv1;)
447
+
448
+ switch (JU_JPTYPE(Pjp))
449
+ {
450
+
451
+
452
+// JPLEAF_B1:
453
+
454
+ case cJU_JPLEAF_B1:
455
+ {
456
+ Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr);
457
+ Word_t Digit; // in LeafB1 bitmap.
458
+ JUDYLCODE(Word_t SubExp;) // in LeafB1.
459
+
460
+ Pop1 = JU_JPBRANCH_POP0(Pjp, 1) + 1; assert(Pop1);
461
+
462
+// Copy 1-byte indexes from old LeafB1 to new Leaf2, including splicing in
463
+// the missing MSByte needed in the Leaf2:
464
+
465
+ for (Digit = 0; Digit < cJU_BRANCHUNUMJPS; ++Digit)
466
+ if (JU_BITMAPTESTL(Pjlb, Digit))
467
+ *PLeaf2++ = MSByte | Digit;
468
+
469
+#ifdef JUDYL
470
+
471
+// Copy all old-LeafB1 value areas from value subarrays to new Leaf2:
472
+
473
+ for (SubExp = 0; SubExp < cJU_NUMSUBEXPL; ++SubExp)
474
+ {
475
+ Word_t SubExpPop1;
476
+
477
+ Pjv1Raw = JL_JLB_PVALUE(Pjlb, SubExp);
478
+ if (Pjv1Raw == (Pjv_t) NULL) continue; // skip empty.
479
+ Pjv1 = P_JV(Pjv1Raw);
480
+
481
+ SubExpPop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, SubExp));
482
+ assert(SubExpPop1);
483
+
484
+ JU_COPYMEM(Pjv2, Pjv1, SubExpPop1); // copy value areas.
485
+ j__udyLFreeJV(Pjv1Raw, SubExpPop1, Pjpm);
486
+ Pjv2 += SubExpPop1; // advance through new.
487
+ }
488
+#endif // JUDYL
489
+
490
+ j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm); // LeafB1 itself.
491
+ return(Pop1);
492
+
493
+ } // case cJU_JPLEAF_B1
494
+
495
+
496
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
497
+
498
+// JPLEAF1:
499
+
500
+ case cJU_JPLEAF1:
501
+ {
502
+ uint8_t * PLeaf1 = (uint8_t *) P_JLL(Pjp->jp_Addr);
503
+
504
+ Pop1 = JU_JPBRANCH_POP0(Pjp, 1) + 1; assert(Pop1);
505
+ JUDYLCODE(Pjv1 = JL_LEAF1VALUEAREA(PLeaf1, Pop1);)
506
+
507
+// Copy all Index bytes including splicing in missing MSByte needed in Leaf2
508
+// (plus, for JudyL, value areas):
509
+
510
+ for (Offset = 0; Offset < Pop1; ++Offset)
511
+ {
512
+ PLeaf2[Offset] = MSByte | PLeaf1[Offset];
513
+ JUDYLCODE(Pjv2[Offset] = Pjv1[Offset];)
514
+ }
515
+ j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
516
+ return(Pop1);
517
+ }
518
+#endif // (JUDYL || (! JU_64BIT))
519
+
520
+
521
+// JPIMMED_1_01:
522
+//
523
+// Note: jp_DcdPopO has 3 [7] bytes of Index (all but most significant byte),
524
+// so the assignment to PLeaf2[] truncates and MSByte is not needed.
525
+
526
+ case cJU_JPIMMED_1_01:
527
+ {
528
+ PLeaf2[0] = JU_JPDCDPOP0(Pjp); // see above.
529
+ JUDYLCODE(Pjv2[0] = Pjp->jp_Addr;)
530
+ return(1);
531
+ }
532
+
533
+
534
+// JPIMMED_1_0[2+]:
535
+
536
+ case cJU_JPIMMED_1_02:
537
+ case cJU_JPIMMED_1_03:
538
+#if (defined(JUDY1) || defined(JU_64BIT))
539
+ case cJU_JPIMMED_1_04:
540
+ case cJU_JPIMMED_1_05:
541
+ case cJU_JPIMMED_1_06:
542
+ case cJU_JPIMMED_1_07:
543
+#endif
544
+#if (defined(JUDY1) && defined(JU_64BIT))
545
+ case cJ1_JPIMMED_1_08:
546
+ case cJ1_JPIMMED_1_09:
547
+ case cJ1_JPIMMED_1_10:
548
+ case cJ1_JPIMMED_1_11:
549
+ case cJ1_JPIMMED_1_12:
550
+ case cJ1_JPIMMED_1_13:
551
+ case cJ1_JPIMMED_1_14:
552
+ case cJ1_JPIMMED_1_15:
553
+#endif
554
+ {
555
+ Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2; assert(Pop1);
556
+ JUDYLCODE(Pjv1Raw = (Pjv_t) (Pjp->jp_Addr);)
557
+ JUDYLCODE(Pjv1 = P_JV(Pjv1Raw);)
558
+
559
+ for (Offset = 0; Offset < Pop1; ++Offset)
560
+ {
561
+#ifdef JUDY1
562
+ PLeaf2[Offset] = MSByte | Pjp->jp_1Index[Offset];
563
+#else
564
+ PLeaf2[Offset] = MSByte | Pjp->jp_LIndex[Offset];
565
+ Pjv2 [Offset] = Pjv1[Offset];
566
+#endif
567
+ }
568
+ JUDYLCODE(j__udyLFreeJV(Pjv1Raw, Pop1, Pjpm);)
569
+ return(Pop1);
570
+ }
571
+
572
+
573
+// UNEXPECTED CASES, including JPNULL1, should be handled by caller:
574
+
575
+ default: assert(FALSE); break;
576
+
577
+ } // switch
578
+
579
+ return(0);
580
+
581
+} // j__udyLeaf1ToLeaf2()
582
+
583
+
584
+// *****************************************************************************
585
+// __ J U D Y L E A F 2 T O L E A F 3
586
+//
587
+// Copy 2-byte Indexes from a Leaf2 to 3-byte Indexes in a Leaf3.
588
+// Pjp MUST be one of: cJU_JPLEAF2 or cJU_JPIMMED_2_*.
589
+// Return number of Indexes copied.
590
+//
591
+// Note: By the time this function is called to compress a level-3 branch to a
592
+// Leaf3, the branch has no narrow pointers under it, meaning only level-2
593
+// objects are below it and must be handled here.
594
+
595
+FUNCTION Word_t j__udyLeaf2ToLeaf3(
596
+ uint8_t * PLeaf3, // destination "uint24_t *" Index part of leaf.
597
+#ifdef JUDYL
598
+ Pjv_t Pjv3, // destination value part of leaf.
599
+#endif
600
+ Pjp_t Pjp, // 2-byte-index object from which to copy.
601
+ Word_t MSByte, // most-significant byte, prefix to each Index.
602
+ Pvoid_t Pjpm) // for global accounting.
603
+{
604
+ Word_t Pop1; // Indexes in leaf.
605
+#if (defined(JUDYL) && defined(JU_64BIT))
606
+ Pjv_t Pjv2Raw; // source object value area.
607
+#endif
608
+JUDYLCODE(Pjv_t Pjv2;)
609
+
610
+ switch (JU_JPTYPE(Pjp))
611
+ {
612
+
613
+
614
+// JPLEAF2:
615
+
616
+ case cJU_JPLEAF2:
617
+ {
618
+ uint16_t * PLeaf2 = (uint16_t *) P_JLL(Pjp->jp_Addr);
619
+
620
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1; assert(Pop1);
621
+ j__udyCopy2to3(PLeaf3, PLeaf2, Pop1, MSByte);
622
+#ifdef JUDYL
623
+ Pjv2 = JL_LEAF2VALUEAREA(PLeaf2, Pop1);
624
+ JU_COPYMEM(Pjv3, Pjv2, Pop1);
625
+#endif
626
+ j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
627
+ return(Pop1);
628
+ }
629
+
630
+
631
+// JPIMMED_2_01:
632
+//
633
+// Note: jp_DcdPopO has 3 [7] bytes of Index (all but most significant byte),
634
+// so the "assignment" to PLeaf3[] is exact [truncates] and MSByte is not
635
+// needed.
636
+
637
+ case cJU_JPIMMED_2_01:
638
+ {
639
+ JU_COPY3_LONG_TO_PINDEX(PLeaf3, JU_JPDCDPOP0(Pjp)); // see above.
640
+ JUDYLCODE(Pjv3[0] = Pjp->jp_Addr;)
641
+ return(1);
642
+ }
643
+
644
+
645
+// JPIMMED_2_0[2+]:
646
+
647
+#if (defined(JUDY1) || defined(JU_64BIT))
648
+ case cJU_JPIMMED_2_02:
649
+ case cJU_JPIMMED_2_03:
650
+#endif
651
+#if (defined(JUDY1) && defined(JU_64BIT))
652
+ case cJ1_JPIMMED_2_04:
653
+ case cJ1_JPIMMED_2_05:
654
+ case cJ1_JPIMMED_2_06:
655
+ case cJ1_JPIMMED_2_07:
656
+#endif
657
+#if (defined(JUDY1) || defined(JU_64BIT))
658
+ {
659
+ JUDY1CODE(uint16_t * PLeaf2 = (uint16_t *) (Pjp->jp_1Index);)
660
+ JUDYLCODE(uint16_t * PLeaf2 = (uint16_t *) (Pjp->jp_LIndex);)
661
+
662
+ Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2; assert(Pop1);
663
+ j__udyCopy2to3(PLeaf3, PLeaf2, Pop1, MSByte);
664
+#ifdef JUDYL
665
+ Pjv2Raw = (Pjv_t) (Pjp->jp_Addr);
666
+ Pjv2 = P_JV(Pjv2Raw);
667
+ JU_COPYMEM(Pjv3, Pjv2, Pop1);
668
+ j__udyLFreeJV(Pjv2Raw, Pop1, Pjpm);
669
+#endif
670
+ return(Pop1);
671
+ }
672
+#endif // (JUDY1 || JU_64BIT)
673
+
674
+
675
+// UNEXPECTED CASES, including JPNULL2, should be handled by caller:
676
+
677
+ default: assert(FALSE); break;
678
+
679
+ } // switch
680
+
681
+ return(0);
682
+
683
+} // j__udyLeaf2ToLeaf3()
684
+
685
+
686
+#ifdef JU_64BIT
687
+
688
+// ****************************************************************************
689
+// __ J U D Y L E A F 3 T O L E A F 4
690
+//
691
+// Copy 3-byte Indexes from a Leaf3 to 4-byte Indexes in a Leaf4.
692
+// Pjp MUST be one of: cJU_JPLEAF3 or cJU_JPIMMED_3_*.
693
+// Return number of Indexes copied.
694
+//
695
+// Note: By the time this function is called to compress a level-4 branch to a
696
+// Leaf4, the branch has no narrow pointers under it, meaning only level-3
697
+// objects are below it and must be handled here.
698
+
699
+FUNCTION Word_t j__udyLeaf3ToLeaf4(
700
+ uint32_t * PLeaf4, // destination uint32_t * Index part of leaf.
701
+#ifdef JUDYL
702
+ Pjv_t Pjv4, // destination value part of leaf.
703
+#endif
704
+ Pjp_t Pjp, // 3-byte-index object from which to copy.
705
+ Word_t MSByte, // most-significant byte, prefix to each Index.
706
+ Pvoid_t Pjpm) // for global accounting.
707
+{
708
+ Word_t Pop1; // Indexes in leaf.
709
+JUDYLCODE(Pjv_t Pjv3Raw;) // source object value area.
710
+JUDYLCODE(Pjv_t Pjv3;)
711
+
712
+ switch (JU_JPTYPE(Pjp))
713
+ {
714
+
715
+
716
+// JPLEAF3:
717
+
718
+ case cJU_JPLEAF3:
719
+ {
720
+ uint8_t * PLeaf3 = (uint8_t *) P_JLL(Pjp->jp_Addr);
721
+
722
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1; assert(Pop1);
723
+ j__udyCopy3to4(PLeaf4, (uint8_t *) PLeaf3, Pop1, MSByte);
724
+#ifdef JUDYL
725
+ Pjv3 = JL_LEAF3VALUEAREA(PLeaf3, Pop1);
726
+ JU_COPYMEM(Pjv4, Pjv3, Pop1);
727
+#endif
728
+ j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
729
+ return(Pop1);
730
+ }
731
+
732
+
733
+// JPIMMED_3_01:
734
+//
735
+// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), so
736
+// the assignment to PLeaf4[] truncates and MSByte is not needed.
737
+
738
+ case cJU_JPIMMED_3_01:
739
+ {
740
+ PLeaf4[0] = JU_JPDCDPOP0(Pjp); // see above.
741
+ JUDYLCODE(Pjv4[0] = Pjp->jp_Addr;)
742
+ return(1);
743
+ }
744
+
745
+
746
+// JPIMMED_3_0[2+]:
747
+
748
+ case cJU_JPIMMED_3_02:
749
+#ifdef JUDY1
750
+ case cJ1_JPIMMED_3_03:
751
+ case cJ1_JPIMMED_3_04:
752
+ case cJ1_JPIMMED_3_05:
753
+#endif
754
+ {
755
+ JUDY1CODE(uint8_t * PLeaf3 = (uint8_t *) (Pjp->jp_1Index);)
756
+ JUDYLCODE(uint8_t * PLeaf3 = (uint8_t *) (Pjp->jp_LIndex);)
757
+
758
+ JUDY1CODE(Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_3_02 + 2;)
759
+ JUDYLCODE(Pop1 = 2;)
760
+
761
+ j__udyCopy3to4(PLeaf4, PLeaf3, Pop1, MSByte);
762
+#ifdef JUDYL
763
+ Pjv3Raw = (Pjv_t) (Pjp->jp_Addr);
764
+ Pjv3 = P_JV(Pjv3Raw);
765
+ JU_COPYMEM(Pjv4, Pjv3, Pop1);
766
+ j__udyLFreeJV(Pjv3Raw, Pop1, Pjpm);
767
+#endif
768
+ return(Pop1);
769
+ }
770
+
771
+
772
+// UNEXPECTED CASES, including JPNULL3, should be handled by caller:
773
+
774
+ default: assert(FALSE); break;
775
+
776
+ } // switch
777
+
778
+ return(0);
779
+
780
+} // j__udyLeaf3ToLeaf4()
781
+
782
+
783
+// Note: In all following j__udyLeaf*ToLeaf*() functions, JPIMMED_*_0[2+]
784
+// cases exist for Judy1 (&& 64-bit) only. JudyL has no equivalent Immeds.
785
+
786
+
787
+// *****************************************************************************
788
+// __ J U D Y L E A F 4 T O L E A F 5
789
+//
790
+// Copy 4-byte Indexes from a Leaf4 to 5-byte Indexes in a Leaf5.
791
+// Pjp MUST be one of: cJU_JPLEAF4 or cJU_JPIMMED_4_*.
792
+// Return number of Indexes copied.
793
+//
794
+// Note: By the time this function is called to compress a level-5 branch to a
795
+// Leaf5, the branch has no narrow pointers under it, meaning only level-4
796
+// objects are below it and must be handled here.
797
+
798
+FUNCTION Word_t j__udyLeaf4ToLeaf5(
799
+ uint8_t * PLeaf5, // destination "uint40_t *" Index part of leaf.
800
+#ifdef JUDYL
801
+ Pjv_t Pjv5, // destination value part of leaf.
802
+#endif
803
+ Pjp_t Pjp, // 4-byte-index object from which to copy.
804
+ Word_t MSByte, // most-significant byte, prefix to each Index.
805
+ Pvoid_t Pjpm) // for global accounting.
806
+{
807
+ Word_t Pop1; // Indexes in leaf.
808
+JUDYLCODE(Pjv_t Pjv4;) // source object value area.
809
+
810
+ switch (JU_JPTYPE(Pjp))
811
+ {
812
+
813
+
814
+// JPLEAF4:
815
+
816
+ case cJU_JPLEAF4:
817
+ {
818
+ uint32_t * PLeaf4 = (uint32_t *) P_JLL(Pjp->jp_Addr);
819
+
820
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1; assert(Pop1);
821
+ j__udyCopy4to5(PLeaf5, PLeaf4, Pop1, MSByte);
822
+#ifdef JUDYL
823
+ Pjv4 = JL_LEAF4VALUEAREA(PLeaf4, Pop1);
824
+ JU_COPYMEM(Pjv5, Pjv4, Pop1);
825
+#endif
826
+ j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
827
+ return(Pop1);
828
+ }
829
+
830
+
831
+// JPIMMED_4_01:
832
+//
833
+// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), so
834
+// the assignment to PLeaf5[] truncates and MSByte is not needed.
835
+
836
+ case cJU_JPIMMED_4_01:
837
+ {
838
+ JU_COPY5_LONG_TO_PINDEX(PLeaf5, JU_JPDCDPOP0(Pjp)); // see above.
839
+ JUDYLCODE(Pjv5[0] = Pjp->jp_Addr;)
840
+ return(1);
841
+ }
842
+
843
+
844
+#ifdef JUDY1
845
+
846
+// JPIMMED_4_0[4+]:
847
+
848
+ case cJ1_JPIMMED_4_02:
849
+ case cJ1_JPIMMED_4_03:
850
+ {
851
+ uint32_t * PLeaf4 = (uint32_t *) (Pjp->jp_1Index);
852
+
853
+ Pop1 = JU_JPTYPE(Pjp) - cJ1_JPIMMED_4_02 + 2;
854
+ j__udyCopy4to5(PLeaf5, PLeaf4, Pop1, MSByte);
855
+ return(Pop1);
856
+ }
857
+#endif // JUDY1
858
+
859
+
860
+// UNEXPECTED CASES, including JPNULL4, should be handled by caller:
861
+
862
+ default: assert(FALSE); break;
863
+
864
+ } // switch
865
+
866
+ return(0);
867
+
868
+} // j__udyLeaf4ToLeaf5()
869
+
870
+
871
+// ****************************************************************************
872
+// __ J U D Y L E A F 5 T O L E A F 6
873
+//
874
+// Copy 5-byte Indexes from a Leaf5 to 6-byte Indexes in a Leaf6.
875
+// Pjp MUST be one of: cJU_JPLEAF5 or cJU_JPIMMED_5_*.
876
+// Return number of Indexes copied.
877
+//
878
+// Note: By the time this function is called to compress a level-6 branch to a
879
+// Leaf6, the branch has no narrow pointers under it, meaning only level-5
880
+// objects are below it and must be handled here.
881
+
882
+FUNCTION Word_t j__udyLeaf5ToLeaf6(
883
+ uint8_t * PLeaf6, // destination uint8_t * Index part of leaf.
884
+#ifdef JUDYL
885
+ Pjv_t Pjv6, // destination value part of leaf.
886
+#endif
887
+ Pjp_t Pjp, // 5-byte-index object from which to copy.
888
+ Word_t MSByte, // most-significant byte, prefix to each Index.
889
+ Pvoid_t Pjpm) // for global accounting.
890
+{
891
+ Word_t Pop1; // Indexes in leaf.
892
+JUDYLCODE(Pjv_t Pjv5;) // source object value area.
893
+
894
+ switch (JU_JPTYPE(Pjp))
895
+ {
896
+
897
+
898
+// JPLEAF5:
899
+
900
+ case cJU_JPLEAF5:
901
+ {
902
+ uint8_t * PLeaf5 = (uint8_t *) P_JLL(Pjp->jp_Addr);
903
+
904
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1; assert(Pop1);
905
+ j__udyCopy5to6(PLeaf6, PLeaf5, Pop1, MSByte);
906
+#ifdef JUDYL
907
+ Pjv5 = JL_LEAF5VALUEAREA(PLeaf5, Pop1);
908
+ JU_COPYMEM(Pjv6, Pjv5, Pop1);
909
+#endif
910
+ j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
911
+ return(Pop1);
912
+ }
913
+
914
+
915
+// JPIMMED_5_01:
916
+//
917
+// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), so
918
+// the assignment to PLeaf6[] truncates and MSByte is not needed.
919
+
920
+ case cJU_JPIMMED_5_01:
921
+ {
922
+ JU_COPY6_LONG_TO_PINDEX(PLeaf6, JU_JPDCDPOP0(Pjp)); // see above.
923
+ JUDYLCODE(Pjv6[0] = Pjp->jp_Addr;)
924
+ return(1);
925
+ }
926
+
927
+
928
+#ifdef JUDY1
929
+
930
+// JPIMMED_5_0[2+]:
931
+
932
+ case cJ1_JPIMMED_5_02:
933
+ case cJ1_JPIMMED_5_03:
934
+ {
935
+ uint8_t * PLeaf5 = (uint8_t *) (Pjp->jp_1Index);
936
+
937
+ Pop1 = JU_JPTYPE(Pjp) - cJ1_JPIMMED_5_02 + 2;
938
+ j__udyCopy5to6(PLeaf6, PLeaf5, Pop1, MSByte);
939
+ return(Pop1);
940
+ }
941
+#endif // JUDY1
942
+
943
+
944
+// UNEXPECTED CASES, including JPNULL5, should be handled by caller:
945
+
946
+ default: assert(FALSE); break;
947
+
948
+ } // switch
949
+
950
+ return(0);
951
+
952
+} // j__udyLeaf5ToLeaf6()
953
+
954
+
955
+// *****************************************************************************
956
+// __ J U D Y L E A F 6 T O L E A F 7
957
+//
958
+// Copy 6-byte Indexes from a Leaf2 to 7-byte Indexes in a Leaf7.
959
+// Pjp MUST be one of: cJU_JPLEAF6 or cJU_JPIMMED_6_*.
960
+// Return number of Indexes copied.
961
+//
962
+// Note: By the time this function is called to compress a level-7 branch to a
963
+// Leaf7, the branch has no narrow pointers under it, meaning only level-6
964
+// objects are below it and must be handled here.
965
+
966
+FUNCTION Word_t j__udyLeaf6ToLeaf7(
967
+ uint8_t * PLeaf7, // destination "uint24_t *" Index part of leaf.
968
+#ifdef JUDYL
969
+ Pjv_t Pjv7, // destination value part of leaf.
970
+#endif
971
+ Pjp_t Pjp, // 6-byte-index object from which to copy.
972
+ Word_t MSByte, // most-significant byte, prefix to each Index.
973
+ Pvoid_t Pjpm) // for global accounting.
974
+{
975
+ Word_t Pop1; // Indexes in leaf.
976
+JUDYLCODE(Pjv_t Pjv6;) // source object value area.
977
+
978
+ switch (JU_JPTYPE(Pjp))
979
+ {
980
+
981
+
982
+// JPLEAF6:
983
+
984
+ case cJU_JPLEAF6:
985
+ {
986
+ uint8_t * PLeaf6 = (uint8_t *) P_JLL(Pjp->jp_Addr);
987
+
988
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
989
+ j__udyCopy6to7(PLeaf7, PLeaf6, Pop1, MSByte);
990
+#ifdef JUDYL
991
+ Pjv6 = JL_LEAF6VALUEAREA(PLeaf6, Pop1);
992
+ JU_COPYMEM(Pjv7, Pjv6, Pop1);
993
+#endif
994
+ j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
995
+ return(Pop1);
996
+ }
997
+
998
+
999
+// JPIMMED_6_01:
1000
+//
1001
+// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), so
1002
+// the "assignment" to PLeaf7[] is exact and MSByte is not needed.
1003
+
1004
+ case cJU_JPIMMED_6_01:
1005
+ {
1006
+ JU_COPY7_LONG_TO_PINDEX(PLeaf7, JU_JPDCDPOP0(Pjp)); // see above.
1007
+ JUDYLCODE(Pjv7[0] = Pjp->jp_Addr;)
1008
+ return(1);
1009
+ }
1010
+
1011
+
1012
+#ifdef JUDY1
1013
+
1014
+// JPIMMED_6_02:
1015
+
1016
+ case cJ1_JPIMMED_6_02:
1017
+ {
1018
+ uint8_t * PLeaf6 = (uint8_t *) (Pjp->jp_1Index);
1019
+
1020
+ j__udyCopy6to7(PLeaf7, PLeaf6, /* Pop1 = */ 2, MSByte);
1021
+ return(2);
1022
+ }
1023
+#endif // JUDY1
1024
+
1025
+
1026
+// UNEXPECTED CASES, including JPNULL6, should be handled by caller:
1027
+
1028
+ default: assert(FALSE); break;
1029
+
1030
+ } // switch
1031
+
1032
+ return(0);
1033
+
1034
+} // j__udyLeaf6ToLeaf7()
1035
+
1036
+#endif // JU_64BIT
1037
+
1038
+
1039
+#ifndef JU_64BIT // 32-bit version first
1040
+
1041
+// ****************************************************************************
1042
+// __ J U D Y L E A F 3 T O L E A F W
1043
+//
1044
+// Copy 3-byte Indexes from a Leaf3 to 4-byte Indexes in a LeafW. Pjp MUST be
1045
+// one of: cJU_JPLEAF3 or cJU_JPIMMED_3_*. Return number of Indexes copied.
1046
+//
1047
+// Note: By the time this function is called to compress a level-L branch to a
1048
+// LeafW, the branch has no narrow pointers under it, meaning only level-3
1049
+// objects are below it and must be handled here.
1050
+
1051
+FUNCTION Word_t j__udyLeaf3ToLeafW(
1052
+ Pjlw_t Pjlw, // destination Index part of leaf.
1053
+#ifdef JUDYL
1054
+ Pjv_t PjvW, // destination value part of leaf.
1055
+#endif
1056
+ Pjp_t Pjp, // 3-byte-index object from which to copy.
1057
+ Word_t MSByte, // most-significant byte, prefix to each Index.
1058
+ Pvoid_t Pjpm) // for global accounting.
1059
+{
1060
+ Word_t Pop1; // Indexes in leaf.
1061
+JUDYLCODE(Pjv_t Pjv3;) // source object value area.
1062
+
1063
+ switch (JU_JPTYPE(Pjp))
1064
+ {
1065
+
1066
+
1067
+// JPLEAF3:
1068
+
1069
+ case cJU_JPLEAF3:
1070
+ {
1071
+ uint8_t * PLeaf3 = (uint8_t *) P_JLL(Pjp->jp_Addr);
1072
+
1073
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
1074
+ j__udyCopy3toW((PWord_t) Pjlw, PLeaf3, Pop1, MSByte);
1075
+#ifdef JUDYL
1076
+ Pjv3 = JL_LEAF3VALUEAREA(PLeaf3, Pop1);
1077
+ JU_COPYMEM(PjvW, Pjv3, Pop1);
1078
+#endif
1079
+ j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1080
+ return(Pop1);
1081
+ }
1082
+
1083
+
1084
+// JPIMMED_3_01:
1085
+//
1086
+// Note: jp_DcdPopO has 3 bytes of Index (all but most significant byte), and
1087
+// MSByte must be ord in.
1088
+
1089
+ case cJU_JPIMMED_3_01:
1090
+ {
1091
+ Pjlw[0] = MSByte | JU_JPDCDPOP0(Pjp); // see above.
1092
+ JUDYLCODE(PjvW[0] = Pjp->jp_Addr;)
1093
+ return(1);
1094
+ }
1095
+
1096
+
1097
+#ifdef JUDY1
1098
+
1099
+// JPIMMED_3_02:
1100
+
1101
+ case cJU_JPIMMED_3_02:
1102
+ {
1103
+ uint8_t * PLeaf3 = (uint8_t *) (Pjp->jp_1Index);
1104
+
1105
+ j__udyCopy3toW((PWord_t) Pjlw, PLeaf3, /* Pop1 = */ 2, MSByte);
1106
+ return(2);
1107
+ }
1108
+#endif // JUDY1
1109
+
1110
+
1111
+// UNEXPECTED CASES, including JPNULL3, should be handled by caller:
1112
+
1113
+ default: assert(FALSE); break;
1114
+
1115
+ } // switch
1116
+
1117
+ return(0);
1118
+
1119
+} // j__udyLeaf3ToLeafW()
1120
+
1121
+
1122
+#else // JU_64BIT
1123
+
1124
+
1125
+// ****************************************************************************
1126
+// __ J U D Y L E A F 7 T O L E A F W
1127
+//
1128
+// Copy 7-byte Indexes from a Leaf7 to 8-byte Indexes in a LeafW.
1129
+// Pjp MUST be one of: cJU_JPLEAF7 or cJU_JPIMMED_7_*.
1130
+// Return number of Indexes copied.
1131
+//
1132
+// Note: By the time this function is called to compress a level-L branch to a
1133
+// LeafW, the branch has no narrow pointers under it, meaning only level-7
1134
+// objects are below it and must be handled here.
1135
+
1136
+FUNCTION Word_t j__udyLeaf7ToLeafW(
1137
+ Pjlw_t Pjlw, // destination Index part of leaf.
1138
+#ifdef JUDYL
1139
+ Pjv_t PjvW, // destination value part of leaf.
1140
+#endif
1141
+ Pjp_t Pjp, // 7-byte-index object from which to copy.
1142
+ Word_t MSByte, // most-significant byte, prefix to each Index.
1143
+ Pvoid_t Pjpm) // for global accounting.
1144
+{
1145
+ Word_t Pop1; // Indexes in leaf.
1146
+JUDYLCODE(Pjv_t Pjv7;) // source object value area.
1147
+
1148
+ switch (JU_JPTYPE(Pjp))
1149
+ {
1150
+
1151
+
1152
+// JPLEAF7:
1153
+
1154
+ case cJU_JPLEAF7:
1155
+ {
1156
+ uint8_t * PLeaf7 = (uint8_t *) P_JLL(Pjp->jp_Addr);
1157
+
1158
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
1159
+ j__udyCopy7toW((PWord_t) Pjlw, PLeaf7, Pop1, MSByte);
1160
+#ifdef JUDYL
1161
+ Pjv7 = JL_LEAF7VALUEAREA(PLeaf7, Pop1);
1162
+ JU_COPYMEM(PjvW, Pjv7, Pop1);
1163
+#endif
1164
+ j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
1165
+ return(Pop1);
1166
+ }
1167
+
1168
+
1169
+// JPIMMED_7_01:
1170
+//
1171
+// Note: jp_DcdPopO has 7 bytes of Index (all but most significant byte), and
1172
+// MSByte must be ord in.
1173
+
1174
+ case cJU_JPIMMED_7_01:
1175
+ {
1176
+ Pjlw[0] = MSByte | JU_JPDCDPOP0(Pjp); // see above.
1177
+ JUDYLCODE(PjvW[0] = Pjp->jp_Addr;)
1178
+ return(1);
1179
+ }
1180
+
1181
+
1182
+#ifdef JUDY1
1183
+
1184
+// JPIMMED_7_02:
1185
+
1186
+ case cJ1_JPIMMED_7_02:
1187
+ {
1188
+ uint8_t * PLeaf7 = (uint8_t *) (Pjp->jp_1Index);
1189
+
1190
+ j__udyCopy7toW((PWord_t) Pjlw, PLeaf7, /* Pop1 = */ 2, MSByte);
1191
+ return(2);
1192
+ }
1193
+#endif
1194
+
1195
+
1196
+// UNEXPECTED CASES, including JPNULL7, should be handled by caller:
1197
+
1198
+ default: assert(FALSE); break;
1199
+
1200
+ } // switch
1201
+
1202
+ return(0);
1203
+
1204
+} // j__udyLeaf7ToLeafW()
1205
+
1206
+#endif // JU_64BIT
libnetdata/libjudy/src/JudyL/JudyLDel.c
new
+2146
@@ -0,0 +1,2146 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.68 $ $Source: /judy/src/JudyCommon/JudyDel.c $
19
+//
20
+// Judy1Unset() and JudyLDel() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// About HYSTERESIS: In the Judy code, hysteresis means leaving around a
24
+// nominally suboptimal (not maximally compressed) data structure after a
25
+// deletion. As a result, the shape of the tree for two identical index sets
26
+// can differ depending on the insert/delete path taken to arrive at the index
27
+// sets. The purpose is to minimize worst-case behavior (thrashing) that could
28
+// result from a series of intermixed insertions and deletions. It also makes
29
+// for MUCH simpler code, because instead of performing, "delete and then
30
+// compress," it can say, "compress and then delete," where due to hysteresis,
31
+// compression is not even attempted until the object IS compressible.
32
+//
33
+// In some cases the code has no choice and it must "ungrow" a data structure
34
+// across a "phase transition" boundary without hysteresis. In other cases the
35
+// amount (such as "hysteresis = 1") is indicated by the number of JP deletions
36
+// (in branches) or index deletions (in leaves) that can occur in succession
37
+// before compressing the data structure. (It appears that hysteresis <= 1 in
38
+// all cases.)
39
+//
40
+// In general no hysteresis occurs when the data structure type remains the
41
+// same but the allocated memory chunk for the node must shrink, because the
42
+// relationship is hardwired and theres no way to know how much memory is
43
+// allocated to a given data structure. Hysteresis = 0 in all these cases.
44
+//
45
+// TBD: Could this code be faster if memory chunk hysteresis were supported
46
+// somehow along with data structure type hysteresis?
47
+//
48
+// TBD: Should some of the assertions here be converted to product code that
49
+// returns JU_ERRNO_CORRUPT?
50
+//
51
+// TBD: Dougs code had an odd mix of function-wide and limited-scope
52
+// variables. Should some of the function-wide variables appear only in
53
+// limited scopes, or more likely, vice-versa?
54
+
55
+#if (! (defined(JUDY1) || defined(JUDYL)))
56
+#error: One of -DJUDY1 or -DJUDYL must be specified.
57
+#endif
58
+
59
+#ifdef JUDY1
60
+#include "Judy1.h"
61
+#else
62
+#include "JudyL.h"
63
+#endif
64
+
65
+#include "JudyPrivate1L.h"
66
+
67
+DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
68
+DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);)
69
+
70
+#ifdef TRACEJP
71
+#include "JudyPrintJP.c"
72
+#endif
73
+
74
+// These are defined to generic values in JudyCommon/JudyPrivateTypes.h:
75
+//
76
+// TBD: These should be exported from a header file, but perhaps not, as they
77
+// are only used here, and exported from JudyDecascade.c, which is a separate
78
+// file for profiling reasons (to prevent inlining), but which potentially
79
+// could be merged with this file, either in SoftCM or at compile-time:
80
+
81
+#ifdef JUDY1
82
+
83
+extern int j__udy1BranchBToBranchL(Pjp_t Pjp, Pvoid_t Pjpm);
84
+#ifndef JU_64BIT
85
+extern int j__udy1LeafB1ToLeaf1(Pjp_t, Pvoid_t);
86
+#endif
87
+extern Word_t j__udy1Leaf1ToLeaf2(uint16_t *, Pjp_t, Word_t, Pvoid_t);
88
+extern Word_t j__udy1Leaf2ToLeaf3(uint8_t *, Pjp_t, Word_t, Pvoid_t);
89
+#ifndef JU_64BIT
90
+extern Word_t j__udy1Leaf3ToLeafW(Pjlw_t, Pjp_t, Word_t, Pvoid_t);
91
+#else
92
+extern Word_t j__udy1Leaf3ToLeaf4(uint32_t *, Pjp_t, Word_t, Pvoid_t);
93
+extern Word_t j__udy1Leaf4ToLeaf5(uint8_t *, Pjp_t, Word_t, Pvoid_t);
94
+extern Word_t j__udy1Leaf5ToLeaf6(uint8_t *, Pjp_t, Word_t, Pvoid_t);
95
+extern Word_t j__udy1Leaf6ToLeaf7(uint8_t *, Pjp_t, Word_t, Pvoid_t);
96
+extern Word_t j__udy1Leaf7ToLeafW(Pjlw_t, Pjp_t, Word_t, Pvoid_t);
97
+#endif
98
+
99
+#else // JUDYL
100
+
101
+extern int j__udyLBranchBToBranchL(Pjp_t Pjp, Pvoid_t Pjpm);
102
+extern int j__udyLLeafB1ToLeaf1(Pjp_t, Pvoid_t);
103
+extern Word_t j__udyLLeaf1ToLeaf2(uint16_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
104
+extern Word_t j__udyLLeaf2ToLeaf3(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
105
+#ifndef JU_64BIT
106
+extern Word_t j__udyLLeaf3ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t);
107
+#else
108
+extern Word_t j__udyLLeaf3ToLeaf4(uint32_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
109
+extern Word_t j__udyLLeaf4ToLeaf5(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
110
+extern Word_t j__udyLLeaf5ToLeaf6(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
111
+extern Word_t j__udyLLeaf6ToLeaf7(uint8_t *, Pjv_t, Pjp_t, Word_t, Pvoid_t);
112
+extern Word_t j__udyLLeaf7ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t);
113
+#endif
114
+
115
+#endif // JUDYL
116
+
117
+// For convenience in the calling code; "M1" means "minus one":
118
+
119
+#ifndef JU_64BIT
120
+#define j__udyLeafM1ToLeafW j__udyLeaf3ToLeafW
121
+#else
122
+#define j__udyLeafM1ToLeafW j__udyLeaf7ToLeafW
123
+#endif
124
+
125
+
126
+// ****************************************************************************
127
+// __ J U D Y D E L W A L K
128
+//
129
+// Given a pointer to a JP, an Index known to be valid, the number of bytes
130
+// left to decode (== level in the tree), and a pointer to a global JPM, walk a
131
+// Judy (sub)tree to do an unset/delete of that index, and possibly modify the
132
+// JPM. This function is only called internally, and recursively. Unlike
133
+// Judy1Test() and JudyLGet(), the extra time required for recursion should be
134
+// negligible compared with the total.
135
+//
136
+// Return values:
137
+//
138
+// -1 error; details in JPM
139
+//
140
+// 0 Index already deleted (should never happen, Index is known to be valid)
141
+//
142
+// 1 previously valid Index deleted
143
+//
144
+// 2 same as 1, but in addition the JP now points to a BranchL containing a
145
+// single JP, which should be compressed into the parent branch (if there
146
+// is one, which is not the case for a top-level branch under a JPM)
147
+
148
+DBGCODE(uint8_t parentJPtype;) // parent branch JP type.
149
+
150
+FUNCTION static int j__udyDelWalk(
151
+ Pjp_t Pjp, // current JP under which to delete.
152
+ Word_t Index, // to delete.
153
+ Word_t ParentLevel, // of parent branch.
154
+ Pjpm_t Pjpm) // for returning info to top level.
155
+{
156
+ Word_t pop1; // of a leaf.
157
+ Word_t level; // of a leaf.
158
+ uint8_t digit; // from Index, in current branch.
159
+ Pjll_t PjllnewRaw; // address of newly allocated leaf.
160
+ Pjll_t Pjllnew;
161
+ int offset; // within a branch.
162
+ int retcode; // return code: -1, 0, 1, 2.
163
+JUDYLCODE(Pjv_t PjvRaw;) // value area.
164
+JUDYLCODE(Pjv_t Pjv;)
165
+
166
+ DBGCODE(level = 0;)
167
+
168
+ContinueDelWalk: // for modifying state without recursing.
169
+
170
+#ifdef TRACEJP
171
+ JudyPrintJP(Pjp, "d", __LINE__);
172
+#endif
173
+
174
+ switch (JU_JPTYPE(Pjp)) // entry: Pjp, Index.
175
+ {
176
+
177
+
178
+// ****************************************************************************
179
+// LINEAR BRANCH:
180
+//
181
+// MACROS FOR COMMON CODE:
182
+//
183
+// Check for population too high to compress a branch to a leaf, meaning just
184
+// descend through the branch, with a purposeful off-by-one error that
185
+// constitutes hysteresis = 1. In other words, do not compress until the
186
+// branchs CURRENT population fits in the leaf, even BEFORE deleting one
187
+// index.
188
+//
189
+// Next is a label for branch-type-specific common code. Variables pop1,
190
+// level, digit, and Index are in the context.
191
+
192
+#define JU_BRANCH_KEEP(cLevel,MaxPop1,Next) \
193
+ if (pop1 > (MaxPop1)) /* hysteresis = 1 */ \
194
+ { \
195
+ assert((cLevel) >= 2); \
196
+ level = (cLevel); \
197
+ digit = JU_DIGITATSTATE(Index, cLevel); \
198
+ goto Next; \
199
+ }
200
+
201
+// Support for generic calling of JudyLeaf*ToLeaf*() functions:
202
+//
203
+// Note: Cannot use JUDYLCODE() because this contains a comma.
204
+
205
+#ifdef JUDY1
206
+#define JU_PVALUEPASS // null.
207
+#else
208
+#define JU_PVALUEPASS Pjv,
209
+#endif
210
+
211
+// During compression to a leaf, check if a JP contains nothing but a
212
+// cJU_JPIMMED_*_01, in which case shortcut calling j__udyLeaf*ToLeaf*():
213
+//
214
+// Copy the index bytes from the jp_DcdPopO field (with possible truncation),
215
+// and continue the branch-JP-walk loop. Variables Pjp and Pleaf are in the
216
+// context.
217
+
218
+#define JU_BRANCH_COPY_IMMED_EVEN(cLevel,Pjp,ignore) \
219
+ if (JU_JPTYPE(Pjp) == cJU_JPIMMED_1_01 + (cLevel) - 2) \
220
+ { \
221
+ *Pleaf++ = JU_JPDCDPOP0(Pjp); \
222
+ JUDYLCODE(*Pjv++ = (Pjp)->jp_Addr;) \
223
+ continue; /* for-loop */ \
224
+ }
225
+
226
+#define JU_BRANCH_COPY_IMMED_ODD(cLevel,Pjp,CopyIndex) \
227
+ if (JU_JPTYPE(Pjp) == cJU_JPIMMED_1_01 + (cLevel) - 2) \
228
+ { \
229
+ CopyIndex(Pleaf, (Word_t) (JU_JPDCDPOP0(Pjp))); \
230
+ Pleaf += (cLevel); /* index size = level */ \
231
+ JUDYLCODE(*Pjv++ = (Pjp)->jp_Addr;) \
232
+ continue; /* for-loop */ \
233
+ }
234
+
235
+// Compress a BranchL into a leaf one index size larger:
236
+//
237
+// Allocate a new leaf, walk the JPs in the old BranchL and pack their contents
238
+// into the new leaf (of type NewJPType), free the old BranchL, and finally
239
+// restart the switch to delete Index from the new leaf. (Note that all
240
+// BranchLs are the same size.) Variables Pjp, Pjpm, Pleaf, digit, and pop1
241
+// are in the context.
242
+
243
+#define JU_BRANCHL_COMPRESS(cLevel,LeafType,MaxPop1,NewJPType, \
244
+ LeafToLeaf,Alloc,ValueArea, \
245
+ CopyImmed,CopyIndex) \
246
+ { \
247
+ LeafType Pleaf; \
248
+ Pjbl_t PjblRaw; \
249
+ Pjbl_t Pjbl; \
250
+ Word_t numJPs; \
251
+ \
252
+ if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
253
+ Pjllnew = P_JLL(PjllnewRaw); \
254
+ Pleaf = (LeafType) Pjllnew; \
255
+ JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
256
+ \
257
+ PjblRaw = (Pjbl_t) (Pjp->jp_Addr); \
258
+ Pjbl = P_JBL(PjblRaw); \
259
+ numJPs = Pjbl->jbl_NumJPs; \
260
+ \
261
+ for (offset = 0; offset < numJPs; ++offset) \
262
+ { \
263
+ CopyImmed(cLevel, (Pjbl->jbl_jp) + offset, CopyIndex); \
264
+ \
265
+ pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS \
266
+ (Pjbl->jbl_jp) + offset, \
267
+ JU_DIGITTOSTATE(Pjbl->jbl_Expanse[offset], \
268
+ cLevel), (Pvoid_t) Pjpm); \
269
+ Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
270
+ JUDYLCODE(Pjv += pop1;) \
271
+ } \
272
+ assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
273
+ JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
274
+ DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
275
+ \
276
+ j__udyFreeJBL(PjblRaw, Pjpm); \
277
+ \
278
+ Pjp->jp_Type = (NewJPType); \
279
+ Pjp->jp_Addr = (Word_t) PjllnewRaw; \
280
+ goto ContinueDelWalk; /* delete from new leaf */ \
281
+ }
282
+
283
+// Overall common code for initial BranchL deletion handling:
284
+//
285
+// Assert that Index is in the branch, then see if the BranchL should be kept
286
+// or else compressed to a leaf. Variables Index, Pjp, and pop1 are in the
287
+// context.
288
+
289
+#define JU_BRANCHL(cLevel,MaxPop1,LeafType,NewJPType, \
290
+ LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
291
+ \
292
+ assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \
293
+ assert(ParentLevel > (cLevel)); \
294
+ \
295
+ pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \
296
+ JU_BRANCH_KEEP(cLevel, MaxPop1, BranchLKeep); \
297
+ assert(pop1 == (MaxPop1)); \
298
+ \
299
+ JU_BRANCHL_COMPRESS(cLevel, LeafType, MaxPop1, NewJPType, \
300
+ LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
301
+
302
+
303
+// END OF MACROS, START OF CASES:
304
+
305
+ case cJU_JPBRANCH_L2:
306
+
307
+ JU_BRANCHL(2, cJU_LEAF2_MAXPOP1, uint16_t *, cJU_JPLEAF2,
308
+ j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA,
309
+ JU_BRANCH_COPY_IMMED_EVEN, ignore);
310
+
311
+ case cJU_JPBRANCH_L3:
312
+
313
+ JU_BRANCHL(3, cJU_LEAF3_MAXPOP1, uint8_t *, cJU_JPLEAF3,
314
+ j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA,
315
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
316
+
317
+#ifdef JU_64BIT
318
+ case cJU_JPBRANCH_L4:
319
+
320
+ JU_BRANCHL(4, cJU_LEAF4_MAXPOP1, uint32_t *, cJU_JPLEAF4,
321
+ j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA,
322
+ JU_BRANCH_COPY_IMMED_EVEN, ignore);
323
+
324
+ case cJU_JPBRANCH_L5:
325
+
326
+ JU_BRANCHL(5, cJU_LEAF5_MAXPOP1, uint8_t *, cJU_JPLEAF5,
327
+ j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA,
328
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
329
+
330
+ case cJU_JPBRANCH_L6:
331
+
332
+ JU_BRANCHL(6, cJU_LEAF6_MAXPOP1, uint8_t *, cJU_JPLEAF6,
333
+ j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA,
334
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
335
+
336
+ case cJU_JPBRANCH_L7:
337
+
338
+ JU_BRANCHL(7, cJU_LEAF7_MAXPOP1, uint8_t *, cJU_JPLEAF7,
339
+ j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA,
340
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
341
+#endif // JU_64BIT
342
+
343
+// A top-level BranchL is different and cannot use JU_BRANCHL(): Dont try to
344
+// compress to a (LEAFW) leaf yet, but leave this for a later deletion
345
+// (hysteresis > 0); and the next JP type depends on the system word size; so
346
+// dont use JU_BRANCH_KEEP():
347
+
348
+ case cJU_JPBRANCH_L:
349
+ {
350
+ Pjbl_t Pjbl;
351
+ Word_t numJPs;
352
+
353
+ level = cJU_ROOTSTATE;
354
+ digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
355
+
356
+ // fall through:
357
+
358
+
359
+// COMMON CODE FOR KEEPING AND DESCENDING THROUGH A BRANCHL:
360
+//
361
+// Come here with level and digit set.
362
+
363
+BranchLKeep:
364
+ Pjbl = P_JBL(Pjp->jp_Addr);
365
+ numJPs = Pjbl->jbl_NumJPs;
366
+ assert(numJPs > 0);
367
+ DBGCODE(parentJPtype = JU_JPTYPE(Pjp);)
368
+
369
+// Search for a match to the digit (valid Index => must find digit):
370
+
371
+ for (offset = 0; (Pjbl->jbl_Expanse[offset]) != digit; ++offset)
372
+ assert(offset < numJPs - 1);
373
+
374
+ Pjp = (Pjbl->jbl_jp) + offset;
375
+
376
+// If not at a (deletable) JPIMMED_*_01, continue the walk (to descend through
377
+// the BranchL):
378
+
379
+ assert(level >= 2);
380
+ if ((JU_JPTYPE(Pjp)) != cJU_JPIMMED_1_01 + level - 2) break;
381
+
382
+// At JPIMMED_*_01: Ensure the index is in the right expanse, then delete the
383
+// Immed from the BranchL:
384
+//
385
+// Note: A BranchL has a fixed size and format regardless of numJPs.
386
+
387
+ assert(JU_JPDCDPOP0(Pjp) == JU_TRIMTODCDSIZE(Index));
388
+
389
+ JU_DELETEINPLACE(Pjbl->jbl_Expanse, numJPs, offset, ignore);
390
+ JU_DELETEINPLACE(Pjbl->jbl_jp, numJPs, offset, ignore);
391
+
392
+ DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse),
393
+ numJPs - 1, 1);)
394
+
395
+// If only one index left in the BranchL, indicate this to the caller:
396
+
397
+ return ((--(Pjbl->jbl_NumJPs) <= 1) ? 2 : 1);
398
+
399
+ } // case cJU_JPBRANCH_L.
400
+
401
+
402
+// ****************************************************************************
403
+// BITMAP BRANCH:
404
+//
405
+// MACROS FOR COMMON CODE:
406
+//
407
+// Note the reuse of common macros here, defined earlier: JU_BRANCH_KEEP(),
408
+// JU_PVALUE*.
409
+//
410
+// Compress a BranchB into a leaf one index size larger:
411
+//
412
+// Allocate a new leaf, walk the JPs in the old BranchB (one bitmap subexpanse
413
+// at a time) and pack their contents into the new leaf (of type NewJPType),
414
+// free the old BranchB, and finally restart the switch to delete Index from
415
+// the new leaf. Variables Pjp, Pjpm, Pleaf, digit, and pop1 are in the
416
+// context.
417
+//
418
+// Note: Its no accident that the interface to JU_BRANCHB_COMPRESS() is
419
+// identical to JU_BRANCHL_COMPRESS(). Only the details differ in how to
420
+// traverse the branchs JPs.
421
+
422
+#define JU_BRANCHB_COMPRESS(cLevel,LeafType,MaxPop1,NewJPType, \
423
+ LeafToLeaf,Alloc,ValueArea, \
424
+ CopyImmed,CopyIndex) \
425
+ { \
426
+ LeafType Pleaf; \
427
+ Pjbb_t PjbbRaw; /* BranchB to compress */ \
428
+ Pjbb_t Pjbb; \
429
+ Word_t subexp; /* current subexpanse number */ \
430
+ BITMAPB_t bitmap; /* portion for this subexpanse */ \
431
+ Pjp_t Pjp2Raw; /* one subexpanses subarray */ \
432
+ Pjp_t Pjp2; \
433
+ \
434
+ if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
435
+ Pjllnew = P_JLL(PjllnewRaw); \
436
+ Pleaf = (LeafType) Pjllnew; \
437
+ JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
438
+ \
439
+ PjbbRaw = (Pjbb_t) (Pjp->jp_Addr); \
440
+ Pjbb = P_JBB(PjbbRaw); \
441
+ \
442
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp) \
443
+ { \
444
+ if ((bitmap = JU_JBB_BITMAP(Pjbb, subexp)) == 0) \
445
+ continue; /* empty subexpanse */ \
446
+ \
447
+ digit = subexp * cJU_BITSPERSUBEXPB; \
448
+ Pjp2Raw = JU_JBB_PJP(Pjbb, subexp); \
449
+ Pjp2 = P_JP(Pjp2Raw); \
450
+ assert(Pjp2 != (Pjp_t) NULL); \
451
+ \
452
+ for (offset = 0; bitmap != 0; bitmap >>= 1, ++digit) \
453
+ { \
454
+ if (! (bitmap & 1)) \
455
+ continue; /* empty sub-subexpanse */ \
456
+ \
457
+ ++offset; /* before any continue */ \
458
+ \
459
+ CopyImmed(cLevel, Pjp2 + offset - 1, CopyIndex); \
460
+ \
461
+ pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS \
462
+ Pjp2 + offset - 1, \
463
+ JU_DIGITTOSTATE(digit, cLevel), \
464
+ (Pvoid_t) Pjpm); \
465
+ Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
466
+ JUDYLCODE(Pjv += pop1;) \
467
+ } \
468
+ j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm); \
469
+ } \
470
+ assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
471
+ JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
472
+ DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
473
+ \
474
+ j__udyFreeJBB(PjbbRaw, Pjpm); \
475
+ \
476
+ Pjp->jp_Type = (NewJPType); \
477
+ Pjp->jp_Addr = (Word_t) PjllnewRaw; \
478
+ goto ContinueDelWalk; /* delete from new leaf */ \
479
+ }
480
+
481
+// Overall common code for initial BranchB deletion handling:
482
+//
483
+// Assert that Index is in the branch, then see if the BranchB should be kept
484
+// or else compressed to a leaf. Variables Index, Pjp, and pop1 are in the
485
+// context.
486
+
487
+#define JU_BRANCHB(cLevel,MaxPop1,LeafType,NewJPType, \
488
+ LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
489
+ \
490
+ assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \
491
+ assert(ParentLevel > (cLevel)); \
492
+ \
493
+ pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \
494
+ JU_BRANCH_KEEP(cLevel, MaxPop1, BranchBKeep); \
495
+ assert(pop1 == (MaxPop1)); \
496
+ \
497
+ JU_BRANCHB_COMPRESS(cLevel, LeafType, MaxPop1, NewJPType, \
498
+ LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
499
+
500
+
501
+// END OF MACROS, START OF CASES:
502
+//
503
+// Note: Its no accident that the macro calls for these cases is nearly
504
+// identical to the code for BranchLs.
505
+
506
+ case cJU_JPBRANCH_B2:
507
+
508
+ JU_BRANCHB(2, cJU_LEAF2_MAXPOP1, uint16_t *, cJU_JPLEAF2,
509
+ j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA,
510
+ JU_BRANCH_COPY_IMMED_EVEN, ignore);
511
+
512
+ case cJU_JPBRANCH_B3:
513
+
514
+ JU_BRANCHB(3, cJU_LEAF3_MAXPOP1, uint8_t *, cJU_JPLEAF3,
515
+ j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA,
516
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
517
+
518
+#ifdef JU_64BIT
519
+ case cJU_JPBRANCH_B4:
520
+
521
+ JU_BRANCHB(4, cJU_LEAF4_MAXPOP1, uint32_t *, cJU_JPLEAF4,
522
+ j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA,
523
+ JU_BRANCH_COPY_IMMED_EVEN, ignore);
524
+
525
+ case cJU_JPBRANCH_B5:
526
+
527
+ JU_BRANCHB(5, cJU_LEAF5_MAXPOP1, uint8_t *, cJU_JPLEAF5,
528
+ j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA,
529
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
530
+
531
+ case cJU_JPBRANCH_B6:
532
+
533
+ JU_BRANCHB(6, cJU_LEAF6_MAXPOP1, uint8_t *, cJU_JPLEAF6,
534
+ j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA,
535
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
536
+
537
+ case cJU_JPBRANCH_B7:
538
+
539
+ JU_BRANCHB(7, cJU_LEAF7_MAXPOP1, uint8_t *, cJU_JPLEAF7,
540
+ j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA,
541
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
542
+#endif // JU_64BIT
543
+
544
+// A top-level BranchB is different and cannot use JU_BRANCHB(): Dont try to
545
+// compress to a (LEAFW) leaf yet, but leave this for a later deletion
546
+// (hysteresis > 0); and the next JP type depends on the system word size; so
547
+// dont use JU_BRANCH_KEEP():
548
+
549
+ case cJU_JPBRANCH_B:
550
+ {
551
+ Pjbb_t Pjbb; // BranchB to modify.
552
+ Word_t subexp; // current subexpanse number.
553
+ Word_t subexp2; // in second-level loop.
554
+ BITMAPB_t bitmap; // portion for this subexpanse.
555
+ BITMAPB_t bitmask; // with digits bit set.
556
+ Pjp_t Pjp2Raw; // one subexpanses subarray.
557
+ Pjp_t Pjp2;
558
+ Word_t numJPs; // in one subexpanse.
559
+
560
+ level = cJU_ROOTSTATE;
561
+ digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
562
+
563
+ // fall through:
564
+
565
+
566
+// COMMON CODE FOR KEEPING AND DESCENDING THROUGH A BRANCHB:
567
+//
568
+// Come here with level and digit set.
569
+
570
+BranchBKeep:
571
+ Pjbb = P_JBB(Pjp->jp_Addr);
572
+ subexp = digit / cJU_BITSPERSUBEXPB;
573
+ bitmap = JU_JBB_BITMAP(Pjbb, subexp);
574
+ bitmask = JU_BITPOSMASKB(digit);
575
+ assert(bitmap & bitmask); // Index valid => digits bit is set.
576
+ DBGCODE(parentJPtype = JU_JPTYPE(Pjp);)
577
+
578
+// Compute digits offset into the bitmap, with a fast method if all bits are
579
+// set:
580
+
581
+ offset = ((bitmap == (cJU_FULLBITMAPB)) ?
582
+ digit % cJU_BITSPERSUBEXPB :
583
+ j__udyCountBitsB(bitmap & JU_MASKLOWEREXC(bitmask)));
584
+
585
+ Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
586
+ Pjp2 = P_JP(Pjp2Raw);
587
+ assert(Pjp2 != (Pjp_t) NULL); // valid subexpanse pointer.
588
+
589
+// If not at a (deletable) JPIMMED_*_01, continue the walk (to descend through
590
+// the BranchB):
591
+
592
+ if (JU_JPTYPE(Pjp2 + offset) != cJU_JPIMMED_1_01 + level - 2)
593
+ {
594
+ Pjp = Pjp2 + offset;
595
+ break;
596
+ }
597
+
598
+// At JPIMMED_*_01: Ensure the index is in the right expanse, then delete the
599
+// Immed from the BranchB:
600
+
601
+ assert(JU_JPDCDPOP0(Pjp2 + offset)
602
+ == JU_TRIMTODCDSIZE(Index));
603
+
604
+// If only one index is left in the subexpanse, free the JP array:
605
+
606
+ if ((numJPs = j__udyCountBitsB(bitmap)) == 1)
607
+ {
608
+ j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ 1, Pjpm);
609
+ JU_JBB_PJP(Pjbb, subexp) = (Pjp_t) NULL;
610
+ }
611
+
612
+// Shrink JP array in-place:
613
+
614
+ else if (JU_BRANCHBJPGROWINPLACE(numJPs - 1))
615
+ {
616
+ assert(numJPs > 0);
617
+ JU_DELETEINPLACE(Pjp2, numJPs, offset, ignore);
618
+ }
619
+
620
+// JP array would end up too large; compress it to a smaller one:
621
+
622
+ else
623
+ {
624
+ Pjp_t PjpnewRaw;
625
+ Pjp_t Pjpnew;
626
+
627
+ if ((PjpnewRaw = j__udyAllocJBBJP(numJPs - 1, Pjpm))
628
+ == (Pjp_t) NULL) return(-1);
629
+ Pjpnew = P_JP(PjpnewRaw);
630
+
631
+ JU_DELETECOPY(Pjpnew, Pjp2, numJPs, offset, ignore);
632
+ j__udyFreeJBBJP(Pjp2Raw, numJPs, Pjpm); // old.
633
+
634
+ JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw;
635
+ }
636
+
637
+// Clear digits bit in the bitmap:
638
+
639
+ JU_JBB_BITMAP(Pjbb, subexp) ^= bitmask;
640
+
641
+// If the current subexpanse alone is still too large for a BranchL (with
642
+// hysteresis = 1), the delete is all done:
643
+
644
+ if (numJPs > cJU_BRANCHLMAXJPS) return(1);
645
+
646
+// Consider shrinking the current BranchB to a BranchL:
647
+//
648
+// Check the numbers of JPs in other subexpanses in the BranchL. Upon reaching
649
+// the critical number of numJPs (which could be right at the start; again,
650
+// with hysteresis = 1), its faster to just watch for any non-empty subexpanse
651
+// than to count bits in each subexpanse. Upon finding too many JPs, give up
652
+// on shrinking the BranchB.
653
+
654
+ for (subexp2 = 0; subexp2 < cJU_NUMSUBEXPB; ++subexp2)
655
+ {
656
+ if (subexp2 == subexp) continue; // skip current subexpanse.
657
+
658
+ if ((numJPs == cJU_BRANCHLMAXJPS) ?
659
+ JU_JBB_BITMAP(Pjbb, subexp2) :
660
+ ((numJPs += j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp2)))
661
+ > cJU_BRANCHLMAXJPS))
662
+ {
663
+ return(1); // too many JPs, cannot shrink.
664
+ }
665
+ }
666
+
667
+// Shrink current BranchB to a BranchL:
668
+//
669
+// Note: In this rare case, ignore the return value, do not pass it to the
670
+// caller, because the deletion is already successfully completed and the
671
+// caller(s) must decrement population counts. The only errors expected from
672
+// this call are JU_ERRNO_NOMEM and JU_ERRNO_OVERRUN, neither of which is worth
673
+// forwarding from this point. See also 4.1, 4.8, and 4.15 of this file.
674
+
675
+ (void) j__udyBranchBToBranchL(Pjp, Pjpm);
676
+ return(1);
677
+
678
+ } // case.
679
+
680
+
681
+// ****************************************************************************
682
+// UNCOMPRESSED BRANCH:
683
+//
684
+// MACROS FOR COMMON CODE:
685
+//
686
+// Note the reuse of common macros here, defined earlier: JU_PVALUE*.
687
+//
688
+// Compress a BranchU into a leaf one index size larger:
689
+//
690
+// Allocate a new leaf, walk the JPs in the old BranchU and pack their contents
691
+// into the new leaf (of type NewJPType), free the old BranchU, and finally
692
+// restart the switch to delete Index from the new leaf. Variables Pjp, Pjpm,
693
+// digit, and pop1 are in the context.
694
+//
695
+// Note: Its no accident that the interface to JU_BRANCHU_COMPRESS() is
696
+// nearly identical to JU_BRANCHL_COMPRESS(); just NullJPType is added. The
697
+// details differ in how to traverse the branchs JPs --
698
+//
699
+// -- and also, what to do upon encountering a cJU_JPIMMED_*_01 JP. In
700
+// BranchLs and BranchBs the JP must be deleted, but in a BranchU its merely
701
+// converted to a null JP, and this is done by other switch cases, so the "keep
702
+// branch" situation is simpler here and JU_BRANCH_KEEP() is not used. Also,
703
+// theres no code to convert a BranchU to a BranchB since counting the JPs in
704
+// a BranchU is (at least presently) expensive, and besides, keeping around a
705
+// BranchU is form of hysteresis.
706
+
707
+#define JU_BRANCHU_COMPRESS(cLevel,LeafType,MaxPop1,NullJPType,NewJPType, \
708
+ LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
709
+ { \
710
+ LeafType Pleaf; \
711
+ Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr); \
712
+ Pjp_t Pjp2 = JU_JBU_PJP0(Pjp); \
713
+ Word_t ldigit; /* larger than uint8_t */ \
714
+ \
715
+ if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
716
+ Pjllnew = P_JLL(PjllnewRaw); \
717
+ Pleaf = (LeafType) Pjllnew; \
718
+ JUDYLCODE(Pjv = ValueArea(Pleaf, MaxPop1);) \
719
+ \
720
+ for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit, ++Pjp2) \
721
+ { \
722
+ /* fast-process common types: */ \
723
+ if (JU_JPTYPE(Pjp2) == (NullJPType)) continue; \
724
+ CopyImmed(cLevel, Pjp2, CopyIndex); \
725
+ \
726
+ pop1 = LeafToLeaf(Pleaf, JU_PVALUEPASS Pjp2, \
727
+ JU_DIGITTOSTATE(ldigit, cLevel), \
728
+ (Pvoid_t) Pjpm); \
729
+ Pleaf = (LeafType) (((Word_t) Pleaf) + ((cLevel) * pop1)); \
730
+ JUDYLCODE(Pjv += pop1;) \
731
+ } \
732
+ assert(((((Word_t) Pleaf) - ((Word_t) Pjllnew)) / (cLevel)) == (MaxPop1)); \
733
+ JUDYLCODE(assert((Pjv - ValueArea(Pjllnew, MaxPop1)) == (MaxPop1));) \
734
+ DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cLevel);) \
735
+ \
736
+ j__udyFreeJBU(PjbuRaw, Pjpm); \
737
+ \
738
+ Pjp->jp_Type = (NewJPType); \
739
+ Pjp->jp_Addr = (Word_t) PjllnewRaw; \
740
+ goto ContinueDelWalk; /* delete from new leaf */ \
741
+ }
742
+
743
+// Overall common code for initial BranchU deletion handling:
744
+//
745
+// Assert that Index is in the branch, then see if a BranchU should be kept or
746
+// else compressed to a leaf. Variables level, Index, Pjp, and pop1 are in the
747
+// context.
748
+//
749
+// Note: BranchU handling differs from BranchL and BranchB as described above.
750
+
751
+#define JU_BRANCHU(cLevel,MaxPop1,LeafType,NullJPType,NewJPType, \
752
+ LeafToLeaf,Alloc,ValueArea,CopyImmed,CopyIndex) \
753
+ \
754
+ assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)); \
755
+ assert(ParentLevel > (cLevel)); \
756
+ DBGCODE(parentJPtype = JU_JPTYPE(Pjp);) \
757
+ \
758
+ pop1 = JU_JPBRANCH_POP0(Pjp, cLevel) + 1; \
759
+ \
760
+ if (pop1 > (MaxPop1)) /* hysteresis = 1 */ \
761
+ { \
762
+ level = (cLevel); \
763
+ Pjp = P_JP(Pjp->jp_Addr) + JU_DIGITATSTATE(Index, cLevel);\
764
+ break; /* descend to next level */ \
765
+ } \
766
+ assert(pop1 == (MaxPop1)); \
767
+ \
768
+ JU_BRANCHU_COMPRESS(cLevel, LeafType, MaxPop1, NullJPType, NewJPType, \
769
+ LeafToLeaf, Alloc, ValueArea, CopyImmed, CopyIndex)
770
+
771
+
772
+// END OF MACROS, START OF CASES:
773
+//
774
+// Note: Its no accident that the macro calls for these cases is nearly
775
+// identical to the code for BranchLs, with the addition of cJU_JPNULL*
776
+// parameters only needed for BranchUs.
777
+
778
+ case cJU_JPBRANCH_U2:
779
+
780
+ JU_BRANCHU(2, cJU_LEAF2_MAXPOP1, uint16_t *,
781
+ cJU_JPNULL1, cJU_JPLEAF2,
782
+ j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA,
783
+ JU_BRANCH_COPY_IMMED_EVEN, ignore);
784
+
785
+ case cJU_JPBRANCH_U3:
786
+
787
+ JU_BRANCHU(3, cJU_LEAF3_MAXPOP1, uint8_t *,
788
+ cJU_JPNULL2, cJU_JPLEAF3,
789
+ j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA,
790
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY3_LONG_TO_PINDEX);
791
+
792
+#ifdef JU_64BIT
793
+ case cJU_JPBRANCH_U4:
794
+
795
+ JU_BRANCHU(4, cJU_LEAF4_MAXPOP1, uint32_t *,
796
+ cJU_JPNULL3, cJU_JPLEAF4,
797
+ j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA,
798
+ JU_BRANCH_COPY_IMMED_EVEN, ignore);
799
+
800
+ case cJU_JPBRANCH_U5:
801
+
802
+ JU_BRANCHU(5, cJU_LEAF5_MAXPOP1, uint8_t *,
803
+ cJU_JPNULL4, cJU_JPLEAF5,
804
+ j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA,
805
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY5_LONG_TO_PINDEX);
806
+
807
+ case cJU_JPBRANCH_U6:
808
+
809
+ JU_BRANCHU(6, cJU_LEAF6_MAXPOP1, uint8_t *,
810
+ cJU_JPNULL5, cJU_JPLEAF6,
811
+ j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA,
812
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY6_LONG_TO_PINDEX);
813
+
814
+ case cJU_JPBRANCH_U7:
815
+
816
+ JU_BRANCHU(7, cJU_LEAF7_MAXPOP1, uint8_t *,
817
+ cJU_JPNULL6, cJU_JPLEAF7,
818
+ j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA,
819
+ JU_BRANCH_COPY_IMMED_ODD, JU_COPY7_LONG_TO_PINDEX);
820
+#endif // JU_64BIT
821
+
822
+// A top-level BranchU is different and cannot use JU_BRANCHU(): Dont try to
823
+// compress to a (LEAFW) leaf yet, but leave this for a later deletion
824
+// (hysteresis > 0); just descend through the BranchU:
825
+
826
+ case cJU_JPBRANCH_U:
827
+
828
+ DBGCODE(parentJPtype = JU_JPTYPE(Pjp);)
829
+
830
+ level = cJU_ROOTSTATE;
831
+ Pjp = P_JP(Pjp->jp_Addr) + JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
832
+ break;
833
+
834
+
835
+// ****************************************************************************
836
+// LINEAR LEAF:
837
+//
838
+// State transitions while deleting an Index, the inverse of the similar table
839
+// that appears in JudyIns.c:
840
+//
841
+// Note: In JudyIns.c this table is not needed and does not appear until the
842
+// Immed handling code; because once a Leaf is reached upon growing the tree,
843
+// the situation remains simpler, but for deleting indexes, the complexity
844
+// arises when leaves must compress to Immeds.
845
+//
846
+// Note: There are other transitions possible too, not shown here, such as to
847
+// a leaf one level higher.
848
+//
849
+// (Yes, this is very terse... Study it and it will make sense.)
850
+// (Note, parts of this diagram are repeated below for quick reference.)
851
+//
852
+// reformat JP here for Judy1 only, from word-1 to word-2
853
+// |
854
+// JUDY1 && JU_64BIT JUDY1 || JU_64BIT |
855
+// V
856
+// (*) Leaf1 [[ => 1_15..08 ] => 1_07 => ... => 1_04 ] => 1_03 => 1_02 => 1_01
857
+// Leaf2 [[ => 2_07..04 ] => 2_03 => 2_02 ] => 2_01
858
+// Leaf3 [[ => 3_05..03 ] => 3_02 ] => 3_01
859
+// JU_64BIT only:
860
+// Leaf4 [[ => 4_03..02 ]] => 4_01
861
+// Leaf5 [[ => 5_03..02 ]] => 5_01
862
+// Leaf6 [[ => 6_02 ]] => 6_01
863
+// Leaf7 [[ => 7_02 ]] => 7_01
864
+//
865
+// (*) For Judy1 & 64-bit, go directly from a LeafB1 to cJU_JPIMMED_1_15; skip
866
+// Leaf1, as described in Judy1.h regarding cJ1_JPLEAF1.
867
+//
868
+// MACROS FOR COMMON CODE:
869
+//
870
+// (De)compress a LeafX into a LeafY one index size (cIS) larger (X+1 = Y):
871
+//
872
+// This is only possible when the current leaf is under a narrow pointer
873
+// ((ParentLevel - 1) > cIS) and its population fits in a higher-level leaf.
874
+// Variables ParentLevel, pop1, PjllnewRaw, Pjllnew, Pjpm, and Index are in the
875
+// context.
876
+//
877
+// Note: Doing an "uplevel" doesnt occur until the old leaf can be compressed
878
+// up one level BEFORE deleting an index; that is, hysteresis = 1.
879
+//
880
+// Note: LeafType, MaxPop1, NewJPType, and Alloc refer to the up-level leaf,
881
+// not the current leaf.
882
+//
883
+// Note: 010327: Fixed bug where the jp_DcdPopO next-uplevel digit (byte)
884
+// above the current Pop0 value was not being cleared. When upleveling, one
885
+// digit in jp_DcdPopO "moves" from being part of the Dcd subfield to the Pop0
886
+// subfield, but since a leaf maxpop1 is known to be <= 1 byte in size, the new
887
+// Pop0 byte should always be zero. This is easy to overlook because
888
+// JU_JPLEAF_POP0() "knows" to only use the LSB of Pop0 (for efficiency) and
889
+// ignore the other bytes... Until someone uses cJU_POP0MASK() instead of
890
+// JU_JPLEAF_POP0(), such as in JudyInsertBranch.c.
891
+//
892
+// TBD: Should JudyInsertBranch.c use JU_JPLEAF_POP0() rather than
893
+// cJU_POP0MASK(), for efficiency? Does it know for sure its a narrow pointer
894
+// under the leaf? Not necessarily.
895
+
896
+#define JU_LEAF_UPLEVEL(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
897
+ Alloc,ValueArea) \
898
+ \
899
+ assert(((ParentLevel - 1) == (cIS)) || (pop1 >= (MaxPop1))); \
900
+ \
901
+ if (((ParentLevel - 1) > (cIS)) /* under narrow pointer */ \
902
+ && (pop1 == (MaxPop1))) /* hysteresis = 1 */ \
903
+ { \
904
+ Word_t D_cdP0; \
905
+ if ((PjllnewRaw = Alloc(MaxPop1, Pjpm)) == 0) return(-1); \
906
+ Pjllnew = P_JLL(PjllnewRaw); \
907
+ JUDYLCODE(Pjv = ValueArea((LeafType) Pjllnew, MaxPop1);) \
908
+ \
909
+ (void) LeafToLeaf((LeafType) Pjllnew, JU_PVALUEPASS Pjp, \
910
+ Index & cJU_DCDMASK(cIS), /* TBD, Doug says */ \
911
+ (Pvoid_t) Pjpm); \
912
+ DBGCODE(JudyCheckSorted(Pjllnew, MaxPop1, cIS + 1);) \
913
+ \
914
+ D_cdP0 = (~cJU_MASKATSTATE((cIS) + 1)) & JU_JPDCDPOP0(Pjp); \
915
+ JU_JPSETADT(Pjp, (Word_t)PjllnewRaw, D_cdP0, NewJPType); \
916
+ goto ContinueDelWalk; /* delete from new leaf */ \
917
+ }
918
+
919
+
920
+// For Leaf3, only support JU_LEAF_UPLEVEL on a 64-bit system, and for Leaf7,
921
+// there is no JU_LEAF_UPLEVEL:
922
+//
923
+// Note: Theres no way here to go from Leaf3 [Leaf7] to LEAFW on a 32-bit
924
+// [64-bit] system. Thats handled in the main code, because its different in
925
+// that a JPM is involved.
926
+
927
+#ifndef JU_64BIT // 32-bit.
928
+#define JU_LEAF_UPLEVEL64(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
929
+ Alloc,ValueArea) // null.
930
+#else
931
+#define JU_LEAF_UPLEVEL64(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
932
+ Alloc,ValueArea) \
933
+ JU_LEAF_UPLEVEL (cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
934
+ Alloc,ValueArea)
935
+#define JU_LEAF_UPLEVEL_NONE(cIS,LeafType,MaxPop1,NewJPType,LeafToLeaf, \
936
+ Alloc,ValueArea) // null.
937
+#endif
938
+
939
+// Compress a Leaf* with pop1 = 2, or a JPIMMED_*_02, into a JPIMMED_*_01:
940
+//
941
+// Copy whichever Index is NOT being deleted (and assert that the other one is
942
+// found; Index must be valid). This requires special handling of the Index
943
+// bytes (and value area). Variables Pjp, Index, offset, and Pleaf are in the
944
+// context, offset is modified to the undeleted Index, and Pjp is modified
945
+// including jp_Addr.
946
+
947
+
948
+#define JU_TOIMMED_01_EVEN(cIS,ignore1,ignore2) \
949
+{ \
950
+ Word_t D_cdP0; \
951
+ Word_t A_ddr = 0; \
952
+ uint8_t T_ype = JU_JPTYPE(Pjp); \
953
+ offset = (Pleaf[0] == JU_LEASTBYTES(Index, cIS)); /* undeleted Ind */ \
954
+ assert(Pleaf[offset ? 0 : 1] == JU_LEASTBYTES(Index, cIS)); \
955
+ D_cdP0 = (Index & cJU_DCDMASK(cIS)) | Pleaf[offset]; \
956
+JUDYLCODE(A_ddr = Pjv[offset];) \
957
+ JU_JPSETADT(Pjp, A_ddr, D_cdP0, T_ype); \
958
+}
959
+
960
+#define JU_TOIMMED_01_ODD(cIS,SearchLeaf,CopyPIndex) \
961
+ { \
962
+ Word_t D_cdP0; \
963
+ Word_t A_ddr = 0; \
964
+ uint8_t T_ype = JU_JPTYPE(Pjp); \
965
+ \
966
+ offset = SearchLeaf(Pleaf, 2, Index); \
967
+ assert(offset >= 0); /* Index must be valid */ \
968
+ CopyPIndex(D_cdP0, & (Pleaf[offset ? 0 : cIS])); \
969
+ D_cdP0 |= Index & cJU_DCDMASK(cIS); \
970
+ JUDYLCODE(A_ddr = Pjv[offset ? 0 : 1];) \
971
+ JU_JPSETADT(Pjp, A_ddr, D_cdP0, T_ype); \
972
+ }
973
+
974
+
975
+// Compress a Leaf* into a JPIMMED_*_0[2+]:
976
+//
977
+// This occurs as soon as its possible, with hysteresis = 0. Variables pop1,
978
+// Pleaf, offset, and Pjpm are in the context.
979
+//
980
+// TBD: Explain why hysteresis = 0 here, rather than > 0. Probably because
981
+// the insert code assumes if the population is small enough, an Immed is used,
982
+// not a leaf.
983
+//
984
+// The differences between Judy1 and JudyL with respect to value area handling
985
+// are just too large for completely common code between them... Oh well, some
986
+// big ifdefs follow.
987
+
988
+#ifdef JUDY1
989
+
990
+#define JU_LEAF_TOIMMED(cIS,LeafType,MaxPop1,BaseJPType,ignore1,\
991
+ ignore2,ignore3,ignore4, \
992
+ DeleteCopy,FreeLeaf) \
993
+ \
994
+ assert(pop1 > (MaxPop1)); \
995
+ \
996
+ if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
997
+ { \
998
+ Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
999
+ DeleteCopy((LeafType) (Pjp->jp_1Index), Pleaf, pop1, offset, cIS); \
1000
+ DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_1Index), pop1-1, cIS);) \
1001
+ Pjp->jp_Type = (BaseJPType) - 1 + (MaxPop1) - 1; \
1002
+ FreeLeaf(PjllRaw, pop1, Pjpm); \
1003
+ return(1); \
1004
+ }
1005
+
1006
+#else // JUDYL
1007
+
1008
+// Pjv is also in the context.
1009
+
1010
+#define JU_LEAF_TOIMMED(cIS,LeafType,MaxPop1,BaseJPType,ignore1,\
1011
+ ignore2,ignore3,ignore4, \
1012
+ DeleteCopy,FreeLeaf) \
1013
+ \
1014
+ assert(pop1 > (MaxPop1)); \
1015
+ \
1016
+ if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
1017
+ { \
1018
+ Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
1019
+ Pjv_t PjvnewRaw; \
1020
+ Pjv_t Pjvnew; \
1021
+ \
1022
+ if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm)) \
1023
+ == (Pjv_t) NULL) return(-1); \
1024
+ JUDYLCODE(Pjvnew = P_JV(PjvnewRaw);) \
1025
+ \
1026
+ DeleteCopy((LeafType) (Pjp->jp_LIndex), Pleaf, pop1, offset, cIS); \
1027
+ JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, cIS); \
1028
+ DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_LIndex), pop1-1, cIS);) \
1029
+ FreeLeaf(PjllRaw, pop1, Pjpm); \
1030
+ Pjp->jp_Addr = (Word_t) PjvnewRaw; \
1031
+ Pjp->jp_Type = (BaseJPType) - 2 + (MaxPop1); \
1032
+ return(1); \
1033
+ }
1034
+
1035
+// A complicating factor for JudyL & 32-bit is that Leaf2..3, and for JudyL &
1036
+// 64-bit Leaf 4..7, go directly to an Immed*_01, where the value is stored in
1037
+// jp_Addr and not in a separate LeafV. For efficiency, use the following
1038
+// macro in cases where it can apply; it is rigged to do the right thing.
1039
+// Unfortunately, this requires the calling code to "know" the transition table
1040
+// and call the right macro.
1041
+//
1042
+// This variant compresses a Leaf* with pop1 = 2 into a JPIMMED_*_01:
1043
+
1044
+#define JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1045
+ ToImmed,SearchLeaf,CopyPIndex, \
1046
+ DeleteCopy,FreeLeaf) \
1047
+ \
1048
+ assert(pop1 > (MaxPop1)); \
1049
+ \
1050
+ if ((pop1 - 1) == (MaxPop1)) /* hysteresis = 0 */ \
1051
+ { \
1052
+ Pjll_t PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
1053
+ ToImmed(cIS, SearchLeaf, CopyPIndex); \
1054
+ FreeLeaf(PjllRaw, pop1, Pjpm); \
1055
+ Pjp->jp_Type = (Immed01JPType); \
1056
+ return(1); \
1057
+ }
1058
+#endif // JUDYL
1059
+
1060
+// See comments above about these:
1061
+//
1062
+// Note: Here "23" means index size 2 or 3, and "47" means 4..7.
1063
+
1064
+#if (defined(JUDY1) || defined(JU_64BIT))
1065
+#define JU_LEAF_TOIMMED_23(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1066
+ ToImmed,SearchLeaf,CopyPIndex, \
1067
+ DeleteCopy,FreeLeaf) \
1068
+ JU_LEAF_TOIMMED( cIS,LeafType,MaxPop1,BaseJPType,ignore1, \
1069
+ ignore2,ignore3,ignore4, \
1070
+ DeleteCopy,FreeLeaf)
1071
+#else // JUDYL && 32-bit
1072
+#define JU_LEAF_TOIMMED_23(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1073
+ ToImmed,SearchLeaf,CopyPIndex, \
1074
+ DeleteCopy,FreeLeaf) \
1075
+ JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1076
+ ToImmed,SearchLeaf,CopyPIndex, \
1077
+ DeleteCopy,FreeLeaf)
1078
+#endif
1079
+
1080
+#ifdef JU_64BIT
1081
+#ifdef JUDY1
1082
+#define JU_LEAF_TOIMMED_47(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1083
+ ToImmed,SearchLeaf,CopyPIndex, \
1084
+ DeleteCopy,FreeLeaf) \
1085
+ JU_LEAF_TOIMMED( cIS,LeafType,MaxPop1,BaseJPType,ignore1, \
1086
+ ignore2,ignore3,ignore4, \
1087
+ DeleteCopy,FreeLeaf)
1088
+#else // JUDYL && 64-bit
1089
+#define JU_LEAF_TOIMMED_47(cIS,LeafType,MaxPop1,BaseJPType,Immed01JPType, \
1090
+ ToImmed,SearchLeaf,CopyPIndex, \
1091
+ DeleteCopy,FreeLeaf) \
1092
+ JU_LEAF_TOIMMED_01(cIS,LeafType,MaxPop1,ignore,Immed01JPType, \
1093
+ ToImmed,SearchLeaf,CopyPIndex, \
1094
+ DeleteCopy,FreeLeaf)
1095
+#endif // JUDYL
1096
+#endif // JU_64BIT
1097
+
1098
+// Compress a Leaf* in place:
1099
+//
1100
+// Here hysteresis = 0 (no memory is wasted). Variables pop1, Pleaf, and
1101
+// offset, and for JudyL, Pjv, are in the context.
1102
+
1103
+#ifdef JUDY1
1104
+#define JU_LEAF_INPLACE(cIS,GrowInPlace,DeleteInPlace) \
1105
+ if (GrowInPlace(pop1 - 1)) /* hysteresis = 0 */ \
1106
+ { \
1107
+ DeleteInPlace(Pleaf, pop1, offset, cIS); \
1108
+ DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \
1109
+ return(1); \
1110
+ }
1111
+#else
1112
+#define JU_LEAF_INPLACE(cIS,GrowInPlace,DeleteInPlace) \
1113
+ if (GrowInPlace(pop1 - 1)) /* hysteresis = 0 */ \
1114
+ { \
1115
+ DeleteInPlace(Pleaf, pop1, offset, cIS); \
1116
+/**/ JU_DELETEINPLACE(Pjv, pop1, offset, ignore); \
1117
+ DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \
1118
+ return(1); \
1119
+ }
1120
+#endif
1121
+
1122
+// Compress a Leaf* into a smaller memory object of the same JP type:
1123
+//
1124
+// Variables PjllnewRaw, Pjllnew, Pleafpop1, Pjpm, PleafRaw, Pleaf, and offset
1125
+// are in the context.
1126
+
1127
+#ifdef JUDY1
1128
+
1129
+#define JU_LEAF_SHRINK(cIS,LeafType,DeleteCopy,Alloc,FreeLeaf,ValueArea) \
1130
+ if ((PjllnewRaw = Alloc(pop1 - 1, Pjpm)) == 0) return(-1); \
1131
+ Pjllnew = P_JLL(PjllnewRaw); \
1132
+ DeleteCopy((LeafType) Pjllnew, Pleaf, pop1, offset, cIS); \
1133
+ DBGCODE(JudyCheckSorted(Pjllnew, pop1 - 1, cIS);) \
1134
+ FreeLeaf(PleafRaw, pop1, Pjpm); \
1135
+ Pjp->jp_Addr = (Word_t) PjllnewRaw; \
1136
+ return(1)
1137
+
1138
+#else // JUDYL
1139
+
1140
+#define JU_LEAF_SHRINK(cIS,LeafType,DeleteCopy,Alloc,FreeLeaf,ValueArea) \
1141
+ { \
1142
+/**/ Pjv_t Pjvnew; \
1143
+ \
1144
+ if ((PjllnewRaw = Alloc(pop1 - 1, Pjpm)) == 0) return(-1); \
1145
+ Pjllnew = P_JLL(PjllnewRaw); \
1146
+/**/ Pjvnew = ValueArea(Pjllnew, pop1 - 1); \
1147
+ DeleteCopy((LeafType) Pjllnew, Pleaf, pop1, offset, cIS); \
1148
+/**/ JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, cIS); \
1149
+ DBGCODE(JudyCheckSorted(Pjllnew, pop1 - 1, cIS);) \
1150
+ FreeLeaf(PleafRaw, pop1, Pjpm); \
1151
+ Pjp->jp_Addr = (Word_t) PjllnewRaw; \
1152
+ return(1); \
1153
+ }
1154
+#endif // JUDYL
1155
+
1156
+// Overall common code for Leaf* deletion handling:
1157
+//
1158
+// See if the leaf can be:
1159
+// - (de)compressed to one a level higher (JU_LEAF_UPLEVEL()), or if not,
1160
+// - compressed to an Immediate JP (JU_LEAF_TOIMMED()), or if not,
1161
+// - shrunk in place (JU_LEAF_INPLACE()), or if none of those, then
1162
+// - shrink the leaf to a smaller chunk of memory (JU_LEAF_SHRINK()).
1163
+//
1164
+// Variables Pjp, pop1, Index, and offset are in the context.
1165
+// The *Up parameters refer to a leaf one level up, if there is any.
1166
+
1167
+#define JU_LEAF(cIS, \
1168
+ UpLevel, \
1169
+ LeafTypeUp,MaxPop1Up,LeafJPTypeUp,LeafToLeaf, \
1170
+ AllocUp,ValueAreaUp, \
1171
+ LeafToImmed,ToImmed,CopyPIndex, \
1172
+ LeafType,ImmedMaxPop1,ImmedBaseJPType,Immed01JPType, \
1173
+ SearchLeaf,GrowInPlace,DeleteInPlace,DeleteCopy, \
1174
+ Alloc,FreeLeaf,ValueArea) \
1175
+ { \
1176
+ Pjll_t PleafRaw; \
1177
+ LeafType Pleaf; \
1178
+ \
1179
+ assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, cIS)); \
1180
+ assert(ParentLevel > (cIS)); \
1181
+ \
1182
+ PleafRaw = (Pjll_t) (Pjp->jp_Addr); \
1183
+ Pleaf = (LeafType) P_JLL(PleafRaw); \
1184
+ pop1 = JU_JPLEAF_POP0(Pjp) + 1; \
1185
+ \
1186
+ UpLevel(cIS, LeafTypeUp, MaxPop1Up, LeafJPTypeUp, \
1187
+ LeafToLeaf, AllocUp, ValueAreaUp); \
1188
+ \
1189
+ offset = SearchLeaf(Pleaf, pop1, Index); \
1190
+ assert(offset >= 0); /* Index must be valid */ \
1191
+ JUDYLCODE(Pjv = ValueArea(Pleaf, pop1);) \
1192
+ \
1193
+ LeafToImmed(cIS, LeafType, ImmedMaxPop1, \
1194
+ ImmedBaseJPType, Immed01JPType, \
1195
+ ToImmed, SearchLeaf, CopyPIndex, \
1196
+ DeleteCopy, FreeLeaf); \
1197
+ \
1198
+ JU_LEAF_INPLACE(cIS, GrowInPlace, DeleteInPlace); \
1199
+ \
1200
+ JU_LEAF_SHRINK(cIS, LeafType, DeleteCopy, Alloc, FreeLeaf, \
1201
+ ValueArea); \
1202
+ }
1203
+
1204
+// END OF MACROS, START OF CASES:
1205
+//
1206
+// (*) Leaf1 [[ => 1_15..08 ] => 1_07 => ... => 1_04 ] => 1_03 => 1_02 => 1_01
1207
+
1208
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
1209
+ case cJU_JPLEAF1:
1210
+
1211
+ JU_LEAF(1,
1212
+ JU_LEAF_UPLEVEL, uint16_t *, cJU_LEAF2_MAXPOP1, cJU_JPLEAF2,
1213
+ j__udyLeaf1ToLeaf2, j__udyAllocJLL2, JL_LEAF2VALUEAREA,
1214
+ JU_LEAF_TOIMMED, ignore, ignore,
1215
+ uint8_t *, cJU_IMMED1_MAXPOP1,
1216
+ cJU_JPIMMED_1_02, cJU_JPIMMED_1_01, j__udySearchLeaf1,
1217
+ JU_LEAF1GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1218
+ j__udyAllocJLL1, j__udyFreeJLL1, JL_LEAF1VALUEAREA);
1219
+#endif
1220
+
1221
+// A complicating factor is that for JudyL & 32-bit, a Leaf2 must go directly
1222
+// to an Immed 2_01 and a Leaf3 must go directly to an Immed 3_01:
1223
+//
1224
+// Leaf2 [[ => 2_07..04 ] => 2_03 => 2_02 ] => 2_01
1225
+// Leaf3 [[ => 3_05..03 ] => 3_02 ] => 3_01
1226
+//
1227
+// Hence use JU_LEAF_TOIMMED_23 instead of JU_LEAF_TOIMMED in the cases below,
1228
+// and also the parameters ToImmed and, for odd index sizes, CopyPIndex, are
1229
+// required.
1230
+
1231
+ case cJU_JPLEAF2:
1232
+
1233
+ JU_LEAF(2,
1234
+ JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF3_MAXPOP1, cJU_JPLEAF3,
1235
+ j__udyLeaf2ToLeaf3, j__udyAllocJLL3, JL_LEAF3VALUEAREA,
1236
+ JU_LEAF_TOIMMED_23, JU_TOIMMED_01_EVEN, ignore,
1237
+ uint16_t *, cJU_IMMED2_MAXPOP1,
1238
+ cJU_JPIMMED_2_02, cJU_JPIMMED_2_01, j__udySearchLeaf2,
1239
+ JU_LEAF2GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1240
+ j__udyAllocJLL2, j__udyFreeJLL2, JL_LEAF2VALUEAREA);
1241
+
1242
+// On 32-bit there is no transition to "uplevel" for a Leaf3, so use
1243
+// JU_LEAF_UPLEVEL64 instead of JU_LEAF_UPLEVEL:
1244
+
1245
+ case cJU_JPLEAF3:
1246
+
1247
+ JU_LEAF(3,
1248
+ JU_LEAF_UPLEVEL64, uint32_t *, cJU_LEAF4_MAXPOP1,
1249
+ cJU_JPLEAF4,
1250
+ j__udyLeaf3ToLeaf4, j__udyAllocJLL4, JL_LEAF4VALUEAREA,
1251
+ JU_LEAF_TOIMMED_23,
1252
+ JU_TOIMMED_01_ODD, JU_COPY3_PINDEX_TO_LONG,
1253
+ uint8_t *, cJU_IMMED3_MAXPOP1,
1254
+ cJU_JPIMMED_3_02, cJU_JPIMMED_3_01, j__udySearchLeaf3,
1255
+ JU_LEAF3GROWINPLACE, JU_DELETEINPLACE_ODD,
1256
+ JU_DELETECOPY_ODD,
1257
+ j__udyAllocJLL3, j__udyFreeJLL3, JL_LEAF3VALUEAREA);
1258
+
1259
+#ifdef JU_64BIT
1260
+
1261
+// A complicating factor is that for JudyL & 64-bit, a Leaf[4-7] must go
1262
+// directly to an Immed [4-7]_01:
1263
+//
1264
+// Leaf4 [[ => 4_03..02 ]] => 4_01
1265
+// Leaf5 [[ => 5_03..02 ]] => 5_01
1266
+// Leaf6 [[ => 6_02 ]] => 6_01
1267
+// Leaf7 [[ => 7_02 ]] => 7_01
1268
+//
1269
+// Hence use JU_LEAF_TOIMMED_47 instead of JU_LEAF_TOIMMED in the cases below.
1270
+
1271
+ case cJU_JPLEAF4:
1272
+
1273
+ JU_LEAF(4,
1274
+ JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF5_MAXPOP1, cJU_JPLEAF5,
1275
+ j__udyLeaf4ToLeaf5, j__udyAllocJLL5, JL_LEAF5VALUEAREA,
1276
+ JU_LEAF_TOIMMED_47, JU_TOIMMED_01_EVEN, ignore,
1277
+ uint32_t *, cJU_IMMED4_MAXPOP1,
1278
+ cJ1_JPIMMED_4_02, cJU_JPIMMED_4_01, j__udySearchLeaf4,
1279
+ JU_LEAF4GROWINPLACE, JU_DELETEINPLACE, JU_DELETECOPY,
1280
+ j__udyAllocJLL4, j__udyFreeJLL4, JL_LEAF4VALUEAREA);
1281
+
1282
+ case cJU_JPLEAF5:
1283
+
1284
+ JU_LEAF(5,
1285
+ JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF6_MAXPOP1, cJU_JPLEAF6,
1286
+ j__udyLeaf5ToLeaf6, j__udyAllocJLL6, JL_LEAF6VALUEAREA,
1287
+ JU_LEAF_TOIMMED_47,
1288
+ JU_TOIMMED_01_ODD, JU_COPY5_PINDEX_TO_LONG,
1289
+ uint8_t *, cJU_IMMED5_MAXPOP1,
1290
+ cJ1_JPIMMED_5_02, cJU_JPIMMED_5_01, j__udySearchLeaf5,
1291
+ JU_LEAF5GROWINPLACE, JU_DELETEINPLACE_ODD,
1292
+ JU_DELETECOPY_ODD,
1293
+ j__udyAllocJLL5, j__udyFreeJLL5, JL_LEAF5VALUEAREA);
1294
+
1295
+ case cJU_JPLEAF6:
1296
+
1297
+ JU_LEAF(6,
1298
+ JU_LEAF_UPLEVEL, uint8_t *, cJU_LEAF7_MAXPOP1, cJU_JPLEAF7,
1299
+ j__udyLeaf6ToLeaf7, j__udyAllocJLL7, JL_LEAF7VALUEAREA,
1300
+ JU_LEAF_TOIMMED_47,
1301
+ JU_TOIMMED_01_ODD, JU_COPY6_PINDEX_TO_LONG,
1302
+ uint8_t *, cJU_IMMED6_MAXPOP1,
1303
+ cJ1_JPIMMED_6_02, cJU_JPIMMED_6_01, j__udySearchLeaf6,
1304
+ JU_LEAF6GROWINPLACE, JU_DELETEINPLACE_ODD,
1305
+ JU_DELETECOPY_ODD,
1306
+ j__udyAllocJLL6, j__udyFreeJLL6, JL_LEAF6VALUEAREA);
1307
+
1308
+// There is no transition to "uplevel" for a Leaf7, so use JU_LEAF_UPLEVEL_NONE
1309
+// instead of JU_LEAF_UPLEVEL, and ignore all of the parameters to that macro:
1310
+
1311
+ case cJU_JPLEAF7:
1312
+
1313
+ JU_LEAF(7,
1314
+ JU_LEAF_UPLEVEL_NONE, ignore1, ignore2, ignore3, ignore4,
1315
+ ignore5, ignore6,
1316
+ JU_LEAF_TOIMMED_47,
1317
+ JU_TOIMMED_01_ODD, JU_COPY7_PINDEX_TO_LONG,
1318
+ uint8_t *, cJU_IMMED7_MAXPOP1,
1319
+ cJ1_JPIMMED_7_02, cJU_JPIMMED_7_01, j__udySearchLeaf7,
1320
+ JU_LEAF7GROWINPLACE, JU_DELETEINPLACE_ODD,
1321
+ JU_DELETECOPY_ODD,
1322
+ j__udyAllocJLL7, j__udyFreeJLL7, JL_LEAF7VALUEAREA);
1323
+#endif // JU_64BIT
1324
+
1325
+
1326
+// ****************************************************************************
1327
+// BITMAP LEAF:
1328
+
1329
+ case cJU_JPLEAF_B1:
1330
+ {
1331
+#ifdef JUDYL
1332
+ Pjv_t PjvnewRaw; // new value area.
1333
+ Pjv_t Pjvnew;
1334
+ Word_t subexp; // 1 of 8 subexpanses in bitmap.
1335
+ Pjlb_t Pjlb; // pointer to bitmap part of the leaf.
1336
+ BITMAPL_t bitmap; // for one subexpanse.
1337
+ BITMAPL_t bitmask; // bit set for Indexs digit.
1338
+#endif
1339
+ assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, 1));
1340
+ assert(ParentLevel > 1);
1341
+ // valid Index:
1342
+ assert(JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index));
1343
+
1344
+ pop1 = JU_JPLEAF_POP0(Pjp) + 1;
1345
+
1346
+// Like a Leaf1, see if its under a narrow pointer and can become a Leaf2
1347
+// (hysteresis = 1):
1348
+
1349
+ JU_LEAF_UPLEVEL(1, uint16_t *, cJU_LEAF2_MAXPOP1, cJU_JPLEAF2,
1350
+ j__udyLeaf1ToLeaf2, j__udyAllocJLL2,
1351
+ JL_LEAF2VALUEAREA);
1352
+
1353
+#if (defined(JUDY1) && defined(JU_64BIT))
1354
+
1355
+// Handle the unusual special case, on Judy1 64-bit only, where a LeafB1 goes
1356
+// directly to a JPIMMED_1_15; as described in comments in Judy1.h and
1357
+// JudyIns.c. Copy 1-byte indexes from old LeafB1 to the Immed:
1358
+
1359
+ if ((pop1 - 1) == cJU_IMMED1_MAXPOP1) // hysteresis = 0.
1360
+ {
1361
+ Pjlb_t PjlbRaw; // bitmap in old leaf.
1362
+ Pjlb_t Pjlb;
1363
+ uint8_t * Pleafnew; // JPIMMED as a pointer.
1364
+ Word_t ldigit; // larger than uint8_t.
1365
+
1366
+ PjlbRaw = (Pjlb_t) (Pjp->jp_Addr);
1367
+ Pjlb = P_JLB(PjlbRaw);
1368
+ Pleafnew = Pjp->jp_1Index;
1369
+
1370
+ JU_BITMAPCLEARL(Pjlb, Index); // unset Indexs bit.
1371
+
1372
+// TBD: This is very slow, there must be a better way:
1373
+
1374
+ for (ldigit = 0; ldigit < cJU_BRANCHUNUMJPS; ++ldigit)
1375
+ {
1376
+ if (JU_BITMAPTESTL(Pjlb, ldigit))
1377
+ {
1378
+ *Pleafnew++ = ldigit;
1379
+ assert(Pleafnew - (Pjp->jp_1Index)
1380
+ <= cJU_IMMED1_MAXPOP1);
1381
+ }
1382
+ }
1383
+
1384
+ DBGCODE(JudyCheckSorted((Pjll_t) (Pjp->jp_1Index),
1385
+ cJU_IMMED1_MAXPOP1, 1);)
1386
+ j__udyFreeJLB1(PjlbRaw, Pjpm);
1387
+
1388
+ Pjp->jp_Type = cJ1_JPIMMED_1_15;
1389
+ return(1);
1390
+ }
1391
+
1392
+#else // (JUDYL || (! JU_64BIT))
1393
+
1394
+// Compress LeafB1 to a Leaf1:
1395
+//
1396
+// Note: 4.37 of this file contained alternate code for Judy1 only that simply
1397
+// cleared the bit and allowed the LeafB1 to go below cJU_LEAF1_MAXPOP1. This
1398
+// was the ONLY case where a malloc failure was not fatal; however, it violated
1399
+// the critical assumption that the tree is always kept in least-compressed
1400
+// form.
1401
+
1402
+ if (pop1 == cJU_LEAF1_MAXPOP1) // hysteresis = 1.
1403
+ {
1404
+ if (j__udyLeafB1ToLeaf1(Pjp, Pjpm) == -1) return(-1);
1405
+ goto ContinueDelWalk; // delete Index in new Leaf1.
1406
+ }
1407
+#endif // (JUDYL || (! JU_64BIT))
1408
+
1409
+#ifdef JUDY1
1410
+ // unset Indexs bit:
1411
+
1412
+ JU_BITMAPCLEARL(P_JLB(Pjp->jp_Addr), Index);
1413
+#else // JUDYL
1414
+
1415
+// This is very different from Judy1 because of the need to manage the value
1416
+// area:
1417
+//
1418
+// Get last byte to decode from Index, and pointer to bitmap leaf:
1419
+
1420
+ digit = JU_DIGITATSTATE(Index, 1);
1421
+ Pjlb = P_JLB(Pjp->jp_Addr);
1422
+
1423
+// Prepare additional values:
1424
+
1425
+ subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse.
1426
+ bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexps 32-bit map.
1427
+ PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values.
1428
+ Pjv = P_JV(PjvRaw);
1429
+ bitmask = JU_BITPOSMASKL(digit); // mask for Index.
1430
+
1431
+ assert(bitmap & bitmask); // Index must be valid.
1432
+
1433
+ if (bitmap == cJU_FULLBITMAPL) // full bitmap, take shortcut:
1434
+ {
1435
+ pop1 = cJU_BITSPERSUBEXPL;
1436
+ offset = digit % cJU_BITSPERSUBEXPL;
1437
+ }
1438
+ else // compute subexpanse pop1 and value area offset:
1439
+ {
1440
+ pop1 = j__udyCountBitsL(bitmap);
1441
+ offset = j__udyCountBitsL(bitmap & (bitmask - 1));
1442
+ }
1443
+
1444
+// Handle solitary Index remaining in subexpanse:
1445
+
1446
+ if (pop1 == 1)
1447
+ {
1448
+ j__udyLFreeJV(PjvRaw, 1, Pjpm);
1449
+
1450
+ JL_JLB_PVALUE(Pjlb, subexp) = (Pjv_t) NULL;
1451
+ JU_JLB_BITMAP(Pjlb, subexp) = 0;
1452
+
1453
+ return(1);
1454
+ }
1455
+
1456
+// Shrink value area in place or move to a smaller value area:
1457
+
1458
+ if (JL_LEAFVGROWINPLACE(pop1 - 1)) // hysteresis = 0.
1459
+ {
1460
+ JU_DELETEINPLACE(Pjv, pop1, offset, ignore);
1461
+ }
1462
+ else
1463
+ {
1464
+ if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm))
1465
+ == (Pjv_t) NULL) return(-1);
1466
+ Pjvnew = P_JV(PjvnewRaw);
1467
+
1468
+ JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore);
1469
+ j__udyLFreeJV(PjvRaw, pop1, Pjpm);
1470
+ JL_JLB_PVALUE(Pjlb, subexp) = (Pjv_t) PjvnewRaw;
1471
+ }
1472
+
1473
+ JU_JLB_BITMAP(Pjlb, subexp) ^= bitmask; // clear Indexs bit.
1474
+
1475
+#endif // JUDYL
1476
+
1477
+ return(1);
1478
+
1479
+ } // case.
1480
+
1481
+
1482
+#ifdef JUDY1
1483
+
1484
+// ****************************************************************************
1485
+// FULL POPULATION LEAF:
1486
+//
1487
+// Convert to a LeafB1 and delete the index. Hysteresis = 0; none is possible.
1488
+//
1489
+// Note: Earlier the second assertion below said, "== 2", but in fact the
1490
+// parent could be at a higher level if a fullpop is under a narrow pointer.
1491
+
1492
+ case cJ1_JPFULLPOPU1:
1493
+ {
1494
+ Pjlb_t PjlbRaw;
1495
+ Pjlb_t Pjlb;
1496
+ Word_t subexp;
1497
+
1498
+ assert(! JU_DCDNOTMATCHINDEX(Index, Pjp, 2));
1499
+ assert(ParentLevel > 1); // see above.
1500
+
1501
+ if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL)
1502
+ return(-1);
1503
+ Pjlb = P_JLB(PjlbRaw);
1504
+
1505
+// Fully populate the leaf, then unset Indexs bit:
1506
+
1507
+ for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
1508
+ JU_JLB_BITMAP(Pjlb, subexp) = cJU_FULLBITMAPL;
1509
+
1510
+ JU_BITMAPCLEARL(Pjlb, Index);
1511
+
1512
+ Pjp->jp_Addr = (Word_t) PjlbRaw;
1513
+ Pjp->jp_Type = cJU_JPLEAF_B1;
1514
+
1515
+ return(1);
1516
+ }
1517
+#endif // JUDY1
1518
+
1519
+
1520
+// ****************************************************************************
1521
+// IMMEDIATE JP:
1522
+//
1523
+// If theres just the one Index in the Immed, convert the JP to a JPNULL*
1524
+// (should only happen in a BranchU); otherwise delete the Index from the
1525
+// Immed. See the state transitions table elsewhere in this file for a summary
1526
+// of which Immed types must be handled. Hysteresis = 0; none is possible with
1527
+// Immeds.
1528
+//
1529
+// MACROS FOR COMMON CODE:
1530
+//
1531
+// Single Index remains in cJU_JPIMMED_*_01; convert JP to null:
1532
+//
1533
+// Variables Pjp and parentJPtype are in the context.
1534
+//
1535
+// Note: cJU_JPIMMED_*_01 should only be encountered in BranchUs, not in
1536
+// BranchLs or BranchBs (where its improper to merely modify the JP to be a
1537
+// null JP); that is, BranchL and BranchB code should have already handled
1538
+// any cJU_JPIMMED_*_01 by different means.
1539
+
1540
+#define JU_IMMED_01(NewJPType,ParentJPType) \
1541
+ \
1542
+ assert(parentJPtype == (ParentJPType)); \
1543
+ assert(JU_JPDCDPOP0(Pjp) == JU_TRIMTODCDSIZE(Index)); \
1544
+ JU_JPSETADT(Pjp, 0, 0, NewJPType); \
1545
+ return(1)
1546
+
1547
+// Convert cJ*_JPIMMED_*_02 to cJU_JPIMMED_*_01:
1548
+//
1549
+// Move the undeleted Index, whichever does not match the least bytes of Index,
1550
+// from undecoded-bytes-only (in jp_1Index or jp_LIndex as appropriate) to
1551
+// jp_DcdPopO (full-field). Pjp, Index, and offset are in the context.
1552
+
1553
+#define JU_IMMED_02(cIS,LeafType,NewJPType) \
1554
+ { \
1555
+ LeafType Pleaf; \
1556
+ \
1557
+ assert((ParentLevel - 1) == (cIS)); \
1558
+ JUDY1CODE(Pleaf = (LeafType) (Pjp->jp_1Index);) \
1559
+ JUDYLCODE(Pleaf = (LeafType) (Pjp->jp_LIndex);) \
1560
+ JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1561
+ JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1562
+ JU_TOIMMED_01_EVEN(cIS, ignore, ignore); \
1563
+ JUDYLCODE(j__udyLFreeJV(PjvRaw, 2, Pjpm);) \
1564
+ Pjp->jp_Type = (NewJPType); \
1565
+ return(1); \
1566
+ }
1567
+
1568
+#if (defined(JUDY1) || defined(JU_64BIT))
1569
+
1570
+// Variation for "odd" cJ*_JPIMMED_*_02 JP types, which are very different from
1571
+// "even" types because they use leaf search code and odd-copy macros:
1572
+//
1573
+// Note: JudyL 32-bit has no "odd" JPIMMED_*_02 types.
1574
+
1575
+#define JU_IMMED_02_ODD(cIS,NewJPType,SearchLeaf,CopyPIndex) \
1576
+ { \
1577
+ uint8_t * Pleaf; \
1578
+ \
1579
+ assert((ParentLevel - 1) == (cIS)); \
1580
+ JUDY1CODE(Pleaf = (uint8_t *) (Pjp->jp_1Index);) \
1581
+ JUDYLCODE(Pleaf = (uint8_t *) (Pjp->jp_LIndex);) \
1582
+ JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1583
+ JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1584
+ JU_TOIMMED_01_ODD(cIS, SearchLeaf, CopyPIndex); \
1585
+ JUDYLCODE(j__udyLFreeJV(PjvRaw, 2, Pjpm);) \
1586
+ Pjp->jp_Type = (NewJPType); \
1587
+ return(1); \
1588
+ }
1589
+#endif // (JUDY1 || JU_64BIT)
1590
+
1591
+// Core code for deleting one Index (and for JudyL, its value area) from a
1592
+// larger Immed:
1593
+//
1594
+// Variables Pleaf, pop1, and offset are in the context.
1595
+
1596
+#ifdef JUDY1
1597
+#define JU_IMMED_DEL(cIS,DeleteInPlace) \
1598
+ DeleteInPlace(Pleaf, pop1, offset, cIS); \
1599
+ DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);)
1600
+
1601
+#else // JUDYL
1602
+
1603
+// For JudyL the value area might need to be shrunk:
1604
+
1605
+#define JU_IMMED_DEL(cIS,DeleteInPlace) \
1606
+ \
1607
+ if (JL_LEAFVGROWINPLACE(pop1 - 1)) /* hysteresis = 0 */ \
1608
+ { \
1609
+ DeleteInPlace( Pleaf, pop1, offset, cIS); \
1610
+ JU_DELETEINPLACE(Pjv, pop1, offset, ignore); \
1611
+ DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \
1612
+ } \
1613
+ else \
1614
+ { \
1615
+ Pjv_t PjvnewRaw; \
1616
+ Pjv_t Pjvnew; \
1617
+ \
1618
+ if ((PjvnewRaw = j__udyLAllocJV(pop1 - 1, Pjpm)) \
1619
+ == (Pjv_t) NULL) return(-1); \
1620
+ Pjvnew = P_JV(PjvnewRaw); \
1621
+ \
1622
+ DeleteInPlace(Pleaf, pop1, offset, cIS); \
1623
+ JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore); \
1624
+ DBGCODE(JudyCheckSorted(Pleaf, pop1 - 1, cIS);) \
1625
+ j__udyLFreeJV(PjvRaw, pop1, Pjpm); \
1626
+ \
1627
+ (Pjp->jp_Addr) = (Word_t) PjvnewRaw; \
1628
+ }
1629
+#endif // JUDYL
1630
+
1631
+// Delete one Index from a larger Immed where no restructuring is required:
1632
+//
1633
+// Variables pop1, Pjp, offset, and Index are in the context.
1634
+
1635
+#define JU_IMMED(cIS,LeafType,BaseJPType,SearchLeaf,DeleteInPlace) \
1636
+ { \
1637
+ LeafType Pleaf; \
1638
+ \
1639
+ assert((ParentLevel - 1) == (cIS)); \
1640
+ JUDY1CODE(Pleaf = (LeafType) (Pjp->jp_1Index);) \
1641
+ JUDYLCODE(Pleaf = (LeafType) (Pjp->jp_LIndex);) \
1642
+ JUDYLCODE(PjvRaw = (Pjv_t) (Pjp->jp_Addr);) \
1643
+ JUDYLCODE(Pjv = P_JV(PjvRaw);) \
1644
+ pop1 = (JU_JPTYPE(Pjp)) - (BaseJPType) + 2; \
1645
+ offset = SearchLeaf(Pleaf, pop1, Index); \
1646
+ assert(offset >= 0); /* Index must be valid */ \
1647
+ \
1648
+ JU_IMMED_DEL(cIS, DeleteInPlace); \
1649
+ --(Pjp->jp_Type); \
1650
+ return(1); \
1651
+ }
1652
+
1653
+
1654
+// END OF MACROS, START OF CASES:
1655
+
1656
+// Single Index remains in Immed; convert JP to null:
1657
+
1658
+ case cJU_JPIMMED_1_01: JU_IMMED_01(cJU_JPNULL1, cJU_JPBRANCH_U2);
1659
+ case cJU_JPIMMED_2_01: JU_IMMED_01(cJU_JPNULL2, cJU_JPBRANCH_U3);
1660
+#ifndef JU_64BIT
1661
+ case cJU_JPIMMED_3_01: JU_IMMED_01(cJU_JPNULL3, cJU_JPBRANCH_U);
1662
+#else
1663
+ case cJU_JPIMMED_3_01: JU_IMMED_01(cJU_JPNULL3, cJU_JPBRANCH_U4);
1664
+ case cJU_JPIMMED_4_01: JU_IMMED_01(cJU_JPNULL4, cJU_JPBRANCH_U5);
1665
+ case cJU_JPIMMED_5_01: JU_IMMED_01(cJU_JPNULL5, cJU_JPBRANCH_U6);
1666
+ case cJU_JPIMMED_6_01: JU_IMMED_01(cJU_JPNULL6, cJU_JPBRANCH_U7);
1667
+ case cJU_JPIMMED_7_01: JU_IMMED_01(cJU_JPNULL7, cJU_JPBRANCH_U);
1668
+#endif
1669
+
1670
+// Multiple Indexes remain in the Immed JP; delete the specified Index:
1671
+
1672
+ case cJU_JPIMMED_1_02:
1673
+
1674
+ JU_IMMED_02(1, uint8_t *, cJU_JPIMMED_1_01);
1675
+
1676
+ case cJU_JPIMMED_1_03:
1677
+#if (defined(JUDY1) || defined(JU_64BIT))
1678
+ case cJU_JPIMMED_1_04:
1679
+ case cJU_JPIMMED_1_05:
1680
+ case cJU_JPIMMED_1_06:
1681
+ case cJU_JPIMMED_1_07:
1682
+#endif
1683
+#if (defined(JUDY1) && defined(JU_64BIT))
1684
+ case cJ1_JPIMMED_1_08:
1685
+ case cJ1_JPIMMED_1_09:
1686
+ case cJ1_JPIMMED_1_10:
1687
+ case cJ1_JPIMMED_1_11:
1688
+ case cJ1_JPIMMED_1_12:
1689
+ case cJ1_JPIMMED_1_13:
1690
+ case cJ1_JPIMMED_1_14:
1691
+ case cJ1_JPIMMED_1_15:
1692
+#endif
1693
+ JU_IMMED(1, uint8_t *, cJU_JPIMMED_1_02,
1694
+ j__udySearchLeaf1, JU_DELETEINPLACE);
1695
+
1696
+#if (defined(JUDY1) || defined(JU_64BIT))
1697
+ case cJU_JPIMMED_2_02:
1698
+
1699
+ JU_IMMED_02(2, uint16_t *, cJU_JPIMMED_2_01);
1700
+
1701
+ case cJU_JPIMMED_2_03:
1702
+#endif
1703
+#if (defined(JUDY1) && defined(JU_64BIT))
1704
+ case cJ1_JPIMMED_2_04:
1705
+ case cJ1_JPIMMED_2_05:
1706
+ case cJ1_JPIMMED_2_06:
1707
+ case cJ1_JPIMMED_2_07:
1708
+#endif
1709
+#if (defined(JUDY1) || defined(JU_64BIT))
1710
+ JU_IMMED(2, uint16_t *, cJU_JPIMMED_2_02,
1711
+ j__udySearchLeaf2, JU_DELETEINPLACE);
1712
+
1713
+ case cJU_JPIMMED_3_02:
1714
+
1715
+ JU_IMMED_02_ODD(3, cJU_JPIMMED_3_01,
1716
+ j__udySearchLeaf3, JU_COPY3_PINDEX_TO_LONG);
1717
+
1718
+#endif
1719
+
1720
+#if (defined(JUDY1) && defined(JU_64BIT))
1721
+ case cJ1_JPIMMED_3_03:
1722
+ case cJ1_JPIMMED_3_04:
1723
+ case cJ1_JPIMMED_3_05:
1724
+
1725
+ JU_IMMED(3, uint8_t *, cJU_JPIMMED_3_02,
1726
+ j__udySearchLeaf3, JU_DELETEINPLACE_ODD);
1727
+
1728
+ case cJ1_JPIMMED_4_02:
1729
+
1730
+ JU_IMMED_02(4, uint32_t *, cJU_JPIMMED_4_01);
1731
+
1732
+ case cJ1_JPIMMED_4_03:
1733
+
1734
+ JU_IMMED(4, uint32_t *, cJ1_JPIMMED_4_02,
1735
+ j__udySearchLeaf4, JU_DELETEINPLACE);
1736
+
1737
+ case cJ1_JPIMMED_5_02:
1738
+
1739
+ JU_IMMED_02_ODD(5, cJU_JPIMMED_5_01,
1740
+ j__udySearchLeaf5, JU_COPY5_PINDEX_TO_LONG);
1741
+
1742
+ case cJ1_JPIMMED_5_03:
1743
+
1744
+ JU_IMMED(5, uint8_t *, cJ1_JPIMMED_5_02,
1745
+ j__udySearchLeaf5, JU_DELETEINPLACE_ODD);
1746
+
1747
+ case cJ1_JPIMMED_6_02:
1748
+
1749
+ JU_IMMED_02_ODD(6, cJU_JPIMMED_6_01,
1750
+ j__udySearchLeaf6, JU_COPY6_PINDEX_TO_LONG);
1751
+
1752
+ case cJ1_JPIMMED_7_02:
1753
+
1754
+ JU_IMMED_02_ODD(7, cJU_JPIMMED_7_01,
1755
+ j__udySearchLeaf7, JU_COPY7_PINDEX_TO_LONG);
1756
+
1757
+#endif // (JUDY1 && JU_64BIT)
1758
+
1759
+
1760
+// ****************************************************************************
1761
+// INVALID JP TYPE:
1762
+
1763
+ default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); return(-1);
1764
+
1765
+ } // switch
1766
+
1767
+
1768
+// PROCESS JP -- RECURSIVELY:
1769
+//
1770
+// For non-Immed JP types, if successful, post-decrement the population count
1771
+// at this level, or collapse a BranchL if necessary by copying the remaining
1772
+// JP in the BranchL to the parent (hysteresis = 0), which implicitly creates a
1773
+// narrow pointer if there was not already one in the hierarchy.
1774
+
1775
+ assert(level);
1776
+ retcode = j__udyDelWalk(Pjp, Index, level, Pjpm);
1777
+ assert(retcode != 0); // should never happen.
1778
+
1779
+ if ((JU_JPTYPE(Pjp)) < cJU_JPIMMED_1_01) // not an Immed.
1780
+ {
1781
+ switch (retcode)
1782
+ {
1783
+ case 1:
1784
+ {
1785
+ jp_t JP = *Pjp;
1786
+ Word_t DcdP0;
1787
+
1788
+ DcdP0 = JU_JPDCDPOP0(Pjp) - 1; // decrement count.
1789
+ JU_JPSETADT(Pjp, JP.jp_Addr, DcdP0, JU_JPTYPE(&JP));
1790
+ break;
1791
+ }
1792
+ case 2: // collapse BranchL to single JP; see above:
1793
+ {
1794
+ Pjbl_t PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
1795
+ Pjbl_t Pjbl = P_JBL(PjblRaw);
1796
+
1797
+ *Pjp = Pjbl->jbl_jp[0];
1798
+ j__udyFreeJBL(PjblRaw, Pjpm);
1799
+ retcode = 1;
1800
+ }
1801
+ }
1802
+ }
1803
+
1804
+ return(retcode);
1805
+
1806
+} // j__udyDelWalk()
1807
+
1808
+
1809
+// ****************************************************************************
1810
+// J U D Y 1 U N S E T
1811
+// J U D Y L D E L
1812
+//
1813
+// Main entry point. See the manual entry for details.
1814
+
1815
+#ifdef JUDY1
1816
+FUNCTION int Judy1Unset
1817
+#else
1818
+FUNCTION int JudyLDel
1819
+#endif
1820
+ (
1821
+ PPvoid_t PPArray, // in which to delete.
1822
+ Word_t Index, // to delete.
1823
+ PJError_t PJError // optional, for returning error info.
1824
+ )
1825
+{
1826
+ Word_t pop1; // population of leaf.
1827
+ int offset; // at which to delete Index.
1828
+ JUDY1CODE(int retcode;) // return code from Judy1Test().
1829
+JUDYLCODE(PPvoid_t PPvalue;) // pointer from JudyLGet().
1830
+
1831
+
1832
+// CHECK FOR NULL ARRAY POINTER (error by caller):
1833
+
1834
+ if (PPArray == (PPvoid_t) NULL)
1835
+ {
1836
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
1837
+ return(JERRI);
1838
+ }
1839
+
1840
+
1841
+// CHECK IF INDEX IS INVALID:
1842
+//
1843
+// If so, theres nothing to do. This saves a lot of time. Pass through
1844
+// PJError, if any, from the "get" function.
1845
+
1846
+#ifdef JUDY1
1847
+ if ((retcode = Judy1Test(*PPArray, Index, PJError)) == JERRI)
1848
+ return (JERRI);
1849
+
1850
+ if (retcode == 0) return(0);
1851
+#else
1852
+ if ((PPvalue = JudyLGet(*PPArray, Index, PJError)) == PPJERR)
1853
+ return (JERRI);
1854
+
1855
+ if (PPvalue == (PPvoid_t) NULL) return(0);
1856
+#endif
1857
+
1858
+
1859
+// ****************************************************************************
1860
+// PROCESS TOP LEVEL (LEAFW) BRANCHES AND LEAVES:
1861
+
1862
+// ****************************************************************************
1863
+// LEAFW LEAF, OTHER SIZE:
1864
+//
1865
+// Shrink or convert the leaf as necessary. Hysteresis = 0; none is possible.
1866
+
1867
+ if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
1868
+ {
1869
+ JUDYLCODE(Pjv_t Pjv;) // current value area.
1870
+ JUDYLCODE(Pjv_t Pjvnew;) // value area in new leaf.
1871
+ Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
1872
+ Pjlw_t Pjlwnew; // replacement leaf.
1873
+ pop1 = Pjlw[0] + 1; // first word of leaf is pop0.
1874
+
1875
+// Delete single (last) Index from array:
1876
+
1877
+ if (pop1 == 1)
1878
+ {
1879
+ j__udyFreeJLW(Pjlw, /* pop1 = */ 1, (Pjpm_t) NULL);
1880
+ *PPArray = (Pvoid_t) NULL;
1881
+ return(1);
1882
+ }
1883
+
1884
+// Locate Index in compressible leaf:
1885
+
1886
+ offset = j__udySearchLeafW(Pjlw + 1, pop1, Index);
1887
+ assert(offset >= 0); // Index must be valid.
1888
+
1889
+ JUDYLCODE(Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1);)
1890
+
1891
+// Delete Index in-place:
1892
+//
1893
+// Note: "Grow in place from pop1 - 1" is the logical inverse of, "shrink in
1894
+// place from pop1." Also, Pjlw points to the count word, so skip that for
1895
+// doing the deletion.
1896
+
1897
+ if (JU_LEAFWGROWINPLACE(pop1 - 1))
1898
+ {
1899
+ JU_DELETEINPLACE(Pjlw + 1, pop1, offset, ignore);
1900
+#ifdef JUDYL // also delete from value area:
1901
+ JU_DELETEINPLACE(Pjv, pop1, offset, ignore);
1902
+#endif
1903
+ DBGCODE(JudyCheckSorted((Pjll_t) (Pjlw + 1), pop1 - 1,
1904
+ cJU_ROOTSTATE);)
1905
+ --(Pjlw[0]); // decrement population.
1906
+ DBGCODE(JudyCheckPop(*PPArray);)
1907
+ return(1);
1908
+ }
1909
+
1910
+// Allocate new leaf for use in either case below:
1911
+
1912
+ Pjlwnew = j__udyAllocJLW(pop1 - 1);
1913
+ JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI);
1914
+
1915
+// Shrink to smaller LEAFW:
1916
+//
1917
+// Note: Skip the first word = pop0 in each leaf.
1918
+
1919
+ Pjlwnew[0] = (pop1 - 1) - 1;
1920
+ JU_DELETECOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, ignore);
1921
+
1922
+#ifdef JUDYL // also delete from value area:
1923
+ Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 - 1);
1924
+ JU_DELETECOPY(Pjvnew, Pjv, pop1, offset, ignore);
1925
+#endif
1926
+ DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 - 1, cJU_ROOTSTATE);)
1927
+
1928
+ j__udyFreeJLW(Pjlw, pop1, (Pjpm_t) NULL);
1929
+
1930
+//// *PPArray = (Pvoid_t) Pjlwnew | cJU_LEAFW);
1931
+ *PPArray = (Pvoid_t) Pjlwnew;
1932
+ DBGCODE(JudyCheckPop(*PPArray);)
1933
+ return(1);
1934
+
1935
+ }
1936
+ else
1937
+
1938
+
1939
+// ****************************************************************************
1940
+// JRP BRANCH:
1941
+//
1942
+// Traverse through the JPM to do the deletion unless the population is small
1943
+// enough to convert immediately to a LEAFW.
1944
+
1945
+ {
1946
+ Pjpm_t Pjpm;
1947
+ Pjp_t Pjp; // top-level JP to process.
1948
+ Word_t digit; // in a branch.
1949
+ JUDYLCODE(Pjv_t Pjv;) // to value area.
1950
+ Pjlw_t Pjlwnew; // replacement leaf.
1951
+ DBGCODE(Pjlw_t Pjlwnew_orig;)
1952
+
1953
+ Pjpm = P_JPM(*PPArray); // top object in array (tree).
1954
+ Pjp = &(Pjpm->jpm_JP); // next object (first branch or leaf).
1955
+
1956
+ assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L)
1957
+ || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B)
1958
+ || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U));
1959
+
1960
+// WALK THE TREE
1961
+//
1962
+// Note: Recursive code in j__udyDelWalk() knows how to collapse a lower-level
1963
+// BranchL containing a single JP into the parent JP as a narrow pointer, but
1964
+// the code here cant do that for a top-level BranchL. The result can be
1965
+// PArray -> JPM -> BranchL containing a single JP. This situation is
1966
+// unavoidable because a JPM cannot contain a narrow pointer; the BranchL is
1967
+// required in order to hold the top digit decoded, and it does not collapse to
1968
+// a LEAFW until the population is low enough.
1969
+//
1970
+// TBD: Should we add a topdigit field to JPMs so they can hold narrow
1971
+// pointers?
1972
+
1973
+ if (j__udyDelWalk(Pjp, Index, cJU_ROOTSTATE, Pjpm) == -1)
1974
+ {
1975
+ JU_COPY_ERRNO(PJError, Pjpm);
1976
+ return(JERRI);
1977
+ }
1978
+
1979
+ --(Pjpm->jpm_Pop0); // success; decrement total population.
1980
+
1981
+ if ((Pjpm->jpm_Pop0 + 1) != cJU_LEAFW_MAXPOP1)
1982
+ {
1983
+ DBGCODE(JudyCheckPop(*PPArray);)
1984
+ return(1);
1985
+ }
1986
+
1987
+// COMPRESS A BRANCH[LBU] TO A LEAFW:
1988
+//
1989
+ Pjlwnew = j__udyAllocJLW(cJU_LEAFW_MAXPOP1);
1990
+ JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI);
1991
+
1992
+// Plug leaf into root pointer and set population count:
1993
+
1994
+//// *PPArray = (Pvoid_t) ((Word_t) Pjlwnew | cJU_LEAFW);
1995
+ *PPArray = (Pvoid_t) Pjlwnew;
1996
+#ifdef JUDYL // prepare value area:
1997
+ Pjv = JL_LEAFWVALUEAREA(Pjlwnew, cJU_LEAFW_MAXPOP1);
1998
+#endif
1999
+ *Pjlwnew++ = cJU_LEAFW_MAXPOP1 - 1; // set pop0.
2000
+ DBGCODE(Pjlwnew_orig = Pjlwnew;)
2001
+
2002
+ switch (JU_JPTYPE(Pjp))
2003
+ {
2004
+
2005
+// JPBRANCH_L: Copy each JPs indexes to the new LEAFW and free the old
2006
+// branch:
2007
+
2008
+ case cJU_JPBRANCH_L:
2009
+ {
2010
+ Pjbl_t PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
2011
+ Pjbl_t Pjbl = P_JBL(PjblRaw);
2012
+
2013
+ for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
2014
+ {
2015
+ pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2016
+ (Pjbl->jbl_jp) + offset,
2017
+ JU_DIGITTOSTATE(Pjbl->jbl_Expanse[offset],
2018
+ cJU_BYTESPERWORD),
2019
+ (Pvoid_t) Pjpm);
2020
+ Pjlwnew += pop1; // advance through indexes.
2021
+ JUDYLCODE(Pjv += pop1;) // advance through values.
2022
+ }
2023
+ j__udyFreeJBL(PjblRaw, Pjpm);
2024
+
2025
+ assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1);
2026
+ break; // delete Index from new LEAFW.
2027
+ }
2028
+
2029
+// JPBRANCH_B: Copy each JPs indexes to the new LEAFW and free the old
2030
+// branch, including each JP subarray:
2031
+
2032
+ case cJU_JPBRANCH_B:
2033
+ {
2034
+ Pjbb_t PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
2035
+ Pjbb_t Pjbb = P_JBB(PjbbRaw);
2036
+ Word_t subexp; // current subexpanse number.
2037
+ BITMAPB_t bitmap; // portion for this subexpanse.
2038
+ Pjp_t Pjp2Raw; // one subexpanses subarray.
2039
+ Pjp_t Pjp2;
2040
+
2041
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
2042
+ {
2043
+ if ((bitmap = JU_JBB_BITMAP(Pjbb, subexp)) == 0)
2044
+ continue; // skip empty subexpanse.
2045
+
2046
+ digit = subexp * cJU_BITSPERSUBEXPB;
2047
+ Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
2048
+ Pjp2 = P_JP(Pjp2Raw);
2049
+ assert(Pjp2 != (Pjp_t) NULL);
2050
+
2051
+// Walk through bits for all possible sub-subexpanses (digits); increment
2052
+// offset for each populated subexpanse; until no more set bits:
2053
+
2054
+ for (offset = 0; bitmap != 0; bitmap >>= 1, ++digit)
2055
+ {
2056
+ if (! (bitmap & 1)) // skip empty sub-subexpanse.
2057
+ continue;
2058
+
2059
+ pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2060
+ Pjp2 + offset,
2061
+ JU_DIGITTOSTATE(digit, cJU_BYTESPERWORD),
2062
+ (Pvoid_t) Pjpm);
2063
+ Pjlwnew += pop1; // advance through indexes.
2064
+ JUDYLCODE(Pjv += pop1;) // advance through values.
2065
+ ++offset;
2066
+ }
2067
+ j__udyFreeJBBJP(Pjp2Raw, /* pop1 = */ offset, Pjpm);
2068
+ }
2069
+ j__udyFreeJBB(PjbbRaw, Pjpm);
2070
+
2071
+ assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1);
2072
+ break; // delete Index from new LEAFW.
2073
+
2074
+ } // case cJU_JPBRANCH_B.
2075
+
2076
+
2077
+// JPBRANCH_U: Copy each JPs indexes to the new LEAFW and free the old
2078
+// branch:
2079
+
2080
+ case cJU_JPBRANCH_U:
2081
+ {
2082
+ Pjbu_t PjbuRaw = (Pjbu_t) (Pjp->jp_Addr);
2083
+ Pjbu_t Pjbu = P_JBU(PjbuRaw);
2084
+ Word_t ldigit; // larger than uint8_t.
2085
+
2086
+ for (Pjp = Pjbu->jbu_jp, ldigit = 0;
2087
+ ldigit < cJU_BRANCHUNUMJPS;
2088
+ ++Pjp, ++ldigit)
2089
+ {
2090
+
2091
+// Shortcuts, to save a little time for possibly big branches:
2092
+
2093
+ if ((JU_JPTYPE(Pjp)) == cJU_JPNULLMAX) // skip null JP.
2094
+ continue;
2095
+
2096
+// TBD: Should the following shortcut also be used in BranchL and BranchB
2097
+// code?
2098
+
2099
+#ifndef JU_64BIT
2100
+ if ((JU_JPTYPE(Pjp)) == cJU_JPIMMED_3_01)
2101
+#else
2102
+ if ((JU_JPTYPE(Pjp)) == cJU_JPIMMED_7_01)
2103
+#endif
2104
+ { // single Immed:
2105
+ *Pjlwnew++ = JU_DIGITTOSTATE(ldigit, cJU_BYTESPERWORD)
2106
+ | JU_JPDCDPOP0(Pjp); // rebuild Index.
2107
+#ifdef JUDYL
2108
+ *Pjv++ = Pjp->jp_Addr; // copy value area.
2109
+#endif
2110
+ continue;
2111
+ }
2112
+
2113
+ pop1 = j__udyLeafM1ToLeafW(Pjlwnew, JU_PVALUEPASS
2114
+ Pjp, JU_DIGITTOSTATE(ldigit, cJU_BYTESPERWORD),
2115
+ (Pvoid_t) Pjpm);
2116
+ Pjlwnew += pop1; // advance through indexes.
2117
+ JUDYLCODE(Pjv += pop1;) // advance through values.
2118
+ }
2119
+ j__udyFreeJBU(PjbuRaw, Pjpm);
2120
+
2121
+ assert(Pjlwnew == Pjlwnew_orig + cJU_LEAFW_MAXPOP1);
2122
+ break; // delete Index from new LEAFW.
2123
+
2124
+ } // case cJU_JPBRANCH_U.
2125
+
2126
+
2127
+// INVALID JP TYPE in jpm_t struct
2128
+
2129
+ default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
2130
+ return(JERRI);
2131
+
2132
+ } // end switch on sub-JP type.
2133
+
2134
+ DBGCODE(JudyCheckSorted((Pjll_t) Pjlwnew_orig, cJU_LEAFW_MAXPOP1,
2135
+ cJU_ROOTSTATE);)
2136
+
2137
+// FREE JPM (no longer needed):
2138
+
2139
+ j__udyFreeJPM(Pjpm, (Pjpm_t) NULL);
2140
+ DBGCODE(JudyCheckPop(*PPArray);)
2141
+ return(1);
2142
+
2143
+ }
2144
+ /*NOTREACHED*/
2145
+
2146
+} // Judy1Unset() / JudyLDel()
libnetdata/libjudy/src/JudyL/JudyLFirst.c
new
+213
@@ -0,0 +1,213 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.12 $ $Source: /judy/src/JudyCommon/JudyFirst.c $
19
+//
20
+// Judy*First[Empty]() and Judy*Last[Empty]() routines for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// These are inclusive versions of Judy*Next[Empty]() and Judy*Prev[Empty]().
24
+
25
+#if (! (defined(JUDY1) || defined(JUDYL)))
26
+#error: One of -DJUDY1 or -DJUDYL must be specified.
27
+#endif
28
+
29
+#ifdef JUDY1
30
+#include "Judy1.h"
31
+#else
32
+#include "JudyL.h"
33
+#endif
34
+
35
+
36
+// ****************************************************************************
37
+// J U D Y 1 F I R S T
38
+// J U D Y L F I R S T
39
+//
40
+// See the manual entry for details.
41
+
42
+#ifdef JUDY1
43
+FUNCTION int Judy1First
44
+#else
45
+FUNCTION PPvoid_t JudyLFirst
46
+#endif
47
+ (
48
+ Pcvoid_t PArray, // Judy array to search.
49
+ Word_t * PIndex, // starting point and result.
50
+ PJError_t PJError // optional, for returning error info.
51
+ )
52
+{
53
+ if (PIndex == (PWord_t) NULL) // caller error:
54
+ {
55
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
56
+ JUDY1CODE(return(JERRI );)
57
+ JUDYLCODE(return(PPJERR);)
58
+ }
59
+
60
+#ifdef JUDY1
61
+ switch (Judy1Test(PArray, *PIndex, PJError))
62
+ {
63
+ case 1: return(1); // found *PIndex itself.
64
+ case 0: return(Judy1Next(PArray, PIndex, PJError));
65
+ default: return(JERRI);
66
+ }
67
+#else
68
+ {
69
+ PPvoid_t PValue;
70
+
71
+ if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
72
+ return(PPJERR);
73
+
74
+ if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
75
+
76
+ return(JudyLNext(PArray, PIndex, PJError));
77
+ }
78
+#endif
79
+
80
+} // Judy1First() / JudyLFirst()
81
+
82
+
83
+// ****************************************************************************
84
+// J U D Y 1 L A S T
85
+// J U D Y L L A S T
86
+//
87
+// See the manual entry for details.
88
+
89
+#ifdef JUDY1
90
+FUNCTION int Judy1Last(
91
+#else
92
+FUNCTION PPvoid_t JudyLLast(
93
+#endif
94
+ Pcvoid_t PArray, // Judy array to search.
95
+ Word_t * PIndex, // starting point and result.
96
+ PJError_t PJError) // optional, for returning error info.
97
+{
98
+ if (PIndex == (PWord_t) NULL)
99
+ {
100
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
101
+ JUDY1CODE(return(JERRI );)
102
+ JUDYLCODE(return(PPJERR);)
103
+ }
104
+
105
+#ifdef JUDY1
106
+ switch (Judy1Test(PArray, *PIndex, PJError))
107
+ {
108
+ case 1: return(1); // found *PIndex itself.
109
+ case 0: return(Judy1Prev(PArray, PIndex, PJError));
110
+ default: return(JERRI);
111
+ }
112
+#else
113
+ {
114
+ PPvoid_t PValue;
115
+
116
+ if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
117
+ return(PPJERR);
118
+
119
+ if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
120
+
121
+ return(JudyLPrev(PArray, PIndex, PJError));
122
+ }
123
+#endif
124
+
125
+} // Judy1Last() / JudyLLast()
126
+
127
+
128
+// ****************************************************************************
129
+// J U D Y 1 F I R S T E M P T Y
130
+// J U D Y L F I R S T E M P T Y
131
+//
132
+// See the manual entry for details.
133
+
134
+#ifdef JUDY1
135
+FUNCTION int Judy1FirstEmpty(
136
+#else
137
+FUNCTION int JudyLFirstEmpty(
138
+#endif
139
+ Pcvoid_t PArray, // Judy array to search.
140
+ Word_t * PIndex, // starting point and result.
141
+ PJError_t PJError) // optional, for returning error info.
142
+{
143
+ if (PIndex == (PWord_t) NULL) // caller error:
144
+ {
145
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
146
+ return(JERRI);
147
+ }
148
+
149
+#ifdef JUDY1
150
+ switch (Judy1Test(PArray, *PIndex, PJError))
151
+ {
152
+ case 0: return(1); // found *PIndex itself.
153
+ case 1: return(Judy1NextEmpty(PArray, PIndex, PJError));
154
+ default: return(JERRI);
155
+ }
156
+#else
157
+ {
158
+ PPvoid_t PValue;
159
+
160
+ if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
161
+ return(JERRI);
162
+
163
+ if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
164
+
165
+ return(JudyLNextEmpty(PArray, PIndex, PJError));
166
+ }
167
+#endif
168
+
169
+} // Judy1FirstEmpty() / JudyLFirstEmpty()
170
+
171
+
172
+// ****************************************************************************
173
+// J U D Y 1 L A S T E M P T Y
174
+// J U D Y L L A S T E M P T Y
175
+//
176
+// See the manual entry for details.
177
+
178
+#ifdef JUDY1
179
+FUNCTION int Judy1LastEmpty(
180
+#else
181
+FUNCTION int JudyLLastEmpty(
182
+#endif
183
+ Pcvoid_t PArray, // Judy array to search.
184
+ Word_t * PIndex, // starting point and result.
185
+ PJError_t PJError) // optional, for returning error info.
186
+{
187
+ if (PIndex == (PWord_t) NULL)
188
+ {
189
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
190
+ return(JERRI);
191
+ }
192
+
193
+#ifdef JUDY1
194
+ switch (Judy1Test(PArray, *PIndex, PJError))
195
+ {
196
+ case 0: return(1); // found *PIndex itself.
197
+ case 1: return(Judy1PrevEmpty(PArray, PIndex, PJError));
198
+ default: return(JERRI);
199
+ }
200
+#else
201
+ {
202
+ PPvoid_t PValue;
203
+
204
+ if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
205
+ return(JERRI);
206
+
207
+ if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
208
+
209
+ return(JudyLPrevEmpty(PArray, PIndex, PJError));
210
+ }
211
+#endif
212
+
213
+} // Judy1LastEmpty() / JudyLLastEmpty()
libnetdata/libjudy/src/JudyL/JudyLFreeArray.c
new
+363
@@ -0,0 +1,363 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.51 $ $Source: /judy/src/JudyCommon/JudyFreeArray.c $
19
+//
20
+// Judy1FreeArray() and JudyLFreeArray() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+// Return the number of bytes freed from the array.
23
+
24
+#if (! (defined(JUDY1) || defined(JUDYL)))
25
+#error: One of -DJUDY1 or -DJUDYL must be specified.
26
+#endif
27
+
28
+#ifdef JUDY1
29
+#include "Judy1.h"
30
+#else
31
+#include "JudyL.h"
32
+#endif
33
+
34
+#include "JudyPrivate1L.h"
35
+
36
+DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
37
+
38
+
39
+// ****************************************************************************
40
+// J U D Y 1 F R E E A R R A Y
41
+// J U D Y L F R E E A R R A Y
42
+//
43
+// See the Judy*(3C) manual entry for details.
44
+//
45
+// This code is written recursively, at least at first, because thats much
46
+// simpler. Hope its fast enough.
47
+
48
+#ifdef JUDY1
49
+FUNCTION Word_t Judy1FreeArray
50
+#else
51
+FUNCTION Word_t JudyLFreeArray
52
+#endif
53
+ (
54
+ PPvoid_t PPArray, // array to free.
55
+ PJError_t PJError // optional, for returning error info.
56
+ )
57
+{
58
+ jpm_t jpm; // local to accumulate free statistics.
59
+
60
+// CHECK FOR NULL POINTER (error by caller):
61
+
62
+ if (PPArray == (PPvoid_t) NULL)
63
+ {
64
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
65
+ return(JERR);
66
+ }
67
+
68
+ DBGCODE(JudyCheckPop(*PPArray);)
69
+
70
+// Zero jpm.jpm_Pop0 (meaning the array will be empty in a moment) for accurate
71
+// logging in TRACEMI2.
72
+
73
+ jpm.jpm_Pop0 = 0; // see above.
74
+ jpm.jpm_TotalMemWords = 0; // initialize memory freed.
75
+
76
+// Empty array:
77
+
78
+ if (P_JLW(*PPArray) == (Pjlw_t) NULL) return(0);
79
+
80
+// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAF:
81
+
82
+ if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
83
+ {
84
+ Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
85
+
86
+ j__udyFreeJLW(Pjlw, Pjlw[0] + 1, &jpm);
87
+ *PPArray = (Pvoid_t) NULL; // make an empty array.
88
+ return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD)); // see above.
89
+ }
90
+ else
91
+
92
+// Rootstate leaves: just free the leaf:
93
+
94
+// Common code for returning the amount of memory freed.
95
+//
96
+// Note: In a an ordinary LEAFW, pop0 = *PPArray[0].
97
+//
98
+// Accumulate (negative) words freed, while freeing objects.
99
+// Return the positive bytes freed.
100
+
101
+ {
102
+ Pjpm_t Pjpm = P_JPM(*PPArray);
103
+ Word_t TotalMem = Pjpm->jpm_TotalMemWords;
104
+
105
+ j__udyFreeSM(&(Pjpm->jpm_JP), &jpm); // recurse through tree.
106
+ j__udyFreeJPM(Pjpm, &jpm);
107
+
108
+// Verify the array was not corrupt. This means that amount of memory freed
109
+// (which is negative) is equal to the initial amount:
110
+
111
+ if (TotalMem + jpm.jpm_TotalMemWords)
112
+ {
113
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
114
+ return(JERR);
115
+ }
116
+
117
+ *PPArray = (Pvoid_t) NULL; // make an empty array.
118
+ return (TotalMem * cJU_BYTESPERWORD);
119
+ }
120
+
121
+} // Judy1FreeArray() / JudyLFreeArray()
122
+
123
+
124
+// ****************************************************************************
125
+// __ J U D Y F R E E S M
126
+//
127
+// Given a pointer to a JP, recursively visit and free (depth first) all nodes
128
+// in a Judy array BELOW the JP, but not the JP itself. Accumulate in *Pjpm
129
+// the total words freed (as a negative value). "SM" = State Machine.
130
+//
131
+// Note: Corruption is not detected at this level because during a FreeArray,
132
+// if the code hasnt already core dumped, its better to remain silent, even
133
+// if some memory has not been freed, than to bother the caller about the
134
+// corruption. TBD: Is this true? If not, must list all legitimate JPNULL
135
+// and JPIMMED above first, and revert to returning bool_t (see 4.34).
136
+
137
+FUNCTION void j__udyFreeSM(
138
+ Pjp_t Pjp, // top of Judy (top-state).
139
+ Pjpm_t Pjpm) // to return words freed.
140
+{
141
+ Word_t Pop1;
142
+
143
+ switch (JU_JPTYPE(Pjp))
144
+ {
145
+
146
+#ifdef JUDY1
147
+
148
+// FULL EXPANSE -- nothing to free for this jp_Type.
149
+
150
+ case cJ1_JPFULLPOPU1:
151
+ break;
152
+#endif
153
+
154
+// JUDY BRANCH -- free the sub-tree depth first:
155
+
156
+// LINEAR BRANCH -- visit each JP in the JBLs list, then free the JBL:
157
+//
158
+// Note: There are no null JPs in a JBL.
159
+
160
+ case cJU_JPBRANCH_L:
161
+ case cJU_JPBRANCH_L2:
162
+ case cJU_JPBRANCH_L3:
163
+#ifdef JU_64BIT
164
+ case cJU_JPBRANCH_L4:
165
+ case cJU_JPBRANCH_L5:
166
+ case cJU_JPBRANCH_L6:
167
+ case cJU_JPBRANCH_L7:
168
+#endif // JU_64BIT
169
+ {
170
+ Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
171
+ Word_t offset;
172
+
173
+ for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
174
+ j__udyFreeSM((Pjbl->jbl_jp) + offset, Pjpm);
175
+
176
+ j__udyFreeJBL((Pjbl_t) (Pjp->jp_Addr), Pjpm);
177
+ break;
178
+ }
179
+
180
+
181
+// BITMAP BRANCH -- visit each JP in the JBBs list based on the bitmap, also
182
+//
183
+// Note: There are no null JPs in a JBB.
184
+
185
+ case cJU_JPBRANCH_B:
186
+ case cJU_JPBRANCH_B2:
187
+ case cJU_JPBRANCH_B3:
188
+#ifdef JU_64BIT
189
+ case cJU_JPBRANCH_B4:
190
+ case cJU_JPBRANCH_B5:
191
+ case cJU_JPBRANCH_B6:
192
+ case cJU_JPBRANCH_B7:
193
+#endif // JU_64BIT
194
+ {
195
+ Word_t subexp;
196
+ Word_t offset;
197
+ Word_t jpcount;
198
+
199
+ Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
200
+
201
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
202
+ {
203
+ jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
204
+
205
+ if (jpcount)
206
+ {
207
+ for (offset = 0; offset < jpcount; ++offset)
208
+ {
209
+ j__udyFreeSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + offset,
210
+ Pjpm);
211
+ }
212
+ j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, subexp), jpcount, Pjpm);
213
+ }
214
+ }
215
+ j__udyFreeJBB((Pjbb_t) (Pjp->jp_Addr), Pjpm);
216
+
217
+ break;
218
+ }
219
+
220
+
221
+// UNCOMPRESSED BRANCH -- visit each JP in the JBU array, then free the JBU
222
+// itself:
223
+//
224
+// Note: Null JPs are handled during recursion at a lower state.
225
+
226
+ case cJU_JPBRANCH_U:
227
+ case cJU_JPBRANCH_U2:
228
+ case cJU_JPBRANCH_U3:
229
+#ifdef JU_64BIT
230
+ case cJU_JPBRANCH_U4:
231
+ case cJU_JPBRANCH_U5:
232
+ case cJU_JPBRANCH_U6:
233
+ case cJU_JPBRANCH_U7:
234
+#endif // JU_64BIT
235
+ {
236
+ Word_t offset;
237
+ Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
238
+
239
+ for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
240
+ j__udyFreeSM((Pjbu->jbu_jp) + offset, Pjpm);
241
+
242
+ j__udyFreeJBU((Pjbu_t) (Pjp->jp_Addr), Pjpm);
243
+ break;
244
+ }
245
+
246
+
247
+// -- Cases below here terminate and do not recurse. --
248
+
249
+
250
+// LINEAR LEAF -- just free the leaf; size is computed from jp_Type:
251
+//
252
+// Note: cJU_JPLEAF1 is a special case, see discussion in ../Judy1/Judy1.h
253
+
254
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
255
+ case cJU_JPLEAF1:
256
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
257
+ j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
258
+ break;
259
+#endif
260
+
261
+ case cJU_JPLEAF2:
262
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
263
+ j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
264
+ break;
265
+
266
+ case cJU_JPLEAF3:
267
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
268
+ j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
269
+ break;
270
+
271
+#ifdef JU_64BIT
272
+ case cJU_JPLEAF4:
273
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
274
+ j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
275
+ break;
276
+
277
+ case cJU_JPLEAF5:
278
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
279
+ j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
280
+ break;
281
+
282
+ case cJU_JPLEAF6:
283
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
284
+ j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
285
+ break;
286
+
287
+ case cJU_JPLEAF7:
288
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
289
+ j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
290
+ break;
291
+#endif // JU_64BIT
292
+
293
+
294
+// BITMAP LEAF -- free sub-expanse arrays of JPs, then free the JBB.
295
+
296
+ case cJU_JPLEAF_B1:
297
+ {
298
+#ifdef JUDYL
299
+ Word_t subexp;
300
+ Word_t jpcount;
301
+ Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr);
302
+
303
+// Free the value areas in the bitmap leaf:
304
+
305
+ for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
306
+ {
307
+ jpcount = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
308
+
309
+ if (jpcount)
310
+ j__udyLFreeJV(JL_JLB_PVALUE(Pjlb, subexp), jpcount, Pjpm);
311
+ }
312
+#endif // JUDYL
313
+
314
+ j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm);
315
+ break;
316
+
317
+ } // case cJU_JPLEAF_B1
318
+
319
+#ifdef JUDYL
320
+
321
+
322
+// IMMED*:
323
+//
324
+// For JUDYL, all non JPIMMED_*_01s have a LeafV which must be freed:
325
+
326
+ case cJU_JPIMMED_1_02:
327
+ case cJU_JPIMMED_1_03:
328
+#ifdef JU_64BIT
329
+ case cJU_JPIMMED_1_04:
330
+ case cJU_JPIMMED_1_05:
331
+ case cJU_JPIMMED_1_06:
332
+ case cJU_JPIMMED_1_07:
333
+#endif
334
+ Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2;
335
+ j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
336
+ break;
337
+
338
+#ifdef JU_64BIT
339
+ case cJU_JPIMMED_2_02:
340
+ case cJU_JPIMMED_2_03:
341
+
342
+ Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2;
343
+ j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
344
+ break;
345
+
346
+ case cJU_JPIMMED_3_02:
347
+ j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), 2, Pjpm);
348
+ break;
349
+
350
+#endif // JU_64BIT
351
+#endif // JUDYL
352
+
353
+
354
+// OTHER JPNULL, JPIMMED, OR UNEXPECTED TYPE -- nothing to free for this type:
355
+//
356
+// Note: Lump together no-op and invalid JP types; see function header
357
+// comments.
358
+
359
+ default: break;
360
+
361
+ } // switch (JU_JPTYPE(Pjp))
362
+
363
+} // j__udyFreeSM()
libnetdata/libjudy/src/JudyL/JudyLGet.c
new
+1094
@@ -0,0 +1,1094 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.43 $ $Source: /judy/src/JudyCommon/JudyGet.c $
19
+//
20
+// Judy1Test() and JudyLGet() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+
23
+#if (! (defined(JUDY1) || defined(JUDYL)))
24
+#error: One of -DJUDY1 or -DJUDYL must be specified.
25
+#endif
26
+
27
+#ifdef JUDY1
28
+#include "Judy1.h"
29
+#else
30
+#include "JudyL.h"
31
+#endif
32
+
33
+#include "JudyPrivate1L.h"
34
+
35
+#ifdef TRACEJPR // different macro name, for "retrieval" only.
36
+#include "JudyPrintJP.c"
37
+#endif
38
+
39
+
40
+// ****************************************************************************
41
+// J U D Y 1 T E S T
42
+// J U D Y L G E T
43
+//
44
+// See the manual entry for details. Note support for "shortcut" entries to
45
+// trees known to start with a JPM.
46
+
47
+#ifdef JUDY1
48
+
49
+#ifdef JUDYGETINLINE
50
+FUNCTION int j__udy1Test
51
+#else
52
+FUNCTION int Judy1Test
53
+#endif
54
+
55
+#else // JUDYL
56
+
57
+#ifdef JUDYGETINLINE
58
+FUNCTION PPvoid_t j__udyLGet
59
+#else
60
+FUNCTION PPvoid_t JudyLGet
61
+#endif
62
+
63
+#endif // JUDYL
64
+ (
65
+#ifdef JUDYGETINLINE
66
+ Pvoid_t PArray, // from which to retrieve.
67
+ Word_t Index // to retrieve.
68
+#else
69
+ Pcvoid_t PArray, // from which to retrieve.
70
+ Word_t Index, // to retrieve.
71
+ PJError_t PJError // optional, for returning error info.
72
+#endif
73
+ )
74
+{
75
+ Pjp_t Pjp; // current JP while walking the tree.
76
+ Pjpm_t Pjpm; // for global accounting.
77
+ uint8_t Digit; // byte just decoded from Index.
78
+ Word_t Pop1; // leaf population (number of indexes).
79
+ Pjll_t Pjll; // pointer to LeafL.
80
+ DBGCODE(uint8_t ParentJPType;)
81
+
82
+#ifndef JUDYGETINLINE
83
+
84
+ if (PArray == (Pcvoid_t) NULL) // empty array.
85
+ {
86
+ JUDY1CODE(return(0);)
87
+ JUDYLCODE(return((PPvoid_t) NULL);)
88
+ }
89
+
90
+// ****************************************************************************
91
+// PROCESS TOP LEVEL BRANCHES AND LEAF:
92
+
93
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
94
+ {
95
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
96
+ int posidx; // signed offset in leaf.
97
+
98
+ Pop1 = Pjlw[0] + 1;
99
+ posidx = j__udySearchLeafW(Pjlw + 1, Pop1, Index);
100
+
101
+ if (posidx >= 0)
102
+ {
103
+ JUDY1CODE(return(1);)
104
+ JUDYLCODE(return((PPvoid_t) (JL_LEAFWVALUEAREA(Pjlw, Pop1) + posidx));)
105
+ }
106
+ JUDY1CODE(return(0);)
107
+ JUDYLCODE(return((PPvoid_t) NULL);)
108
+ }
109
+
110
+#endif // ! JUDYGETINLINE
111
+
112
+ Pjpm = P_JPM(PArray);
113
+ Pjp = &(Pjpm->jpm_JP); // top branch is below JPM.
114
+
115
+// ****************************************************************************
116
+// WALK THE JUDY TREE USING A STATE MACHINE:
117
+
118
+ContinueWalk: // for going down one level; come here with Pjp set.
119
+
120
+#ifdef TRACEJPR
121
+ JudyPrintJP(Pjp, "g", __LINE__);
122
+#endif
123
+ switch (JU_JPTYPE(Pjp))
124
+ {
125
+
126
+// Ensure the switch table starts at 0 for speed; otherwise more code is
127
+// executed:
128
+
129
+ case 0: goto ReturnCorrupt; // save a little code.
130
+
131
+
132
+// ****************************************************************************
133
+// JPNULL*:
134
+//
135
+// Note: These are legitimate in a BranchU (only) and do not constitute a
136
+// fault.
137
+
138
+ case cJU_JPNULL1:
139
+ case cJU_JPNULL2:
140
+ case cJU_JPNULL3:
141
+#ifdef JU_64BIT
142
+ case cJU_JPNULL4:
143
+ case cJU_JPNULL5:
144
+ case cJU_JPNULL6:
145
+ case cJU_JPNULL7:
146
+#endif
147
+ assert(ParentJPType >= cJU_JPBRANCH_U2);
148
+ assert(ParentJPType <= cJU_JPBRANCH_U);
149
+ JUDY1CODE(return(0);)
150
+ JUDYLCODE(return((PPvoid_t) NULL);)
151
+
152
+
153
+// ****************************************************************************
154
+// JPBRANCH_L*:
155
+//
156
+// Note: The use of JU_DCDNOTMATCHINDEX() in branches is not strictly
157
+// required,since this can be done at leaf level, but it costs nothing to do it
158
+// sooner, and it aborts an unnecessary traversal sooner.
159
+
160
+ case cJU_JPBRANCH_L2:
161
+
162
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
163
+ Digit = JU_DIGITATSTATE(Index, 2);
164
+ goto JudyBranchL;
165
+
166
+ case cJU_JPBRANCH_L3:
167
+
168
+#ifdef JU_64BIT // otherwise its a no-op:
169
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
170
+#endif
171
+ Digit = JU_DIGITATSTATE(Index, 3);
172
+ goto JudyBranchL;
173
+
174
+#ifdef JU_64BIT
175
+ case cJU_JPBRANCH_L4:
176
+
177
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
178
+ Digit = JU_DIGITATSTATE(Index, 4);
179
+ goto JudyBranchL;
180
+
181
+ case cJU_JPBRANCH_L5:
182
+
183
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
184
+ Digit = JU_DIGITATSTATE(Index, 5);
185
+ goto JudyBranchL;
186
+
187
+ case cJU_JPBRANCH_L6:
188
+
189
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
190
+ Digit = JU_DIGITATSTATE(Index, 6);
191
+ goto JudyBranchL;
192
+
193
+ case cJU_JPBRANCH_L7:
194
+
195
+ // JU_DCDNOTMATCHINDEX() would be a no-op.
196
+ Digit = JU_DIGITATSTATE(Index, 7);
197
+ goto JudyBranchL;
198
+
199
+#endif // JU_64BIT
200
+
201
+ case cJU_JPBRANCH_L:
202
+ {
203
+ Pjbl_t Pjbl;
204
+ int posidx;
205
+
206
+ Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
207
+
208
+// Common code for all BranchLs; come here with Digit set:
209
+
210
+JudyBranchL:
211
+ Pjbl = P_JBL(Pjp->jp_Addr);
212
+
213
+ posidx = 0;
214
+
215
+ do {
216
+ if (Pjbl->jbl_Expanse[posidx] == Digit)
217
+ { // found Digit; continue traversal:
218
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
219
+ Pjp = Pjbl->jbl_jp + posidx;
220
+ goto ContinueWalk;
221
+ }
222
+ } while (++posidx != Pjbl->jbl_NumJPs);
223
+
224
+ break;
225
+ }
226
+
227
+
228
+// ****************************************************************************
229
+// JPBRANCH_B*:
230
+
231
+ case cJU_JPBRANCH_B2:
232
+
233
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
234
+ Digit = JU_DIGITATSTATE(Index, 2);
235
+ goto JudyBranchB;
236
+
237
+ case cJU_JPBRANCH_B3:
238
+
239
+#ifdef JU_64BIT // otherwise its a no-op:
240
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
241
+#endif
242
+ Digit = JU_DIGITATSTATE(Index, 3);
243
+ goto JudyBranchB;
244
+
245
+
246
+#ifdef JU_64BIT
247
+ case cJU_JPBRANCH_B4:
248
+
249
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
250
+ Digit = JU_DIGITATSTATE(Index, 4);
251
+ goto JudyBranchB;
252
+
253
+ case cJU_JPBRANCH_B5:
254
+
255
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
256
+ Digit = JU_DIGITATSTATE(Index, 5);
257
+ goto JudyBranchB;
258
+
259
+ case cJU_JPBRANCH_B6:
260
+
261
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
262
+ Digit = JU_DIGITATSTATE(Index, 6);
263
+ goto JudyBranchB;
264
+
265
+ case cJU_JPBRANCH_B7:
266
+
267
+ // JU_DCDNOTMATCHINDEX() would be a no-op.
268
+ Digit = JU_DIGITATSTATE(Index, 7);
269
+ goto JudyBranchB;
270
+
271
+#endif // JU_64BIT
272
+
273
+ case cJU_JPBRANCH_B:
274
+ {
275
+ Pjbb_t Pjbb;
276
+ Word_t subexp; // in bitmap, 0..7.
277
+ BITMAPB_t BitMap; // for one subexpanse.
278
+ BITMAPB_t BitMask; // bit in BitMap for Indexs Digit.
279
+
280
+ Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
281
+
282
+// Common code for all BranchBs; come here with Digit set:
283
+
284
+JudyBranchB:
285
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
286
+ Pjbb = P_JBB(Pjp->jp_Addr);
287
+ subexp = Digit / cJU_BITSPERSUBEXPB;
288
+
289
+ BitMap = JU_JBB_BITMAP(Pjbb, subexp);
290
+ Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp));
291
+
292
+ BitMask = JU_BITPOSMASKB(Digit);
293
+
294
+// No JP in subexpanse for Index => Index not found:
295
+
296
+ if (! (BitMap & BitMask)) break;
297
+
298
+// Count JPs in the subexpanse below the one for Index:
299
+
300
+ Pjp += j__udyCountBitsB(BitMap & (BitMask - 1));
301
+
302
+ goto ContinueWalk;
303
+
304
+ } // case cJU_JPBRANCH_B*
305
+
306
+
307
+// ****************************************************************************
308
+// JPBRANCH_U*:
309
+//
310
+// Notice the reverse order of the cases, and falling through to the next case,
311
+// for performance.
312
+
313
+ case cJU_JPBRANCH_U:
314
+
315
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
316
+ Pjp = JU_JBU_PJP(Pjp, Index, cJU_ROOTSTATE);
317
+
318
+// If not a BranchU, traverse; otherwise fall into the next case, which makes
319
+// this very fast code for a large Judy array (mainly BranchUs), especially
320
+// when branches are already in the cache, such as for prev/next:
321
+
322
+#ifndef JU_64BIT
323
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U3) goto ContinueWalk;
324
+#else
325
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U7) goto ContinueWalk;
326
+#endif
327
+
328
+#ifdef JU_64BIT
329
+ case cJU_JPBRANCH_U7:
330
+
331
+ // JU_DCDNOTMATCHINDEX() would be a no-op.
332
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
333
+ Pjp = JU_JBU_PJP(Pjp, Index, 7);
334
+
335
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U6) goto ContinueWalk;
336
+ // and fall through.
337
+
338
+ case cJU_JPBRANCH_U6:
339
+
340
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
341
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
342
+ Pjp = JU_JBU_PJP(Pjp, Index, 6);
343
+
344
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U5) goto ContinueWalk;
345
+ // and fall through.
346
+
347
+ case cJU_JPBRANCH_U5:
348
+
349
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
350
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
351
+ Pjp = JU_JBU_PJP(Pjp, Index, 5);
352
+
353
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U4) goto ContinueWalk;
354
+ // and fall through.
355
+
356
+ case cJU_JPBRANCH_U4:
357
+
358
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
359
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
360
+ Pjp = JU_JBU_PJP(Pjp, Index, 4);
361
+
362
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U3) goto ContinueWalk;
363
+ // and fall through.
364
+
365
+#endif // JU_64BIT
366
+
367
+ case cJU_JPBRANCH_U3:
368
+
369
+#ifdef JU_64BIT // otherwise its a no-op:
370
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
371
+#endif
372
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
373
+ Pjp = JU_JBU_PJP(Pjp, Index, 3);
374
+
375
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U2) goto ContinueWalk;
376
+ // and fall through.
377
+
378
+ case cJU_JPBRANCH_U2:
379
+
380
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
381
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
382
+ Pjp = JU_JBU_PJP(Pjp, Index, 2);
383
+
384
+// Note: BranchU2 is a special case that must continue traversal to a leaf,
385
+// immed, full, or null type:
386
+
387
+ goto ContinueWalk;
388
+
389
+
390
+// ****************************************************************************
391
+// JPLEAF*:
392
+//
393
+// Note: Here the calls of JU_DCDNOTMATCHINDEX() are necessary and check
394
+// whether Index is out of the expanse of a narrow pointer.
395
+
396
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
397
+
398
+ case cJU_JPLEAF1:
399
+ {
400
+ int posidx; // signed offset in leaf.
401
+
402
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
403
+
404
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
405
+ Pjll = P_JLL(Pjp->jp_Addr);
406
+
407
+ if ((posidx = j__udySearchLeaf1(Pjll, Pop1, Index)) < 0) break;
408
+
409
+ JUDY1CODE(return(1);)
410
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF1VALUEAREA(Pjll, Pop1) + posidx));)
411
+ }
412
+
413
+#endif // (JUDYL || (! JU_64BIT))
414
+
415
+ case cJU_JPLEAF2:
416
+ {
417
+ int posidx; // signed offset in leaf.
418
+
419
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
420
+
421
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
422
+ Pjll = P_JLL(Pjp->jp_Addr);
423
+
424
+ if ((posidx = j__udySearchLeaf2(Pjll, Pop1, Index)) < 0) break;
425
+
426
+ JUDY1CODE(return(1);)
427
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF2VALUEAREA(Pjll, Pop1) + posidx));)
428
+ }
429
+ case cJU_JPLEAF3:
430
+ {
431
+ int posidx; // signed offset in leaf.
432
+
433
+#ifdef JU_64BIT // otherwise its a no-op:
434
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
435
+#endif
436
+
437
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
438
+ Pjll = P_JLL(Pjp->jp_Addr);
439
+
440
+ if ((posidx = j__udySearchLeaf3(Pjll, Pop1, Index)) < 0) break;
441
+
442
+ JUDY1CODE(return(1);)
443
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF3VALUEAREA(Pjll, Pop1) + posidx));)
444
+ }
445
+#ifdef JU_64BIT
446
+ case cJU_JPLEAF4:
447
+ {
448
+ int posidx; // signed offset in leaf.
449
+
450
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
451
+
452
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
453
+ Pjll = P_JLL(Pjp->jp_Addr);
454
+
455
+ if ((posidx = j__udySearchLeaf4(Pjll, Pop1, Index)) < 0) break;
456
+
457
+ JUDY1CODE(return(1);)
458
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF4VALUEAREA(Pjll, Pop1) + posidx));)
459
+ }
460
+ case cJU_JPLEAF5:
461
+ {
462
+ int posidx; // signed offset in leaf.
463
+
464
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
465
+
466
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
467
+ Pjll = P_JLL(Pjp->jp_Addr);
468
+
469
+ if ((posidx = j__udySearchLeaf5(Pjll, Pop1, Index)) < 0) break;
470
+
471
+ JUDY1CODE(return(1);)
472
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF5VALUEAREA(Pjll, Pop1) + posidx));)
473
+ }
474
+
475
+ case cJU_JPLEAF6:
476
+ {
477
+ int posidx; // signed offset in leaf.
478
+
479
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
480
+
481
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
482
+ Pjll = P_JLL(Pjp->jp_Addr);
483
+
484
+ if ((posidx = j__udySearchLeaf6(Pjll, Pop1, Index)) < 0) break;
485
+
486
+ JUDY1CODE(return(1);)
487
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF6VALUEAREA(Pjll, Pop1) + posidx));)
488
+ }
489
+ case cJU_JPLEAF7:
490
+ {
491
+ int posidx; // signed offset in leaf.
492
+
493
+ // JU_DCDNOTMATCHINDEX() would be a no-op.
494
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
495
+ Pjll = P_JLL(Pjp->jp_Addr);
496
+
497
+ if ((posidx = j__udySearchLeaf7(Pjll, Pop1, Index)) < 0) break;
498
+
499
+ JUDY1CODE(return(1);)
500
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF7VALUEAREA(Pjll, Pop1) + posidx));)
501
+ }
502
+#endif // JU_64BIT
503
+
504
+
505
+// ****************************************************************************
506
+// JPLEAF_B1:
507
+
508
+ case cJU_JPLEAF_B1:
509
+ {
510
+ Pjlb_t Pjlb;
511
+#ifdef JUDYL
512
+ int posidx;
513
+ Word_t subexp; // in bitmap, 0..7.
514
+ BITMAPL_t BitMap; // for one subexpanse.
515
+ BITMAPL_t BitMask; // bit in BitMap for Indexs Digit.
516
+ Pjv_t Pjv;
517
+#endif
518
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
519
+
520
+ Pjlb = P_JLB(Pjp->jp_Addr);
521
+
522
+#ifdef JUDY1
523
+
524
+// Simply check if Indexs bit is set in the bitmap:
525
+
526
+ if (JU_BITMAPTESTL(Pjlb, Index)) return(1);
527
+ break;
528
+
529
+#else // JUDYL
530
+
531
+// JudyL is much more complicated because of value area subarrays:
532
+
533
+ Digit = JU_DIGITATSTATE(Index, 1);
534
+ subexp = Digit / cJU_BITSPERSUBEXPL;
535
+ BitMap = JU_JLB_BITMAP(Pjlb, subexp);
536
+ BitMask = JU_BITPOSMASKL(Digit);
537
+
538
+// No value in subexpanse for Index => Index not found:
539
+
540
+ if (! (BitMap & BitMask)) break;
541
+
542
+// Count value areas in the subexpanse below the one for Index:
543
+
544
+ Pjv = P_JV(JL_JLB_PVALUE(Pjlb, subexp));
545
+ assert(Pjv != (Pjv_t) NULL);
546
+ posidx = j__udyCountBitsL(BitMap & (BitMask - 1));
547
+
548
+ return((PPvoid_t) (Pjv + posidx));
549
+
550
+#endif // JUDYL
551
+
552
+ } // case cJU_JPLEAF_B1
553
+
554
+#ifdef JUDY1
555
+
556
+// ****************************************************************************
557
+// JPFULLPOPU1:
558
+//
559
+// If the Index is in the expanse, it is necessarily valid (found).
560
+
561
+ case cJ1_JPFULLPOPU1:
562
+
563
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
564
+ return(1);
565
+
566
+#ifdef notdef // for future enhancements
567
+#ifdef JU_64BIT
568
+
569
+// Note: Need ? if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
570
+
571
+ case cJ1_JPFULLPOPU1m15:
572
+ if (Pjp->jp_1Index[14] == (uint8_t)Index) break;
573
+ case cJ1_JPFULLPOPU1m14:
574
+ if (Pjp->jp_1Index[13] == (uint8_t)Index) break;
575
+ case cJ1_JPFULLPOPU1m13:
576
+ if (Pjp->jp_1Index[12] == (uint8_t)Index) break;
577
+ case cJ1_JPFULLPOPU1m12:
578
+ if (Pjp->jp_1Index[11] == (uint8_t)Index) break;
579
+ case cJ1_JPFULLPOPU1m11:
580
+ if (Pjp->jp_1Index[10] == (uint8_t)Index) break;
581
+ case cJ1_JPFULLPOPU1m10:
582
+ if (Pjp->jp_1Index[9] == (uint8_t)Index) break;
583
+ case cJ1_JPFULLPOPU1m9:
584
+ if (Pjp->jp_1Index[8] == (uint8_t)Index) break;
585
+ case cJ1_JPFULLPOPU1m8:
586
+ if (Pjp->jp_1Index[7] == (uint8_t)Index) break;
587
+#endif
588
+ case cJ1_JPFULLPOPU1m7:
589
+ if (Pjp->jp_1Index[6] == (uint8_t)Index) break;
590
+ case cJ1_JPFULLPOPU1m6:
591
+ if (Pjp->jp_1Index[5] == (uint8_t)Index) break;
592
+ case cJ1_JPFULLPOPU1m5:
593
+ if (Pjp->jp_1Index[4] == (uint8_t)Index) break;
594
+ case cJ1_JPFULLPOPU1m4:
595
+ if (Pjp->jp_1Index[3] == (uint8_t)Index) break;
596
+ case cJ1_JPFULLPOPU1m3:
597
+ if (Pjp->jp_1Index[2] == (uint8_t)Index) break;
598
+ case cJ1_JPFULLPOPU1m2:
599
+ if (Pjp->jp_1Index[1] == (uint8_t)Index) break;
600
+ case cJ1_JPFULLPOPU1m1:
601
+ if (Pjp->jp_1Index[0] == (uint8_t)Index) break;
602
+
603
+ return(1); // found, not in exclusion list
604
+
605
+#endif // JUDY1
606
+#endif // notdef
607
+
608
+// ****************************************************************************
609
+// JPIMMED*:
610
+//
611
+// Note that the contents of jp_DcdPopO are different for cJU_JPIMMED_*_01:
612
+
613
+ case cJU_JPIMMED_1_01:
614
+ case cJU_JPIMMED_2_01:
615
+ case cJU_JPIMMED_3_01:
616
+#ifdef JU_64BIT
617
+ case cJU_JPIMMED_4_01:
618
+ case cJU_JPIMMED_5_01:
619
+ case cJU_JPIMMED_6_01:
620
+ case cJU_JPIMMED_7_01:
621
+#endif
622
+ if (JU_JPDCDPOP0(Pjp) != JU_TRIMTODCDSIZE(Index)) break;
623
+
624
+ JUDY1CODE(return(1);)
625
+ JUDYLCODE(return((PPvoid_t) &(Pjp->jp_Addr));) // immediate value area.
626
+
627
+
628
+// Macros to make code more readable and avoid dup errors
629
+
630
+#ifdef JUDY1
631
+
632
+#define CHECKINDEXNATIVE(LEAF_T, PJP, IDX, INDEX) \
633
+if (((LEAF_T *)((PJP)->jp_1Index))[(IDX) - 1] == (LEAF_T)(INDEX)) \
634
+ return(1)
635
+
636
+#define CHECKLEAFNONNAT(LFBTS, PJP, INDEX, IDX, COPY) \
637
+{ \
638
+ Word_t i_ndex; \
639
+ uint8_t *a_ddr; \
640
+ a_ddr = (PJP)->jp_1Index + (((IDX) - 1) * (LFBTS)); \
641
+ COPY(i_ndex, a_ddr); \
642
+ if (i_ndex == JU_LEASTBYTES((INDEX), (LFBTS))) \
643
+ return(1); \
644
+}
645
+#endif
646
+
647
+#ifdef JUDYL
648
+
649
+#define CHECKINDEXNATIVE(LEAF_T, PJP, IDX, INDEX) \
650
+if (((LEAF_T *)((PJP)->jp_LIndex))[(IDX) - 1] == (LEAF_T)(INDEX)) \
651
+ return((PPvoid_t)(P_JV((PJP)->jp_Addr) + (IDX) - 1))
652
+
653
+#define CHECKLEAFNONNAT(LFBTS, PJP, INDEX, IDX, COPY) \
654
+{ \
655
+ Word_t i_ndex; \
656
+ uint8_t *a_ddr; \
657
+ a_ddr = (PJP)->jp_LIndex + (((IDX) - 1) * (LFBTS)); \
658
+ COPY(i_ndex, a_ddr); \
659
+ if (i_ndex == JU_LEASTBYTES((INDEX), (LFBTS))) \
660
+ return((PPvoid_t)(P_JV((PJP)->jp_Addr) + (IDX) - 1)); \
661
+}
662
+#endif
663
+
664
+#if (defined(JUDY1) && defined(JU_64BIT))
665
+ case cJ1_JPIMMED_1_15: CHECKINDEXNATIVE(uint8_t, Pjp, 15, Index);
666
+ case cJ1_JPIMMED_1_14: CHECKINDEXNATIVE(uint8_t, Pjp, 14, Index);
667
+ case cJ1_JPIMMED_1_13: CHECKINDEXNATIVE(uint8_t, Pjp, 13, Index);
668
+ case cJ1_JPIMMED_1_12: CHECKINDEXNATIVE(uint8_t, Pjp, 12, Index);
669
+ case cJ1_JPIMMED_1_11: CHECKINDEXNATIVE(uint8_t, Pjp, 11, Index);
670
+ case cJ1_JPIMMED_1_10: CHECKINDEXNATIVE(uint8_t, Pjp, 10, Index);
671
+ case cJ1_JPIMMED_1_09: CHECKINDEXNATIVE(uint8_t, Pjp, 9, Index);
672
+ case cJ1_JPIMMED_1_08: CHECKINDEXNATIVE(uint8_t, Pjp, 8, Index);
673
+#endif
674
+#if (defined(JUDY1) || defined(JU_64BIT))
675
+ case cJU_JPIMMED_1_07: CHECKINDEXNATIVE(uint8_t, Pjp, 7, Index);
676
+ case cJU_JPIMMED_1_06: CHECKINDEXNATIVE(uint8_t, Pjp, 6, Index);
677
+ case cJU_JPIMMED_1_05: CHECKINDEXNATIVE(uint8_t, Pjp, 5, Index);
678
+ case cJU_JPIMMED_1_04: CHECKINDEXNATIVE(uint8_t, Pjp, 4, Index);
679
+#endif
680
+ case cJU_JPIMMED_1_03: CHECKINDEXNATIVE(uint8_t, Pjp, 3, Index);
681
+ case cJU_JPIMMED_1_02: CHECKINDEXNATIVE(uint8_t, Pjp, 2, Index);
682
+ CHECKINDEXNATIVE(uint8_t, Pjp, 1, Index);
683
+ break;
684
+
685
+#if (defined(JUDY1) && defined(JU_64BIT))
686
+ case cJ1_JPIMMED_2_07: CHECKINDEXNATIVE(uint16_t, Pjp, 7, Index);
687
+ case cJ1_JPIMMED_2_06: CHECKINDEXNATIVE(uint16_t, Pjp, 6, Index);
688
+ case cJ1_JPIMMED_2_05: CHECKINDEXNATIVE(uint16_t, Pjp, 5, Index);
689
+ case cJ1_JPIMMED_2_04: CHECKINDEXNATIVE(uint16_t, Pjp, 4, Index);
690
+#endif
691
+#if (defined(JUDY1) || defined(JU_64BIT))
692
+ case cJU_JPIMMED_2_03: CHECKINDEXNATIVE(uint16_t, Pjp, 3, Index);
693
+ case cJU_JPIMMED_2_02: CHECKINDEXNATIVE(uint16_t, Pjp, 2, Index);
694
+ CHECKINDEXNATIVE(uint16_t, Pjp, 1, Index);
695
+ break;
696
+#endif
697
+
698
+#if (defined(JUDY1) && defined(JU_64BIT))
699
+ case cJ1_JPIMMED_3_05:
700
+ CHECKLEAFNONNAT(3, Pjp, Index, 5, JU_COPY3_PINDEX_TO_LONG);
701
+ case cJ1_JPIMMED_3_04:
702
+ CHECKLEAFNONNAT(3, Pjp, Index, 4, JU_COPY3_PINDEX_TO_LONG);
703
+ case cJ1_JPIMMED_3_03:
704
+ CHECKLEAFNONNAT(3, Pjp, Index, 3, JU_COPY3_PINDEX_TO_LONG);
705
+#endif
706
+#if (defined(JUDY1) || defined(JU_64BIT))
707
+ case cJU_JPIMMED_3_02:
708
+ CHECKLEAFNONNAT(3, Pjp, Index, 2, JU_COPY3_PINDEX_TO_LONG);
709
+ CHECKLEAFNONNAT(3, Pjp, Index, 1, JU_COPY3_PINDEX_TO_LONG);
710
+ break;
711
+#endif
712
+
713
+#if (defined(JUDY1) && defined(JU_64BIT))
714
+
715
+ case cJ1_JPIMMED_4_03: CHECKINDEXNATIVE(uint32_t, Pjp, 3, Index);
716
+ case cJ1_JPIMMED_4_02: CHECKINDEXNATIVE(uint32_t, Pjp, 2, Index);
717
+ CHECKINDEXNATIVE(uint32_t, Pjp, 1, Index);
718
+ break;
719
+
720
+ case cJ1_JPIMMED_5_03:
721
+ CHECKLEAFNONNAT(5, Pjp, Index, 3, JU_COPY5_PINDEX_TO_LONG);
722
+ case cJ1_JPIMMED_5_02:
723
+ CHECKLEAFNONNAT(5, Pjp, Index, 2, JU_COPY5_PINDEX_TO_LONG);
724
+ CHECKLEAFNONNAT(5, Pjp, Index, 1, JU_COPY5_PINDEX_TO_LONG);
725
+ break;
726
+
727
+ case cJ1_JPIMMED_6_02:
728
+ CHECKLEAFNONNAT(6, Pjp, Index, 2, JU_COPY6_PINDEX_TO_LONG);
729
+ CHECKLEAFNONNAT(6, Pjp, Index, 1, JU_COPY6_PINDEX_TO_LONG);
730
+ break;
731
+
732
+ case cJ1_JPIMMED_7_02:
733
+ CHECKLEAFNONNAT(7, Pjp, Index, 2, JU_COPY7_PINDEX_TO_LONG);
734
+ CHECKLEAFNONNAT(7, Pjp, Index, 1, JU_COPY7_PINDEX_TO_LONG);
735
+ break;
736
+
737
+#endif // (JUDY1 && JU_64BIT)
738
+
739
+
740
+// ****************************************************************************
741
+// INVALID JP TYPE:
742
+
743
+ default:
744
+
745
+ReturnCorrupt:
746
+
747
+#ifdef JUDYGETINLINE // Pjpm is known to be non-null:
748
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
749
+#else
750
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
751
+#endif
752
+ JUDY1CODE(return(JERRI );)
753
+ JUDYLCODE(return(PPJERR);)
754
+
755
+ } // switch on JP type
756
+
757
+JUDY1CODE(return(0);)
758
+JUDYLCODE(return((PPvoid_t) NULL);)
759
+
760
+} // Judy1Test() / JudyLGet()
761
+
762
+
763
+#ifndef JUDYGETINLINE // only compile the following function once:
764
+#ifdef DEBUG
765
+
766
+// ****************************************************************************
767
+// J U D Y C H E C K P O P
768
+//
769
+// Given a pointer to a Judy array, traverse the entire array to ensure
770
+// population counts add up correctly. This can catch various coding errors.
771
+//
772
+// Since walking the entire tree is probably time-consuming, enable this
773
+// function by setting env parameter $CHECKPOP to first call at which to start
774
+// checking. Note: This function is called both from insert and delete code.
775
+//
776
+// Note: Even though this function does nothing useful for LEAFW leaves, its
777
+// good practice to call it anyway, and cheap too.
778
+//
779
+// TBD: This is a debug-only check function similar to JudyCheckSorted(), but
780
+// since it walks the tree it is Judy1/JudyL-specific and must live in a source
781
+// file that is built both ways.
782
+//
783
+// TBD: As feared, enabling this code for every insert/delete makes Judy
784
+// deathly slow, even for a small tree (10K indexes). Its not so bad if
785
+// present but disabled (<1% slowdown measured). Still, should it be ifdefd
786
+// other than DEBUG and/or called less often?
787
+//
788
+// TBD: Should this "population checker" be expanded to a comprehensive tree
789
+// checker? It currently detects invalid LEAFW/JP types as well as inconsistent
790
+// pop1s. Other possible checks, all based on essentially redundant data in
791
+// the Judy tree, include:
792
+//
793
+// - Zero LS bits in jp_Addr field.
794
+//
795
+// - Correct Dcd bits.
796
+//
797
+// - Consistent JP types (always descending down the tree).
798
+//
799
+// - Sorted linear lists in BranchLs and leaves (using JudyCheckSorted(), but
800
+// ideally that function is already called wherever appropriate after any
801
+// linear list is modified).
802
+//
803
+// - Any others possible?
804
+
805
+#include <stdlib.h> // for getenv() and atol().
806
+
807
+static Word_t JudyCheckPopSM(Pjp_t Pjp, Word_t RootPop1);
808
+
809
+FUNCTION void JudyCheckPop(
810
+ Pvoid_t PArray)
811
+{
812
+static bool_t checked = FALSE; // already checked env parameter.
813
+static bool_t enabled = FALSE; // env parameter set.
814
+static bool_t active = FALSE; // calls >= callsmin.
815
+static Word_t callsmin; // start point from $CHECKPOP.
816
+static Word_t calls = 0; // times called so far.
817
+
818
+
819
+// CHECK FOR EXTERNAL ENABLING:
820
+
821
+ if (! checked) // only check once.
822
+ {
823
+ char * value; // for getenv().
824
+
825
+ checked = TRUE;
826
+
827
+ if ((value = getenv("CHECKPOP")) == (char *) NULL)
828
+ {
829
+#ifdef notdef
830
+// Take this out because nightly tests want to be flavor-independent; its not
831
+// OK to emit special non-error output from the debug flavor:
832
+
833
+ (void) puts("JudyCheckPop() present but not enabled by "
834
+ "$CHECKPOP env parameter; set it to the number of "
835
+ "calls at which to begin checking");
836
+#endif
837
+ return;
838
+ }
839
+
840
+ callsmin = atol(value); // note: non-number evaluates to 0.
841
+ enabled = TRUE;
842
+
843
+ (void) printf("JudyCheckPop() present and enabled; callsmin = "
844
+ "%lu\n", callsmin);
845
+ }
846
+ else if (! enabled) return;
847
+
848
+// Previously or just now enabled; check if non-active or newly active:
849
+
850
+ if (! active)
851
+ {
852
+ if (++calls < callsmin) return;
853
+
854
+ (void) printf("JudyCheckPop() activated at call %lu\n", calls);
855
+ active = TRUE;
856
+ }
857
+
858
+// IGNORE LEAFW AT TOP OF TREE:
859
+
860
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
861
+ return;
862
+
863
+// Check JPM pop0 against tree, recursively:
864
+//
865
+// Note: The traversal code in JudyCheckPopSM() is simplest when the case
866
+// statement for each JP type compares the pop1 for that JP to its subtree (if
867
+// any) after traversing the subtree (thats the hard part) and adding up
868
+// actual pop1s. A top branchs JP in the JPM does not have room for a
869
+// full-word pop1, so pass it in as a special case.
870
+
871
+ {
872
+ Pjpm_t Pjpm = P_JPM(PArray);
873
+ (void) JudyCheckPopSM(&(Pjpm->jpm_JP), Pjpm->jpm_Pop0 + 1);
874
+ return;
875
+ }
876
+
877
+} // JudyCheckPop()
878
+
879
+
880
+// ****************************************************************************
881
+// J U D Y C H E C K P O P S M
882
+//
883
+// Recursive state machine (subroutine) for JudyCheckPop(): Given a Pjp (other
884
+// than JPNULL*; caller should shortcut) and the root population for top-level
885
+// branches, check the subtrees actual pop1 against its nominal value, and
886
+// return the total pop1 for the subtree.
887
+//
888
+// Note: Expect RootPop1 to be ignored at lower levels, so pass down 0, which
889
+// should pop an assertion if this expectation is violated.
890
+
891
+FUNCTION static Word_t JudyCheckPopSM(
892
+ Pjp_t Pjp, // top of subtree.
893
+ Word_t RootPop1) // whole array, for top-level branches only.
894
+{
895
+ Word_t pop1_jp; // nominal population from the JP.
896
+ Word_t pop1 = 0; // actual population at this level.
897
+ Word_t offset; // in a branch.
898
+
899
+#define PREPBRANCH(cPopBytes,Next) \
900
+ pop1_jp = JU_JPBRANCH_POP0(Pjp, cPopBytes) + 1; goto Next
901
+
902
+assert((((Word_t) (Pjp->jp_Addr)) & 7) == 3);
903
+ switch (JU_JPTYPE(Pjp))
904
+ {
905
+
906
+ case cJU_JPBRANCH_L2: PREPBRANCH(2, BranchL);
907
+ case cJU_JPBRANCH_L3: PREPBRANCH(3, BranchL);
908
+#ifdef JU_64BIT
909
+ case cJU_JPBRANCH_L4: PREPBRANCH(4, BranchL);
910
+ case cJU_JPBRANCH_L5: PREPBRANCH(5, BranchL);
911
+ case cJU_JPBRANCH_L6: PREPBRANCH(6, BranchL);
912
+ case cJU_JPBRANCH_L7: PREPBRANCH(7, BranchL);
913
+#endif
914
+ case cJU_JPBRANCH_L: pop1_jp = RootPop1;
915
+ {
916
+ Pjbl_t Pjbl;
917
+BranchL:
918
+ Pjbl = P_JBL(Pjp->jp_Addr);
919
+
920
+ for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
921
+ pop1 += JudyCheckPopSM((Pjbl->jbl_jp) + offset, 0);
922
+
923
+ assert(pop1_jp == pop1);
924
+ return(pop1);
925
+ }
926
+
927
+ case cJU_JPBRANCH_B2: PREPBRANCH(2, BranchB);
928
+ case cJU_JPBRANCH_B3: PREPBRANCH(3, BranchB);
929
+#ifdef JU_64BIT
930
+ case cJU_JPBRANCH_B4: PREPBRANCH(4, BranchB);
931
+ case cJU_JPBRANCH_B5: PREPBRANCH(5, BranchB);
932
+ case cJU_JPBRANCH_B6: PREPBRANCH(6, BranchB);
933
+ case cJU_JPBRANCH_B7: PREPBRANCH(7, BranchB);
934
+#endif
935
+ case cJU_JPBRANCH_B: pop1_jp = RootPop1;
936
+ {
937
+ Word_t subexp;
938
+ Word_t jpcount;
939
+ Pjbb_t Pjbb;
940
+BranchB:
941
+ Pjbb = P_JBB(Pjp->jp_Addr);
942
+
943
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
944
+ {
945
+ jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
946
+
947
+ for (offset = 0; offset < jpcount; ++offset)
948
+ {
949
+ pop1 += JudyCheckPopSM(P_JP(JU_JBB_PJP(Pjbb, subexp))
950
+ + offset, 0);
951
+ }
952
+ }
953
+
954
+ assert(pop1_jp == pop1);
955
+ return(pop1);
956
+ }
957
+
958
+ case cJU_JPBRANCH_U2: PREPBRANCH(2, BranchU);
959
+ case cJU_JPBRANCH_U3: PREPBRANCH(3, BranchU);
960
+#ifdef JU_64BIT
961
+ case cJU_JPBRANCH_U4: PREPBRANCH(4, BranchU);
962
+ case cJU_JPBRANCH_U5: PREPBRANCH(5, BranchU);
963
+ case cJU_JPBRANCH_U6: PREPBRANCH(6, BranchU);
964
+ case cJU_JPBRANCH_U7: PREPBRANCH(7, BranchU);
965
+#endif
966
+ case cJU_JPBRANCH_U: pop1_jp = RootPop1;
967
+ {
968
+ Pjbu_t Pjbu;
969
+BranchU:
970
+ Pjbu = P_JBU(Pjp->jp_Addr);
971
+
972
+ for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
973
+ {
974
+ if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
975
+ && ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
976
+ {
977
+ continue; // skip null JP to save time.
978
+ }
979
+
980
+ pop1 += JudyCheckPopSM((Pjbu->jbu_jp) + offset, 0);
981
+ }
982
+
983
+ assert(pop1_jp == pop1);
984
+ return(pop1);
985
+ }
986
+
987
+
988
+// -- Cases below here terminate and do not recurse. --
989
+//
990
+// For all of these cases except JPLEAF_B1, there is no way to check the JPs
991
+// pop1 against the object itself; just return the pop1; but for linear leaves,
992
+// a bounds check is possible.
993
+
994
+#define CHECKLEAF(MaxPop1) \
995
+ pop1 = JU_JPLEAF_POP0(Pjp) + 1; \
996
+ assert(pop1 >= 1); \
997
+ assert(pop1 <= (MaxPop1)); \
998
+ return(pop1)
999
+
1000
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
1001
+ case cJU_JPLEAF1: CHECKLEAF(cJU_LEAF1_MAXPOP1);
1002
+#endif
1003
+ case cJU_JPLEAF2: CHECKLEAF(cJU_LEAF2_MAXPOP1);
1004
+ case cJU_JPLEAF3: CHECKLEAF(cJU_LEAF3_MAXPOP1);
1005
+#ifdef JU_64BIT
1006
+ case cJU_JPLEAF4: CHECKLEAF(cJU_LEAF4_MAXPOP1);
1007
+ case cJU_JPLEAF5: CHECKLEAF(cJU_LEAF5_MAXPOP1);
1008
+ case cJU_JPLEAF6: CHECKLEAF(cJU_LEAF6_MAXPOP1);
1009
+ case cJU_JPLEAF7: CHECKLEAF(cJU_LEAF7_MAXPOP1);
1010
+#endif
1011
+
1012
+ case cJU_JPLEAF_B1:
1013
+ {
1014
+ Word_t subexp;
1015
+ Pjlb_t Pjlb;
1016
+
1017
+ pop1_jp = JU_JPLEAF_POP0(Pjp) + 1;
1018
+
1019
+ Pjlb = P_JLB(Pjp->jp_Addr);
1020
+
1021
+ for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
1022
+ pop1 += j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
1023
+
1024
+ assert(pop1_jp == pop1);
1025
+ return(pop1);
1026
+ }
1027
+
1028
+ JUDY1CODE(case cJ1_JPFULLPOPU1: return(cJU_JPFULLPOPU1_POP0);)
1029
+
1030
+ case cJU_JPIMMED_1_01: return(1);
1031
+ case cJU_JPIMMED_2_01: return(1);
1032
+ case cJU_JPIMMED_3_01: return(1);
1033
+#ifdef JU_64BIT
1034
+ case cJU_JPIMMED_4_01: return(1);
1035
+ case cJU_JPIMMED_5_01: return(1);
1036
+ case cJU_JPIMMED_6_01: return(1);
1037
+ case cJU_JPIMMED_7_01: return(1);
1038
+#endif
1039
+
1040
+ case cJU_JPIMMED_1_02: return(2);
1041
+ case cJU_JPIMMED_1_03: return(3);
1042
+#if (defined(JUDY1) || defined(JU_64BIT))
1043
+ case cJU_JPIMMED_1_04: return(4);
1044
+ case cJU_JPIMMED_1_05: return(5);
1045
+ case cJU_JPIMMED_1_06: return(6);
1046
+ case cJU_JPIMMED_1_07: return(7);
1047
+#endif
1048
+#if (defined(JUDY1) && defined(JU_64BIT))
1049
+ case cJ1_JPIMMED_1_08: return(8);
1050
+ case cJ1_JPIMMED_1_09: return(9);
1051
+ case cJ1_JPIMMED_1_10: return(10);
1052
+ case cJ1_JPIMMED_1_11: return(11);
1053
+ case cJ1_JPIMMED_1_12: return(12);
1054
+ case cJ1_JPIMMED_1_13: return(13);
1055
+ case cJ1_JPIMMED_1_14: return(14);
1056
+ case cJ1_JPIMMED_1_15: return(15);
1057
+#endif
1058
+
1059
+#if (defined(JUDY1) || defined(JU_64BIT))
1060
+ case cJU_JPIMMED_2_02: return(2);
1061
+ case cJU_JPIMMED_2_03: return(3);
1062
+#endif
1063
+#if (defined(JUDY1) && defined(JU_64BIT))
1064
+ case cJ1_JPIMMED_2_04: return(4);
1065
+ case cJ1_JPIMMED_2_05: return(5);
1066
+ case cJ1_JPIMMED_2_06: return(6);
1067
+ case cJ1_JPIMMED_2_07: return(7);
1068
+#endif
1069
+
1070
+#if (defined(JUDY1) || defined(JU_64BIT))
1071
+ case cJU_JPIMMED_3_02: return(2);
1072
+#endif
1073
+#if (defined(JUDY1) && defined(JU_64BIT))
1074
+ case cJ1_JPIMMED_3_03: return(3);
1075
+ case cJ1_JPIMMED_3_04: return(4);
1076
+ case cJ1_JPIMMED_3_05: return(5);
1077
+
1078
+ case cJ1_JPIMMED_4_02: return(2);
1079
+ case cJ1_JPIMMED_4_03: return(3);
1080
+ case cJ1_JPIMMED_5_02: return(2);
1081
+ case cJ1_JPIMMED_5_03: return(3);
1082
+ case cJ1_JPIMMED_6_02: return(2);
1083
+ case cJ1_JPIMMED_7_02: return(2);
1084
+#endif
1085
+
1086
+ } // switch (JU_JPTYPE(Pjp))
1087
+
1088
+ assert(FALSE); // unrecognized JP type => corruption.
1089
+ return(0); // to make some compilers happy.
1090
+
1091
+} // JudyCheckPopSM()
1092
+
1093
+#endif // DEBUG
1094
+#endif // ! JUDYGETINLINE
libnetdata/libjudy/src/JudyL/JudyLIns.c
new
+1873
@@ -0,0 +1,1873 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.116 $ $Source: /judy/src/JudyCommon/JudyIns.c $
19
+//
20
+// Judy1Set() and JudyLIns() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// TBD: Should some of the assertions here be converted to product code that
24
+// returns JU_ERRNO_CORRUPT?
25
+
26
+#if (! (defined(JUDY1) || defined(JUDYL)))
27
+#error: One of -DJUDY1 or -DJUDYL must be specified.
28
+#endif
29
+
30
+#ifdef JUDY1
31
+#include "Judy1.h"
32
+#else
33
+#include "JudyL.h"
34
+#endif
35
+
36
+#include "JudyPrivate1L.h"
37
+
38
+// Note: Call JudyCheckPop() even before "already inserted" returns, to catch
39
+// population errors; see fix in 4.84:
40
+
41
+DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
42
+DBGCODE(extern void JudyCheckSorted(Pjll_t Pjll, Word_t Pop1, long IndexSize);)
43
+
44
+#ifdef TRACEJP
45
+#include "JudyPrintJP.c"
46
+#endif
47
+
48
+
49
+// These are defined to generic values in JudyCommon/JudyPrivateTypes.h:
50
+//
51
+// TBD: These should be exported from a header file, but perhaps not, as they
52
+// are only used here, and exported from Judy*Decascade, which is a separate
53
+// file for profiling reasons (to prevent inlining), but which potentially
54
+// could be merged with this file, either in SoftCM or at compile-time.
55
+
56
+#ifdef JUDY1
57
+extern int j__udy1CreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
58
+extern int j__udy1CreateBranchU(Pjp_t, Pvoid_t);
59
+
60
+#ifndef JU_64BIT
61
+extern int j__udy1Cascade1(Pjp_t, Pvoid_t);
62
+#endif
63
+extern int j__udy1Cascade2(Pjp_t, Pvoid_t);
64
+extern int j__udy1Cascade3(Pjp_t, Pvoid_t);
65
+#ifdef JU_64BIT
66
+extern int j__udy1Cascade4(Pjp_t, Pvoid_t);
67
+extern int j__udy1Cascade5(Pjp_t, Pvoid_t);
68
+extern int j__udy1Cascade6(Pjp_t, Pvoid_t);
69
+extern int j__udy1Cascade7(Pjp_t, Pvoid_t);
70
+#endif
71
+extern int j__udy1CascadeL(Pjp_t, Pvoid_t);
72
+
73
+extern int j__udy1InsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
74
+
75
+#else // JUDYL
76
+
77
+extern int j__udyLCreateBranchB(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
78
+extern int j__udyLCreateBranchU(Pjp_t, Pvoid_t);
79
+
80
+extern int j__udyLCascade1(Pjp_t, Pvoid_t);
81
+extern int j__udyLCascade2(Pjp_t, Pvoid_t);
82
+extern int j__udyLCascade3(Pjp_t, Pvoid_t);
83
+#ifdef JU_64BIT
84
+extern int j__udyLCascade4(Pjp_t, Pvoid_t);
85
+extern int j__udyLCascade5(Pjp_t, Pvoid_t);
86
+extern int j__udyLCascade6(Pjp_t, Pvoid_t);
87
+extern int j__udyLCascade7(Pjp_t, Pvoid_t);
88
+#endif
89
+extern int j__udyLCascadeL(Pjp_t, Pvoid_t);
90
+
91
+extern int j__udyLInsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
92
+#endif
93
+
94
+
95
+// ****************************************************************************
96
+// MACROS FOR COMMON CODE:
97
+//
98
+// Check if Index is an outlier to (that is, not a member of) this expanse:
99
+//
100
+// An outlier is an Index in-the-expanse of the slot containing the pointer,
101
+// but not-in-the-expanse of the "narrow" pointer in that slot. (This means
102
+// the Dcd part of the Index differs from the equivalent part of jp_DcdPopO.)
103
+// Therefore, the remedy is to put a cJU_JPBRANCH_L* between the narrow pointer
104
+// and the object to which it points, and add the outlier Index as an Immediate
105
+// in the cJU_JPBRANCH_L*. The "trick" is placing the cJU_JPBRANCH_L* at a
106
+// Level that is as low as possible. This is determined by counting the digits
107
+// in the existing narrow pointer that are the same as the digits in the new
108
+// Index (see j__udyInsertBranch()).
109
+//
110
+// Note: At some high Levels, cJU_DCDMASK() is all zeros => dead code; assume
111
+// the compiler optimizes this out.
112
+
113
+#define JU_CHECK_IF_OUTLIER(Pjp, Index, cLevel, Pjpm) \
114
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, cLevel)) \
115
+ return(j__udyInsertBranch(Pjp, Index, cLevel, Pjpm))
116
+
117
+// Check if an Index is already in a leaf or immediate, after calling
118
+// j__udySearchLeaf*() to set Offset:
119
+//
120
+// A non-negative Offset means the Index already exists, so return 0; otherwise
121
+// complement Offset to proceed.
122
+
123
+#ifdef JUDY1
124
+#define Pjv ignore // placeholder.
125
+#define JU_CHECK_IF_EXISTS(Offset,ignore,Pjpm) \
126
+ { \
127
+ if ((Offset) >= 0) return(0); \
128
+ (Offset) = ~(Offset); \
129
+ }
130
+#else
131
+// For JudyL, also set the value area pointer in the Pjpm:
132
+
133
+#define JU_CHECK_IF_EXISTS(Offset,Pjv,Pjpm) \
134
+ { \
135
+ if ((Offset) >= 0) \
136
+ { \
137
+ (Pjpm)->jpm_PValue = (Pjv) + (Offset); \
138
+ return(0); \
139
+ } \
140
+ (Offset) = ~(Offset); \
141
+ }
142
+#endif
143
+
144
+
145
+// ****************************************************************************
146
+// __ J U D Y I N S W A L K
147
+//
148
+// Walk the Judy tree to do a set/insert. This is only called internally, and
149
+// recursively. Unlike Judy1Test() and JudyLGet(), the extra time required for
150
+// recursion should be negligible compared with the total.
151
+//
152
+// Return -1 for error (details in JPM), 0 for Index already inserted, 1 for
153
+// new Index inserted.
154
+
155
+FUNCTION static int j__udyInsWalk(
156
+ Pjp_t Pjp, // current JP to descend.
157
+ Word_t Index, // to insert.
158
+ Pjpm_t Pjpm) // for returning info to top Level.
159
+{
160
+ uint8_t digit; // from Index, current offset into a branch.
161
+ jp_t newJP; // for creating a new Immed JP.
162
+ Word_t exppop1; // expanse (leaf) population.
163
+ int retcode; // return codes: -1, 0, 1.
164
+
165
+#ifdef SUBEXPCOUNTS
166
+// Pointer to BranchB/U subexpanse counter:
167
+//
168
+// Note: Very important for performance reasons (avoids cache fills).
169
+
170
+ PWord_t PSubExp = (PWord_t) NULL;
171
+#endif
172
+
173
+ContinueInsWalk: // for modifying state without recursing.
174
+
175
+#ifdef TRACEJP
176
+ JudyPrintJP(Pjp, "i", __LINE__);
177
+#endif
178
+
179
+ switch (JU_JPTYPE(Pjp)) // entry: Pjp, Index.
180
+ {
181
+
182
+
183
+// ****************************************************************************
184
+// JPNULL*:
185
+//
186
+// Convert JP in place from current null type to cJU_JPIMMED_*_01 by
187
+// calculating new JP type.
188
+
189
+ case cJU_JPNULL1:
190
+ case cJU_JPNULL2:
191
+ case cJU_JPNULL3:
192
+#ifdef JU_64BIT
193
+ case cJU_JPNULL4:
194
+ case cJU_JPNULL5:
195
+ case cJU_JPNULL6:
196
+ case cJU_JPNULL7:
197
+#endif
198
+ assert((Pjp->jp_Addr) == 0);
199
+ JU_JPSETADT(Pjp, 0, Index, JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01 - cJU_JPNULL1);
200
+#ifdef JUDYL
201
+ // value area is first word of new Immed_01 JP:
202
+ Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr));
203
+#endif
204
+ return(1);
205
+
206
+
207
+// ****************************************************************************
208
+// JPBRANCH_L*:
209
+//
210
+// If the new Index is not an outlier to the branchs expanse, and the branch
211
+// should not be converted to uncompressed, extract the digit and record the
212
+// Immediate type to create for a new Immed JP, before going to common code.
213
+//
214
+// Note: JU_CHECK_IF_OUTLIER() is a no-op for BranchB3[7] on 32[64]-bit.
215
+
216
+#define JU_BRANCH_OUTLIER(DIGIT,POP1,cLEVEL,PJP,INDEX,PJPM) \
217
+ JU_CHECK_IF_OUTLIER(PJP, INDEX, cLEVEL, PJPM); \
218
+ (DIGIT) = JU_DIGITATSTATE(INDEX, cLEVEL); \
219
+ (POP1) = JU_JPBRANCH_POP0(PJP, cLEVEL)
220
+
221
+ case cJU_JPBRANCH_L2:
222
+ JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm);
223
+ goto JudyBranchL;
224
+
225
+ case cJU_JPBRANCH_L3:
226
+ JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm);
227
+ goto JudyBranchL;
228
+
229
+#ifdef JU_64BIT
230
+ case cJU_JPBRANCH_L4:
231
+ JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm);
232
+ goto JudyBranchL;
233
+
234
+ case cJU_JPBRANCH_L5:
235
+ JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm);
236
+ goto JudyBranchL;
237
+
238
+ case cJU_JPBRANCH_L6:
239
+ JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm);
240
+ goto JudyBranchL;
241
+
242
+ case cJU_JPBRANCH_L7:
243
+ JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm);
244
+ goto JudyBranchL;
245
+#endif
246
+
247
+// Similar to common code above, but no outlier check is needed, and the Immed
248
+// type depends on the word size:
249
+
250
+ case cJU_JPBRANCH_L:
251
+ {
252
+ Pjbl_t PjblRaw; // pointer to old linear branch.
253
+ Pjbl_t Pjbl;
254
+ Pjbu_t PjbuRaw; // pointer to new uncompressed branch.
255
+ Pjbu_t Pjbu;
256
+ Word_t numJPs; // number of JPs = populated expanses.
257
+ int offset; // in branch.
258
+
259
+ digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
260
+ exppop1 = Pjpm->jpm_Pop0;
261
+
262
+ // fall through:
263
+
264
+// COMMON CODE FOR LINEAR BRANCHES:
265
+//
266
+// Come here with digit and exppop1 already set.
267
+
268
+JudyBranchL:
269
+ PjblRaw = (Pjbl_t) (Pjp->jp_Addr);
270
+ Pjbl = P_JBL(PjblRaw);
271
+
272
+// If population under this branch greater than:
273
+
274
+ if (exppop1 > JU_BRANCHL_MAX_POP)
275
+ goto ConvertBranchLtoU;
276
+
277
+ numJPs = Pjbl->jbl_NumJPs;
278
+
279
+ if ((numJPs == 0) || (numJPs > cJU_BRANCHLMAXJPS))
280
+ {
281
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
282
+ return(-1);
283
+ }
284
+
285
+// Search for a match to the digit:
286
+
287
+ offset = j__udySearchLeaf1((Pjll_t) (Pjbl->jbl_Expanse), numJPs,
288
+ digit);
289
+
290
+// If Index is found, offset is into an array of 1..cJU_BRANCHLMAXJPS JPs:
291
+
292
+ if (offset >= 0)
293
+ {
294
+ Pjp = (Pjbl->jbl_jp) + offset; // address of next JP.
295
+ break; // continue walk.
296
+ }
297
+
298
+// Expanse is missing (not populated) for the passed Index, so insert an Immed
299
+// -- if theres room:
300
+
301
+ if (numJPs < cJU_BRANCHLMAXJPS)
302
+ {
303
+ offset = ~offset; // insertion offset.
304
+
305
+ JU_JPSETADT(&newJP, 0, Index,
306
+ JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01-cJU_JPBRANCH_L2);
307
+
308
+ JU_INSERTINPLACE(Pjbl->jbl_Expanse, numJPs, offset, digit);
309
+ JU_INSERTINPLACE(Pjbl->jbl_jp, numJPs, offset, newJP);
310
+
311
+ DBGCODE(JudyCheckSorted((Pjll_t) (Pjbl->jbl_Expanse),
312
+ numJPs + 1, /* IndexSize = */ 1);)
313
+ ++(Pjbl->jbl_NumJPs);
314
+#ifdef JUDYL
315
+ // value area is first word of new Immed 01 JP:
316
+ Pjpm->jpm_PValue = (Pjv_t) ((Pjbl->jbl_jp) + offset);
317
+#endif
318
+ return(1);
319
+ }
320
+
321
+
322
+// MAXED OUT LINEAR BRANCH, CONVERT TO A BITMAP BRANCH, THEN INSERT:
323
+//
324
+// Copy the linear branch to a bitmap branch.
325
+//
326
+// TBD: Consider renaming j__udyCreateBranchB() to j__udyConvertBranchLtoB().
327
+
328
+ assert((numJPs) <= cJU_BRANCHLMAXJPS);
329
+
330
+ if (j__udyCreateBranchB(Pjp, Pjbl->jbl_jp, Pjbl->jbl_Expanse,
331
+ numJPs, Pjpm) == -1)
332
+ {
333
+ return(-1);
334
+ }
335
+
336
+// Convert jp_Type from linear branch to equivalent bitmap branch:
337
+
338
+ Pjp->jp_Type += cJU_JPBRANCH_B - cJU_JPBRANCH_L;
339
+
340
+ j__udyFreeJBL(PjblRaw, Pjpm); // free old BranchL.
341
+
342
+// Having changed branch types, now do the insert in the new branch type:
343
+
344
+ goto ContinueInsWalk;
345
+
346
+
347
+// OPPORTUNISTICALLY CONVERT FROM BRANCHL TO BRANCHU:
348
+//
349
+// Memory efficiency is no object because the branchs pop1 is large enough, so
350
+// speed up array access. Come here with PjblRaw set. Note: This is goto
351
+// code because the previous block used to fall through into it as well, but no
352
+// longer.
353
+
354
+ConvertBranchLtoU:
355
+
356
+// Allocate memory for an uncompressed branch:
357
+
358
+ if ((PjbuRaw = j__udyAllocJBU(Pjpm)) == (Pjbu_t) NULL)
359
+ return(-1);
360
+ Pjbu = P_JBU(PjbuRaw);
361
+
362
+// Set the proper NULL type for most of the uncompressed branchs JPs:
363
+
364
+ JU_JPSETADT(&newJP, 0, 0,
365
+ JU_JPTYPE(Pjp) - cJU_JPBRANCH_L2 + cJU_JPNULL1);
366
+
367
+// Initialize: Pre-set uncompressed branch to mostly JPNULL*s:
368
+
369
+ for (numJPs = 0; numJPs < cJU_BRANCHUNUMJPS; ++numJPs)
370
+ Pjbu->jbu_jp[numJPs] = newJP;
371
+
372
+// Copy JPs from linear branch to uncompressed branch:
373
+
374
+ {
375
+#ifdef SUBEXPCOUNTS
376
+ Word_t popmask = cJU_POP0MASK(JU_JPTYPE(Pjp))
377
+ - cJU_JPBRANCH_L2 - 2;
378
+
379
+ for (numJPs = 0; numJPs < cJU_NUMSUBEXPU; ++numJPs)
380
+ Pjbu->jbu_subPop1[numJPs] = 0;
381
+#endif
382
+ for (numJPs = 0; numJPs < Pjbl->jbl_NumJPs; ++numJPs)
383
+ {
384
+ Pjp_t Pjp1 = &(Pjbl->jbl_jp[numJPs]);
385
+ offset = Pjbl->jbl_Expanse[numJPs];
386
+ Pjbu->jbu_jp[offset] = *Pjp1;
387
+#ifdef SUBEXPCOUNTS
388
+ Pjbu->jbu_subPop1[offset/cJU_NUMSUBEXPU] +=
389
+ JU_JPDCDPOP0(Pjp1) & popmask + 1;
390
+#endif
391
+ }
392
+ }
393
+ j__udyFreeJBL(PjblRaw, Pjpm); // free old BranchL.
394
+
395
+// Plug new values into parent JP:
396
+
397
+ Pjp->jp_Addr = (Word_t) PjbuRaw;
398
+ Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_L; // to BranchU.
399
+
400
+// Save global population of last BranchU conversion:
401
+
402
+ Pjpm->jpm_LastUPop0 = Pjpm->jpm_Pop0;
403
+ goto ContinueInsWalk;
404
+
405
+ } // case cJU_JPBRANCH_L.
406
+
407
+
408
+// ****************************************************************************
409
+// JPBRANCH_B*:
410
+//
411
+// If the new Index is not an outlier to the branchs expanse, extract the
412
+// digit and record the Immediate type to create for a new Immed JP, before
413
+// going to common code.
414
+//
415
+// Note: JU_CHECK_IF_OUTLIER() is a no-op for BranchB3[7] on 32[64]-bit.
416
+
417
+ case cJU_JPBRANCH_B2:
418
+ JU_BRANCH_OUTLIER(digit, exppop1, 2, Pjp, Index, Pjpm);
419
+ goto JudyBranchB;
420
+
421
+ case cJU_JPBRANCH_B3:
422
+ JU_BRANCH_OUTLIER(digit, exppop1, 3, Pjp, Index, Pjpm);
423
+ goto JudyBranchB;
424
+
425
+#ifdef JU_64BIT
426
+ case cJU_JPBRANCH_B4:
427
+ JU_BRANCH_OUTLIER(digit, exppop1, 4, Pjp, Index, Pjpm);
428
+ goto JudyBranchB;
429
+
430
+ case cJU_JPBRANCH_B5:
431
+ JU_BRANCH_OUTLIER(digit, exppop1, 5, Pjp, Index, Pjpm);
432
+ goto JudyBranchB;
433
+
434
+ case cJU_JPBRANCH_B6:
435
+ JU_BRANCH_OUTLIER(digit, exppop1, 6, Pjp, Index, Pjpm);
436
+ goto JudyBranchB;
437
+
438
+ case cJU_JPBRANCH_B7:
439
+ JU_BRANCH_OUTLIER(digit, exppop1, 7, Pjp, Index, Pjpm);
440
+ goto JudyBranchB;
441
+#endif
442
+
443
+ case cJU_JPBRANCH_B:
444
+ {
445
+ Pjbb_t Pjbb; // pointer to bitmap branch.
446
+ Pjbb_t PjbbRaw; // pointer to bitmap branch.
447
+ Pjp_t Pjp2Raw; // 1 of N arrays of JPs.
448
+ Pjp_t Pjp2; // 1 of N arrays of JPs.
449
+ Word_t subexp; // 1 of N subexpanses in bitmap.
450
+ BITMAPB_t bitmap; // for one subexpanse.
451
+ BITMAPB_t bitmask; // bit set for Indexs digit.
452
+ Word_t numJPs; // number of JPs = populated expanses.
453
+ int offset; // in bitmap branch.
454
+
455
+// Similar to common code above, but no outlier check is needed, and the Immed
456
+// type depends on the word size:
457
+
458
+ digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
459
+ exppop1 = Pjpm->jpm_Pop0;
460
+
461
+ // fall through:
462
+
463
+
464
+// COMMON CODE FOR BITMAP BRANCHES:
465
+//
466
+// Come here with digit and exppop1 already set.
467
+
468
+JudyBranchB:
469
+
470
+// If population increment is greater than.. (300):
471
+
472
+ if ((Pjpm->jpm_Pop0 - Pjpm->jpm_LastUPop0) > JU_BTOU_POP_INCREMENT)
473
+ {
474
+
475
+// If total population of array is greater than.. (750):
476
+
477
+ if (Pjpm->jpm_Pop0 > JU_BRANCHB_MAX_POP)
478
+ {
479
+
480
+// If population under the branch is greater than.. (135):
481
+
482
+ if (exppop1 > JU_BRANCHB_MIN_POP)
483
+ {
484
+ if (j__udyCreateBranchU(Pjp, Pjpm) == -1) return(-1);
485
+
486
+// Save global population of last BranchU conversion:
487
+
488
+ Pjpm->jpm_LastUPop0 = Pjpm->jpm_Pop0;
489
+
490
+ goto ContinueInsWalk;
491
+ }
492
+ }
493
+ }
494
+
495
+// CONTINUE TO USE BRANCHB:
496
+//
497
+// Get pointer to bitmap branch (JBB):
498
+
499
+ PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
500
+ Pjbb = P_JBB(PjbbRaw);
501
+
502
+// Form the Int32 offset, and Bit offset values:
503
+//
504
+// 8 bit Decode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
505
+// |SubExpanse | Bit offset |
506
+//
507
+// Get the 1 of 8 expanses from digit, Bits 5..7 = 1 of 8, and get the 32-bit
508
+// word that may have a bit set:
509
+
510
+ subexp = digit / cJU_BITSPERSUBEXPB;
511
+ bitmap = JU_JBB_BITMAP(Pjbb, subexp);
512
+
513
+ Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
514
+ Pjp2 = P_JP(Pjp2Raw);
515
+
516
+// Get the bit position that represents the desired expanse, and get the offset
517
+// into the array of JPs for the JP that matches the bit.
518
+
519
+ bitmask = JU_BITPOSMASKB(digit);
520
+ offset = j__udyCountBitsB(bitmap & (bitmask - 1));
521
+
522
+// If JP is already in this expanse, get Pjp and continue the walk:
523
+
524
+ if (bitmap & bitmask)
525
+ {
526
+#ifdef SUBEXPCOUNTS
527
+ PSubExp = &(Pjbb->jbb_Counts[subexp]); // ptr to subexp counts.
528
+#endif
529
+ Pjp = Pjp2 + offset;
530
+ break; // continue walk.
531
+ }
532
+
533
+
534
+// ADD NEW EXPANSE FOR NEW INDEX:
535
+//
536
+// The new expanse always an cJU_JPIMMED_*_01 containing just the new Index, so
537
+// finish setting up an Immed JP.
538
+
539
+ JU_JPSETADT(&newJP, 0, Index,
540
+ JU_JPTYPE(Pjp) + cJU_JPIMMED_1_01-cJU_JPBRANCH_B2);
541
+
542
+// Get 1 of the 8 JP arrays and calculate number of JPs in subexpanse array:
543
+
544
+ Pjp2Raw = JU_JBB_PJP(Pjbb, subexp);
545
+ Pjp2 = P_JP(Pjp2Raw);
546
+ numJPs = j__udyCountBitsB(bitmap);
547
+
548
+// Expand branch JP subarray in-place:
549
+
550
+ if (JU_BRANCHBJPGROWINPLACE(numJPs))
551
+ {
552
+ assert(numJPs > 0);
553
+ JU_INSERTINPLACE(Pjp2, numJPs, offset, newJP);
554
+#ifdef JUDYL
555
+ // value area is first word of new Immed 01 JP:
556
+ Pjpm->jpm_PValue = (Pjv_t) (Pjp2 + offset);
557
+#endif
558
+ }
559
+
560
+// No room, allocate a bigger bitmap branch JP subarray:
561
+
562
+ else
563
+ {
564
+ Pjp_t PjpnewRaw;
565
+ Pjp_t Pjpnew;
566
+
567
+ if ((PjpnewRaw = j__udyAllocJBBJP(numJPs + 1, Pjpm)) == 0)
568
+ return(-1);
569
+ Pjpnew = P_JP(PjpnewRaw);
570
+
571
+// If there was an old JP array, then copy it, insert the new Immed JP, and
572
+// free the old array:
573
+
574
+ if (numJPs)
575
+ {
576
+ JU_INSERTCOPY(Pjpnew, Pjp2, numJPs, offset, newJP);
577
+ j__udyFreeJBBJP(Pjp2Raw, numJPs, Pjpm);
578
+#ifdef JUDYL
579
+ // value area is first word of new Immed 01 JP:
580
+ Pjpm->jpm_PValue = (Pjv_t) (Pjpnew + offset);
581
+#endif
582
+ }
583
+
584
+// New JP subarray; point to cJU_JPIMMED_*_01 and place it:
585
+
586
+ else
587
+ {
588
+ assert(JU_JBB_PJP(Pjbb, subexp) == (Pjp_t) NULL);
589
+ Pjp = Pjpnew;
590
+ *Pjp = newJP; // copy to new memory.
591
+#ifdef JUDYL
592
+ // value area is first word of new Immed 01 JP:
593
+ Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr));
594
+#endif
595
+ }
596
+
597
+// Place new JP subarray in BranchB:
598
+
599
+ JU_JBB_PJP(Pjbb, subexp) = PjpnewRaw;
600
+
601
+ } // else
602
+
603
+// Set the new Indexs bit:
604
+
605
+ JU_JBB_BITMAP(Pjbb, subexp) |= bitmask;
606
+
607
+ return(1);
608
+
609
+ } // case
610
+
611
+
612
+// ****************************************************************************
613
+// JPBRANCH_U*:
614
+//
615
+// Just drop through the JP for the correct digit. If the JP turns out to be a
616
+// JPNULL*, thats OK, the memory is already allocated, and the next walk
617
+// simply places an Immed in it.
618
+//
619
+#ifdef SUBEXPCOUNTS
620
+#define JU_GETSUBEXP(PSubExp,Pjbu,Digit) \
621
+ (PSubExp) = &((Pjbu)->jbu_subPop1[(Digit) / cJU_NUMSUBEXPU])
622
+#else
623
+#define JU_GETSUBEXP(PSubExp,Pjbu,Digit) // null.
624
+#endif
625
+
626
+#define JU_JBU_PJP_SUBEXP(Pjp,PSubExp,Index,Level) \
627
+ { \
628
+ uint8_t digit = JU_DIGITATSTATE(Index, Level); \
629
+ Pjbu_t P_jbu = P_JBU((Pjp)->jp_Addr); \
630
+ (Pjp) = &(P_jbu->jbu_jp[digit]); \
631
+ JU_GETSUBEXP(PSubExp, P_jbu, digit); \
632
+ }
633
+
634
+ case cJU_JPBRANCH_U2:
635
+ JU_CHECK_IF_OUTLIER(Pjp, Index, 2, Pjpm);
636
+ JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 2);
637
+ break;
638
+
639
+#ifdef JU_64BIT
640
+ case cJU_JPBRANCH_U3:
641
+ JU_CHECK_IF_OUTLIER(Pjp, Index, 3, Pjpm);
642
+ JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3);
643
+ break;
644
+
645
+ case cJU_JPBRANCH_U4:
646
+ JU_CHECK_IF_OUTLIER(Pjp, Index, 4, Pjpm);
647
+ JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 4);
648
+ break;
649
+
650
+ case cJU_JPBRANCH_U5:
651
+ JU_CHECK_IF_OUTLIER(Pjp, Index, 5, Pjpm);
652
+ JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 5);
653
+ break;
654
+
655
+ case cJU_JPBRANCH_U6:
656
+ JU_CHECK_IF_OUTLIER(Pjp, Index, 6, Pjpm);
657
+ JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 6);
658
+ break;
659
+
660
+ case cJU_JPBRANCH_U7:
661
+ JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 7);
662
+#else
663
+ case cJU_JPBRANCH_U3:
664
+ JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, 3);
665
+#endif
666
+ break;
667
+
668
+ case cJU_JPBRANCH_U:
669
+ JU_JBU_PJP_SUBEXP(Pjp, PSubExp, Index, cJU_ROOTSTATE);
670
+ break;
671
+
672
+
673
+// ****************************************************************************
674
+// JPLEAF*:
675
+//
676
+// COMMON CODE FRAGMENTS TO MINIMIZE REDUNDANCY BELOW:
677
+//
678
+// These are necessary to support performance by function and loop unrolling
679
+// while avoiding huge amounts of nearly identical code.
680
+//
681
+// Prepare to handle a linear leaf: Check for an outlier; set pop1 and pointer
682
+// to leaf:
683
+
684
+#ifdef JUDY1
685
+#define JU_LEAFVALUE(Pjv) // null.
686
+#define JU_LEAFPREPVALUE(Pjv, ValueArea) // null.
687
+#else
688
+#define JU_LEAFVALUE(Pjv) Pjv_t Pjv
689
+#define JU_LEAFPREPVALUE(Pjv, ValueArea) (Pjv) = ValueArea(Pleaf, exppop1)
690
+#endif
691
+
692
+#define JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea) \
693
+ Pjll_t PjllRaw; \
694
+ Type Pleaf; /* specific type */ \
695
+ int offset; \
696
+ JU_LEAFVALUE(Pjv); \
697
+ \
698
+ JU_CHECK_IF_OUTLIER(Pjp, Index, cIS, Pjpm); \
699
+ \
700
+ exppop1 = JU_JPLEAF_POP0(Pjp) + 1; \
701
+ assert(exppop1 <= (MaxPop1)); \
702
+ PjllRaw = (Pjll_t) (Pjp->jp_Addr); \
703
+ Pleaf = (Type) P_JLL(PjllRaw); \
704
+ JU_LEAFPREPVALUE(Pjv, ValueArea)
705
+
706
+// Add to, or grow, a linear leaf: Find Index position; if the Index is
707
+// absent, if theres room in the leaf, insert the Index [and value of 0] in
708
+// place, otherwise grow the leaf:
709
+//
710
+// Note: These insertions always take place with whole words, using
711
+// JU_INSERTINPLACE() or JU_INSERTCOPY().
712
+
713
+#ifdef JUDY1
714
+#define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) // null.
715
+#else
716
+#define JU_LEAFGROWVALUEADD(Pjv,ExpPop1,Offset) \
717
+ JU_INSERTINPLACE(Pjv, ExpPop1, Offset, 0); \
718
+ Pjpm->jpm_PValue = (Pjv) + (Offset)
719
+#endif
720
+
721
+#ifdef JUDY1
722
+#define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) // null.
723
+#else
724
+#define JU_LEAFGROWVALUENEW(ValueArea,Pjv,ExpPop1,Offset) \
725
+ { \
726
+ Pjv_t Pjvnew = ValueArea(Pleafnew, (ExpPop1) + 1); \
727
+ JU_INSERTCOPY(Pjvnew, Pjv, ExpPop1, Offset, 0); \
728
+ Pjpm->jpm_PValue = (Pjvnew) + (Offset); \
729
+ }
730
+#endif
731
+
732
+#define JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \
733
+ InsertInPlace,InsertCopy,Alloc,Free) \
734
+ \
735
+ offset = Search(Pleaf, exppop1, Index); \
736
+ JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
737
+ \
738
+ if (GrowInPlace(exppop1)) /* add to current leaf */ \
739
+ { \
740
+ InsertInPlace(Pleaf, exppop1, offset, Index); \
741
+ JU_LEAFGROWVALUEADD(Pjv, exppop1, offset); \
742
+ DBGCODE(JudyCheckSorted((Pjll_t) Pleaf, exppop1 + 1, cIS);) \
743
+ return(1); \
744
+ } \
745
+ \
746
+ if (exppop1 < (MaxPop1)) /* grow to new leaf */ \
747
+ { \
748
+ Pjll_t PjllnewRaw; \
749
+ Type Pleafnew; \
750
+ if ((PjllnewRaw = Alloc(exppop1 + 1, Pjpm)) == 0) return(-1); \
751
+ Pleafnew = (Type) P_JLL(PjllnewRaw); \
752
+ InsertCopy(Pleafnew, Pleaf, exppop1, offset, Index); \
753
+ JU_LEAFGROWVALUENEW(ValueArea, Pjv, exppop1, offset); \
754
+ DBGCODE(JudyCheckSorted((Pjll_t) Pleafnew, exppop1 + 1, cIS);) \
755
+ Free(PjllRaw, exppop1, Pjpm); \
756
+ (Pjp->jp_Addr) = (Word_t) PjllnewRaw; \
757
+ return(1); \
758
+ } \
759
+ assert(exppop1 == (MaxPop1))
760
+
761
+// Handle linear leaf overflow (cascade): Splay or compress into smaller
762
+// leaves:
763
+
764
+#define JU_LEAFCASCADE(MaxPop1,Cascade,Free) \
765
+ if (Cascade(Pjp, Pjpm) == -1) return(-1); \
766
+ Free(PjllRaw, MaxPop1, Pjpm); \
767
+ goto ContinueInsWalk
768
+
769
+// Wrapper around all of the above:
770
+
771
+#define JU_LEAFSET(cIS,Type,MaxPop1,Search,GrowInPlace,InsertInPlace, \
772
+ InsertCopy,Cascade,Alloc,Free,ValueArea) \
773
+ { \
774
+ JU_LEAFPREP(cIS,Type,MaxPop1,ValueArea); \
775
+ JU_LEAFGROW(cIS,Type,MaxPop1,Search,ValueArea,GrowInPlace, \
776
+ InsertInPlace,InsertCopy,Alloc,Free); \
777
+ JU_LEAFCASCADE(MaxPop1,Cascade,Free); \
778
+ }
779
+
780
+// END OF MACROS; LEAFL CASES START HERE:
781
+//
782
+// 64-bit Judy1 does not have 1-byte leaves:
783
+
784
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
785
+
786
+ case cJU_JPLEAF1:
787
+
788
+ JU_LEAFSET(1, uint8_t *, cJU_LEAF1_MAXPOP1, j__udySearchLeaf1,
789
+ JU_LEAF1GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
790
+ j__udyCascade1, j__udyAllocJLL1, j__udyFreeJLL1,
791
+ JL_LEAF1VALUEAREA);
792
+
793
+#endif // (JUDYL || ! JU_64BIT)
794
+
795
+ case cJU_JPLEAF2:
796
+
797
+ JU_LEAFSET(2, uint16_t *, cJU_LEAF2_MAXPOP1, j__udySearchLeaf2,
798
+ JU_LEAF2GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
799
+ j__udyCascade2, j__udyAllocJLL2, j__udyFreeJLL2,
800
+ JL_LEAF2VALUEAREA);
801
+
802
+ case cJU_JPLEAF3:
803
+
804
+ JU_LEAFSET(3, uint8_t *, cJU_LEAF3_MAXPOP1, j__udySearchLeaf3,
805
+ JU_LEAF3GROWINPLACE, JU_INSERTINPLACE3, JU_INSERTCOPY3,
806
+ j__udyCascade3, j__udyAllocJLL3, j__udyFreeJLL3,
807
+ JL_LEAF3VALUEAREA);
808
+
809
+#ifdef JU_64BIT
810
+ case cJU_JPLEAF4:
811
+
812
+ JU_LEAFSET(4, uint32_t *, cJU_LEAF4_MAXPOP1, j__udySearchLeaf4,
813
+ JU_LEAF4GROWINPLACE, JU_INSERTINPLACE, JU_INSERTCOPY,
814
+ j__udyCascade4, j__udyAllocJLL4, j__udyFreeJLL4,
815
+ JL_LEAF4VALUEAREA);
816
+
817
+ case cJU_JPLEAF5:
818
+
819
+ JU_LEAFSET(5, uint8_t *, cJU_LEAF5_MAXPOP1, j__udySearchLeaf5,
820
+ JU_LEAF5GROWINPLACE, JU_INSERTINPLACE5, JU_INSERTCOPY5,
821
+ j__udyCascade5, j__udyAllocJLL5, j__udyFreeJLL5,
822
+ JL_LEAF5VALUEAREA);
823
+
824
+ case cJU_JPLEAF6:
825
+
826
+ JU_LEAFSET(6, uint8_t *, cJU_LEAF6_MAXPOP1, j__udySearchLeaf6,
827
+ JU_LEAF6GROWINPLACE, JU_INSERTINPLACE6, JU_INSERTCOPY6,
828
+ j__udyCascade6, j__udyAllocJLL6, j__udyFreeJLL6,
829
+ JL_LEAF6VALUEAREA);
830
+
831
+ case cJU_JPLEAF7:
832
+
833
+ JU_LEAFSET(7, uint8_t *, cJU_LEAF7_MAXPOP1, j__udySearchLeaf7,
834
+ JU_LEAF7GROWINPLACE, JU_INSERTINPLACE7, JU_INSERTCOPY7,
835
+ j__udyCascade7, j__udyAllocJLL7, j__udyFreeJLL7,
836
+ JL_LEAF7VALUEAREA);
837
+#endif // JU_64BIT
838
+
839
+
840
+// ****************************************************************************
841
+// JPLEAF_B1:
842
+//
843
+// 8 bit Decode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
844
+// |SubExpanse | Bit offset |
845
+//
846
+// Note: For JudyL, values are stored in 8 subexpanses, each a linear word
847
+// array of up to 32 values each.
848
+
849
+ case cJU_JPLEAF_B1:
850
+ {
851
+#ifdef JUDYL
852
+ Pjv_t PjvRaw; // pointer to value part of the leaf.
853
+ Pjv_t Pjv; // pointer to value part of the leaf.
854
+ Pjv_t PjvnewRaw; // new value area.
855
+ Pjv_t Pjvnew; // new value area.
856
+ Word_t subexp; // 1 of 8 subexpanses in bitmap.
857
+ Pjlb_t Pjlb; // pointer to bitmap part of the leaf.
858
+ BITMAPL_t bitmap; // for one subexpanse.
859
+ BITMAPL_t bitmask; // bit set for Indexs digit.
860
+ int offset; // of index in value area.
861
+#endif
862
+
863
+ JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm);
864
+
865
+#ifdef JUDY1
866
+
867
+// If Index (bit) is already set, return now:
868
+
869
+ if (JU_BITMAPTESTL(P_JLB(Pjp->jp_Addr), Index)) return(0);
870
+
871
+// If bitmap is not full, set the new Indexs bit; otherwise convert to a Full:
872
+
873
+ if ((exppop1 = JU_JPLEAF_POP0(Pjp) + 1)
874
+ < cJU_JPFULLPOPU1_POP0)
875
+ {
876
+ JU_BITMAPSETL(P_JLB(Pjp->jp_Addr), Index);
877
+ }
878
+ else
879
+ {
880
+ j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm); // free LeafB1.
881
+ Pjp->jp_Type = cJ1_JPFULLPOPU1;
882
+ Pjp->jp_Addr = 0;
883
+ }
884
+
885
+#else // JUDYL
886
+
887
+// This is very different from Judy1 because of the need to return a value area
888
+// even for an existing Index, or manage the value area for a new Index, and
889
+// because JudyL has no Full type:
890
+
891
+// Get last byte to decode from Index, and pointer to bitmap leaf:
892
+
893
+ digit = JU_DIGITATSTATE(Index, 1);
894
+ Pjlb = P_JLB(Pjp->jp_Addr);
895
+
896
+// Prepare additional values:
897
+
898
+ subexp = digit / cJU_BITSPERSUBEXPL; // which subexpanse.
899
+ bitmap = JU_JLB_BITMAP(Pjlb, subexp); // subexps 32-bit map.
900
+ PjvRaw = JL_JLB_PVALUE(Pjlb, subexp); // corresponding values.
901
+ Pjv = P_JV(PjvRaw); // corresponding values.
902
+ bitmask = JU_BITPOSMASKL(digit); // mask for Index.
903
+ offset = j__udyCountBitsL(bitmap & (bitmask - 1)); // of Index.
904
+
905
+// If Index already exists, get value pointer and exit:
906
+
907
+ if (bitmap & bitmask)
908
+ {
909
+ assert(Pjv);
910
+ Pjpm->jpm_PValue = Pjv + offset; // existing value.
911
+ return(0);
912
+ }
913
+
914
+// Get the total bits set = expanse population of Value area:
915
+
916
+ exppop1 = j__udyCountBitsL(bitmap);
917
+
918
+// If the value area can grow in place, do it:
919
+
920
+ if (JL_LEAFVGROWINPLACE(exppop1))
921
+ {
922
+ JU_INSERTINPLACE(Pjv, exppop1, offset, 0);
923
+ JU_JLB_BITMAP(Pjlb, subexp) |= bitmask; // set Indexs bit.
924
+ Pjpm->jpm_PValue = Pjv + offset; // new value area.
925
+ return(1);
926
+ }
927
+
928
+// Increase size of value area:
929
+
930
+ if ((PjvnewRaw = j__udyLAllocJV(exppop1 + 1, Pjpm))
931
+ == (Pjv_t) NULL) return(-1);
932
+ Pjvnew = P_JV(PjvnewRaw);
933
+
934
+ if (exppop1) // have existing value area.
935
+ {
936
+ assert(Pjv);
937
+ JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0);
938
+ Pjpm->jpm_PValue = Pjvnew + offset;
939
+ j__udyLFreeJV(PjvRaw, exppop1, Pjpm); // free old values.
940
+ }
941
+ else // first index, new value area:
942
+ {
943
+ Pjpm->jpm_PValue = Pjvnew;
944
+ *(Pjpm->jpm_PValue) = 0;
945
+ }
946
+
947
+// Set bit for new Index and place new leaf value area in bitmap:
948
+
949
+ JU_JLB_BITMAP(Pjlb, subexp) |= bitmask;
950
+ JL_JLB_PVALUE(Pjlb, subexp) = PjvnewRaw;
951
+
952
+#endif // JUDYL
953
+
954
+ return(1);
955
+
956
+ } // case
957
+
958
+
959
+#ifdef JUDY1
960
+// ****************************************************************************
961
+// JPFULLPOPU1:
962
+//
963
+// If Index is not an outlier, then by definition its already set.
964
+
965
+ case cJ1_JPFULLPOPU1:
966
+
967
+ JU_CHECK_IF_OUTLIER(Pjp, Index, 1, Pjpm);
968
+ return(0);
969
+#endif
970
+
971
+
972
+// ****************************************************************************
973
+// JPIMMED*:
974
+//
975
+// This is some of the most complex code in Judy considering Judy1 versus JudyL
976
+// and 32-bit versus 64-bit variations. The following comments attempt to make
977
+// this clearer.
978
+//
979
+// Of the 2 words in a JP, for immediate indexes Judy1 can use 2 words - 1 byte
980
+// = 7 [15] bytes, but JudyL can only use 1 word - 1 byte = 3 [7] bytes because
981
+// the other word is needed for a value area or a pointer to a value area.
982
+//
983
+// For both Judy1 and JudyL, cJU_JPIMMED_*_01 indexes are in word 2; otherwise
984
+// for Judy1 only, a list of 2 or more indexes starts in word 1. JudyL keeps
985
+// the list in word 2 because word 1 is a pointer (to a LeafV, that is, a leaf
986
+// containing only values). Furthermore, cJU_JPIMMED_*_01 indexes are stored
987
+// all-but-first-byte in jp_DcdPopO, not just the Index Sizes bytes.
988
+//
989
+// TBD: This can be confusing because Doug didnt use data structures for it.
990
+// Instead he often directly accesses Pjp for the first word and jp_DcdPopO for
991
+// the second word. It would be nice to use data structs, starting with
992
+// jp_1Index and jp_LIndex where possible.
993
+//
994
+// Maximum Immed JP types for Judy1/JudyL, depending on Index Size (cIS):
995
+//
996
+// 32-bit 64-bit
997
+//
998
+// bytes: 7/ 3 15/ 7 (Judy1/JudyL)
999
+//
1000
+// cIS
1001
+// 1_ 07/03 15/07 (as in: cJ1_JPIMMED_1_07)
1002
+// 2_ 03/01 07/03
1003
+// 3_ 02/01 05/02
1004
+// 4_ 03/01
1005
+// 5_ 03/01
1006
+// 6_ 02/01
1007
+// 7_ 02/01
1008
+//
1009
+// State transitions while inserting an Index, matching the above table:
1010
+// (Yes, this is very terse... Study it and it will make sense.)
1011
+// (Note, parts of this diagram are repeated below for quick reference.)
1012
+//
1013
+// +-- reformat JP here for Judy1 only, from word-2 to word-1
1014
+// |
1015
+// | JUDY1 || JU_64BIT JUDY1 && JU_64BIT
1016
+// V
1017
+// 1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] Leaf1 (*)
1018
+// 2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] Leaf2
1019
+// 3_01 => [ 3_02 => [ 3_03..05 => ]] Leaf3
1020
+// JU_64BIT only:
1021
+// 4_01 => [[ 4_02..03 => ]] Leaf4
1022
+// 5_01 => [[ 5_02..03 => ]] Leaf5
1023
+// 6_01 => [[ 6_02 => ]] Leaf6
1024
+// 7_01 => [[ 7_02 => ]] Leaf7
1025
+//
1026
+// (*) For Judy1 & 64-bit, go directly from cJU_JPIMMED_1_15 to a LeafB1; skip
1027
+// Leaf1, as described in Judy1.h regarding cJ1_JPLEAF1.
1028
+
1029
+
1030
+// COMMON CODE FRAGMENTS TO MINIMIZE REDUNDANCY BELOW:
1031
+//
1032
+// These are necessary to support performance by function and loop unrolling
1033
+// while avoiding huge amounts of nearly identical code.
1034
+//
1035
+// The differences between Judy1 and JudyL with respect to value area handling
1036
+// are just too large for completely common code between them... Oh well, some
1037
+// big ifdefs follow. However, even in the following ifdefd code, use cJU_*,
1038
+// JU_*, and Judy*() instead of cJ1_* / cJL_*, J1_* / JL_*, and
1039
+// Judy1*()/JudyL*(), for minimum diffs.
1040
+//
1041
+// Handle growth of cJU_JPIMMED_*_01 to cJU_JPIMMED_*_02, for an even or odd
1042
+// Index Size (cIS), given oldIndex, Index, and Pjll in the context:
1043
+//
1044
+// Put oldIndex and Index in their proper order. For odd indexes, must copy
1045
+// bytes.
1046
+
1047
+#ifdef JUDY1
1048
+
1049
+#define JU_IMMSET_01_COPY_EVEN(ignore1,ignore2) \
1050
+ if (oldIndex < Index) { Pjll[0] = oldIndex; Pjll[1] = Index; } \
1051
+ else { Pjll[0] = Index; Pjll[1] = oldIndex; }
1052
+
1053
+#define JU_IMMSET_01_COPY_ODD(cIS,CopyWord) \
1054
+ if (oldIndex < Index) \
1055
+ { \
1056
+ CopyWord(Pjll + 0, oldIndex); \
1057
+ CopyWord(Pjll + (cIS), Index); \
1058
+ } \
1059
+ else \
1060
+ { \
1061
+ CopyWord(Pjll + 0, Index); \
1062
+ CopyWord(Pjll + (cIS), oldIndex); \
1063
+ }
1064
+
1065
+// The "real" *_01 Copy macro:
1066
+//
1067
+// Trim the high byte off Index, look for a match with the old Index, and if
1068
+// none, insert the new Index in the leaf in the correct place, given Pjp and
1069
+// Index in the context.
1070
+//
1071
+// Note: A single immediate index lives in the jp_DcdPopO field, but two or
1072
+// more reside starting at Pjp->jp_1Index.
1073
+
1074
+#define JU_IMMSET_01_COPY(cIS,LeafType,NewJPType,Copy,CopyWord) \
1075
+ { \
1076
+ LeafType Pjll; \
1077
+ Word_t oldIndex = JU_JPDCDPOP0(Pjp); \
1078
+ \
1079
+ Index = JU_TRIMTODCDSIZE(Index); \
1080
+ if (oldIndex == Index) return(0); \
1081
+ \
1082
+ Pjll = (LeafType) (Pjp->jp_1Index); \
1083
+ Copy(cIS,CopyWord); \
1084
+ DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \
1085
+ \
1086
+ Pjp->jp_Type = (NewJPType); \
1087
+ return(1); \
1088
+ }
1089
+
1090
+#else // JUDYL
1091
+
1092
+// Variations to also handle value areas; see comments above:
1093
+//
1094
+// For JudyL, Pjv (start of value area) and oldValue are also in the context;
1095
+// leave Pjv set to the value area for Index.
1096
+
1097
+#define JU_IMMSET_01_COPY_EVEN(cIS,CopyWord) \
1098
+ if (oldIndex < Index) \
1099
+ { \
1100
+ Pjll[0] = oldIndex; \
1101
+ Pjv [0] = oldValue; \
1102
+ Pjll[1] = Index; \
1103
+ ++Pjv; \
1104
+ } \
1105
+ else \
1106
+ { \
1107
+ Pjll[0] = Index; \
1108
+ Pjll[1] = oldIndex; \
1109
+ Pjv [1] = oldValue; \
1110
+ }
1111
+
1112
+#define JU_IMMSET_01_COPY_ODD(cIS,CopyWord) \
1113
+ if (oldIndex < Index) \
1114
+ { \
1115
+ CopyWord(Pjll + 0, oldIndex); \
1116
+ CopyWord(Pjll + (cIS), Index); \
1117
+ Pjv[0] = oldValue; \
1118
+ ++Pjv; \
1119
+ } \
1120
+ else \
1121
+ { \
1122
+ CopyWord(Pjll + 0, Index); \
1123
+ CopyWord(Pjll + (cIS), oldIndex); \
1124
+ Pjv[1] = oldValue; \
1125
+ }
1126
+
1127
+// The old value area is in the first word (*Pjp), and Pjv and Pjpm are also in
1128
+// the context. Also, unlike Judy1, indexes remain in word 2 (jp_LIndex),
1129
+// meaning insert-in-place rather than copy.
1130
+//
1131
+// Return jpm_PValue pointing to Indexs value area. If Index is new, allocate
1132
+// a 2-value-leaf and attach it to the JP.
1133
+
1134
+#define JU_IMMSET_01_COPY(cIS,LeafType,NewJPType,Copy,CopyWord) \
1135
+ { \
1136
+ LeafType Pjll; \
1137
+ Word_t oldIndex = JU_JPDCDPOP0(Pjp); \
1138
+ Word_t oldValue; \
1139
+ Pjv_t PjvRaw; \
1140
+ Pjv_t Pjv; \
1141
+ \
1142
+ Index = JU_TRIMTODCDSIZE(Index); \
1143
+ \
1144
+ if (oldIndex == Index) \
1145
+ { \
1146
+ Pjpm->jpm_PValue = (Pjv_t) Pjp; \
1147
+ return(0); \
1148
+ } \
1149
+ \
1150
+ if ((PjvRaw = j__udyLAllocJV(2, Pjpm)) == (Pjv_t) NULL) \
1151
+ return(-1); \
1152
+ Pjv = P_JV(PjvRaw); \
1153
+ \
1154
+ oldValue = Pjp->jp_Addr; \
1155
+ (Pjp->jp_Addr) = (Word_t) PjvRaw; \
1156
+ Pjll = (LeafType) (Pjp->jp_LIndex); \
1157
+ \
1158
+ Copy(cIS,CopyWord); \
1159
+ DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \
1160
+ \
1161
+ Pjp->jp_Type = (NewJPType); \
1162
+ *Pjv = 0; \
1163
+ Pjpm->jpm_PValue = Pjv; \
1164
+ return(1); \
1165
+ }
1166
+
1167
+// The following is a unique mix of JU_IMMSET_01() and JU_IMMSETCASCADE() for
1168
+// going from cJU_JPIMMED_*_01 directly to a cJU_JPLEAF* for JudyL:
1169
+//
1170
+// If Index is not already set, allocate a leaf, copy the old and new indexes
1171
+// into it, clear and return the new value area, and modify the current JP.
1172
+// Note that jp_DcdPop is set to a pop0 of 0 for now, and incremented later.
1173
+
1174
+
1175
+#define JU_IMMSET_01_CASCADE(cIS,LeafType,NewJPType,ValueArea, \
1176
+ Copy,CopyWord,Alloc) \
1177
+ { \
1178
+ Word_t D_P0; \
1179
+ LeafType PjllRaw; \
1180
+ LeafType Pjll; \
1181
+ Word_t oldIndex = JU_JPDCDPOP0(Pjp); \
1182
+ Word_t oldValue; \
1183
+ Pjv_t Pjv; \
1184
+ \
1185
+ Index = JU_TRIMTODCDSIZE(Index); \
1186
+ \
1187
+ if (oldIndex == Index) \
1188
+ { \
1189
+ Pjpm->jpm_PValue = (Pjv_t) (&(Pjp->jp_Addr)); \
1190
+ return(0); \
1191
+ } \
1192
+ \
1193
+ if ((PjllRaw = (LeafType) Alloc(2, Pjpm)) == (LeafType) NULL) \
1194
+ return(-1); \
1195
+ Pjll = (LeafType) P_JLL(PjllRaw); \
1196
+ Pjv = ValueArea(Pjll, 2); \
1197
+ \
1198
+ oldValue = Pjp->jp_Addr; \
1199
+ \
1200
+ Copy(cIS,CopyWord); \
1201
+ DBGCODE(JudyCheckSorted(Pjll, 2, cIS);) \
1202
+ \
1203
+ *Pjv = 0; \
1204
+ Pjpm->jpm_PValue = Pjv; \
1205
+ D_P0 = Index & cJU_DCDMASK(cIS); /* pop0 = 0 */ \
1206
+ JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \
1207
+ \
1208
+ return(1); \
1209
+ }
1210
+
1211
+#endif // JUDYL
1212
+
1213
+// Handle growth of cJU_JPIMMED_*_[02..15]:
1214
+
1215
+#ifdef JUDY1
1216
+
1217
+// Insert an Index into an immediate JP that has room for more, if the Index is
1218
+// not already present; given Pjp, Index, exppop1, Pjv, and Pjpm in the
1219
+// context:
1220
+//
1221
+// Note: Use this only when the JP format doesnt change, that is, going from
1222
+// cJU_JPIMMED_X_0Y to cJU_JPIMMED_X_0Z, where X >= 2 and Y+1 = Z.
1223
+//
1224
+// Note: Incrementing jp_Type is how to increase the Index population.
1225
+
1226
+#define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \
1227
+ { \
1228
+ LeafType Pjll; \
1229
+ int offset; \
1230
+ \
1231
+ exppop1 = JU_JPTYPE(Pjp) - (BaseJPType_02) + 2; \
1232
+ offset = Search((Pjll_t) (Pjp->jp_1Index), exppop1, Index); \
1233
+ \
1234
+ JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \
1235
+ \
1236
+ Pjll = (LeafType) (Pjp->jp_1Index); \
1237
+ InsertInPlace(Pjll, exppop1, offset, Index); \
1238
+ DBGCODE(JudyCheckSorted(Pjll, exppop1 + 1, cIS);) \
1239
+ ++(Pjp->jp_Type); \
1240
+ return(1); \
1241
+ }
1242
+
1243
+// Insert an Index into an immediate JP that has no room for more:
1244
+//
1245
+// If the Index is not already present, do a cascade (to a leaf); given Pjp,
1246
+// Index, Pjv, and Pjpm in the context.
1247
+
1248
+
1249
+#define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \
1250
+ ignore,Search,InsertCopy,Alloc) \
1251
+ { \
1252
+ Word_t D_P0; \
1253
+ Pjll_t PjllRaw; \
1254
+ Pjll_t Pjll; \
1255
+ int offset; \
1256
+ \
1257
+ offset = Search((Pjll_t) (Pjp->jp_1Index), (OldPop1), Index); \
1258
+ JU_CHECK_IF_EXISTS(offset, ignore, Pjpm); \
1259
+ \
1260
+ if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) return(-1); \
1261
+ Pjll = P_JLL(PjllRaw); \
1262
+ \
1263
+ InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_1Index), \
1264
+ OldPop1, offset, Index); \
1265
+ DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \
1266
+ \
1267
+ D_P0 = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \
1268
+ JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \
1269
+ return(1); \
1270
+ }
1271
+
1272
+#else // JUDYL
1273
+
1274
+// Variations to also handle value areas; see comments above:
1275
+//
1276
+// For JudyL, Pjv (start of value area) is also in the context.
1277
+//
1278
+// TBD: This code makes a true but weak assumption that a JudyL 32-bit 2-index
1279
+// value area must be copied to a new 3-index value area. AND it doesnt know
1280
+// anything about JudyL 64-bit cases (cJU_JPIMMED_1_0[3-7] only) where the
1281
+// value area can grow in place! However, this should not break it, just slow
1282
+// it down.
1283
+
1284
+#define JU_IMMSETINPLACE(cIS,LeafType,BaseJPType_02,Search,InsertInPlace) \
1285
+ { \
1286
+ LeafType Pleaf; \
1287
+ int offset; \
1288
+ Pjv_t PjvRaw; \
1289
+ Pjv_t Pjv; \
1290
+ Pjv_t PjvnewRaw; \
1291
+ Pjv_t Pjvnew; \
1292
+ \
1293
+ exppop1 = JU_JPTYPE(Pjp) - (BaseJPType_02) + 2; \
1294
+ offset = Search((Pjll_t) (Pjp->jp_LIndex), exppop1, Index); \
1295
+ PjvRaw = (Pjv_t) (Pjp->jp_Addr); \
1296
+ Pjv = P_JV(PjvRaw); \
1297
+ \
1298
+ JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
1299
+ \
1300
+ if ((PjvnewRaw = j__udyLAllocJV(exppop1 + 1, Pjpm)) \
1301
+ == (Pjv_t) NULL) return(-1); \
1302
+ Pjvnew = P_JV(PjvnewRaw); \
1303
+ \
1304
+ Pleaf = (LeafType) (Pjp->jp_LIndex); \
1305
+ \
1306
+ InsertInPlace(Pleaf, exppop1, offset, Index); \
1307
+ /* see TBD above about this: */ \
1308
+ JU_INSERTCOPY(Pjvnew, Pjv, exppop1, offset, 0); \
1309
+ DBGCODE(JudyCheckSorted(Pleaf, exppop1 + 1, cIS);) \
1310
+ j__udyLFreeJV(PjvRaw, exppop1, Pjpm); \
1311
+ Pjp->jp_Addr = (Word_t) PjvnewRaw; \
1312
+ Pjpm->jpm_PValue = Pjvnew + offset; \
1313
+ \
1314
+ ++(Pjp->jp_Type); \
1315
+ return(1); \
1316
+ }
1317
+
1318
+#define JU_IMMSETCASCADE(cIS,OldPop1,LeafType,NewJPType, \
1319
+ ValueArea,Search,InsertCopy,Alloc) \
1320
+ { \
1321
+ Word_t D_P0; \
1322
+ Pjll_t PjllRaw; \
1323
+ Pjll_t Pjll; \
1324
+ int offset; \
1325
+ Pjv_t PjvRaw; \
1326
+ Pjv_t Pjv; \
1327
+ Pjv_t Pjvnew; \
1328
+ \
1329
+ PjvRaw = (Pjv_t) (Pjp->jp_Addr); \
1330
+ Pjv = P_JV(PjvRaw); \
1331
+ offset = Search((Pjll_t) (Pjp->jp_LIndex), (OldPop1), Index); \
1332
+ JU_CHECK_IF_EXISTS(offset, Pjv, Pjpm); \
1333
+ \
1334
+ if ((PjllRaw = Alloc((OldPop1) + 1, Pjpm)) == 0) \
1335
+ return(-1); \
1336
+ Pjll = P_JLL(PjllRaw); \
1337
+ InsertCopy((LeafType) Pjll, (LeafType) (Pjp->jp_LIndex), \
1338
+ OldPop1, offset, Index); \
1339
+ DBGCODE(JudyCheckSorted(Pjll, (OldPop1) + 1, cIS);) \
1340
+ \
1341
+ Pjvnew = ValueArea(Pjll, (OldPop1) + 1); \
1342
+ JU_INSERTCOPY(Pjvnew, Pjv, OldPop1, offset, 0); \
1343
+ j__udyLFreeJV(PjvRaw, (OldPop1), Pjpm); \
1344
+ Pjpm->jpm_PValue = Pjvnew + offset; \
1345
+ \
1346
+ D_P0 = (Index & cJU_DCDMASK(cIS)) + (OldPop1) - 1; \
1347
+ JU_JPSETADT(Pjp, (Word_t)PjllRaw, D_P0, NewJPType); \
1348
+ return(1); \
1349
+ }
1350
+
1351
+#endif // JUDYL
1352
+
1353
+// Common convenience/shorthand wrappers around JU_IMMSET_01_COPY() for
1354
+// even/odd index sizes:
1355
+
1356
+#define JU_IMMSET_01( cIS, LeafType, NewJPType) \
1357
+ JU_IMMSET_01_COPY(cIS, LeafType, NewJPType, JU_IMMSET_01_COPY_EVEN, \
1358
+ ignore)
1359
+
1360
+#define JU_IMMSET_01_ODD( cIS, NewJPType, CopyWord) \
1361
+ JU_IMMSET_01_COPY(cIS, uint8_t *, NewJPType, JU_IMMSET_01_COPY_ODD, \
1362
+ CopyWord)
1363
+
1364
+
1365
+// END OF MACROS; IMMED CASES START HERE:
1366
+
1367
+// cJU_JPIMMED_*_01 cases:
1368
+//
1369
+// 1_01 always leads to 1_02:
1370
+//
1371
+// (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL)
1372
+
1373
+ case cJU_JPIMMED_1_01: JU_IMMSET_01(1, uint8_t *, cJU_JPIMMED_1_02);
1374
+
1375
+// 2_01 leads to 2_02, and 3_01 leads to 3_02, except for JudyL 32-bit, where
1376
+// they lead to a leaf:
1377
+//
1378
+// (2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] LeafL)
1379
+// (3_01 => [ 3_02 => [ 3_03..05 => ]] LeafL)
1380
+
1381
+#if (defined(JUDY1) || defined(JU_64BIT))
1382
+ case cJU_JPIMMED_2_01: JU_IMMSET_01(2, uint16_t *, cJU_JPIMMED_2_02);
1383
+ case cJU_JPIMMED_3_01: JU_IMMSET_01_ODD (3, cJU_JPIMMED_3_02,
1384
+ JU_COPY3_LONG_TO_PINDEX);
1385
+#else
1386
+ case cJU_JPIMMED_2_01:
1387
+ JU_IMMSET_01_CASCADE(2, uint16_t *, cJU_JPLEAF2, JL_LEAF2VALUEAREA,
1388
+ JU_IMMSET_01_COPY_EVEN, ignore,
1389
+ j__udyAllocJLL2);
1390
+ case cJU_JPIMMED_3_01:
1391
+ JU_IMMSET_01_CASCADE(3, uint8_t *, cJU_JPLEAF3, JL_LEAF3VALUEAREA,
1392
+ JU_IMMSET_01_COPY_ODD,
1393
+ JU_COPY3_LONG_TO_PINDEX, j__udyAllocJLL3);
1394
+#endif
1395
+
1396
+#ifdef JU_64BIT
1397
+
1398
+// [4-7]_01 lead to [4-7]_02 for Judy1, and to leaves for JudyL:
1399
+//
1400
+// (4_01 => [[ 4_02..03 => ]] LeafL)
1401
+// (5_01 => [[ 5_02..03 => ]] LeafL)
1402
+// (6_01 => [[ 6_02 => ]] LeafL)
1403
+// (7_01 => [[ 7_02 => ]] LeafL)
1404
+
1405
+#ifdef JUDY1
1406
+ case cJU_JPIMMED_4_01: JU_IMMSET_01(4, uint32_t *, cJ1_JPIMMED_4_02);
1407
+ case cJU_JPIMMED_5_01: JU_IMMSET_01_ODD(5, cJ1_JPIMMED_5_02,
1408
+ JU_COPY5_LONG_TO_PINDEX);
1409
+ case cJU_JPIMMED_6_01: JU_IMMSET_01_ODD(6, cJ1_JPIMMED_6_02,
1410
+ JU_COPY6_LONG_TO_PINDEX);
1411
+ case cJU_JPIMMED_7_01: JU_IMMSET_01_ODD(7, cJ1_JPIMMED_7_02,
1412
+ JU_COPY7_LONG_TO_PINDEX);
1413
+#else // JUDYL
1414
+ case cJU_JPIMMED_4_01:
1415
+ JU_IMMSET_01_CASCADE(4, uint32_t *, cJU_JPLEAF4, JL_LEAF4VALUEAREA,
1416
+ JU_IMMSET_01_COPY_EVEN, ignore,
1417
+ j__udyAllocJLL4);
1418
+ case cJU_JPIMMED_5_01:
1419
+ JU_IMMSET_01_CASCADE(5, uint8_t *, cJU_JPLEAF5, JL_LEAF5VALUEAREA,
1420
+ JU_IMMSET_01_COPY_ODD,
1421
+ JU_COPY5_LONG_TO_PINDEX, j__udyAllocJLL5);
1422
+ case cJU_JPIMMED_6_01:
1423
+ JU_IMMSET_01_CASCADE(6, uint8_t *, cJU_JPLEAF6, JL_LEAF6VALUEAREA,
1424
+ JU_IMMSET_01_COPY_ODD,
1425
+ JU_COPY6_LONG_TO_PINDEX, j__udyAllocJLL6);
1426
+ case cJU_JPIMMED_7_01:
1427
+ JU_IMMSET_01_CASCADE(7, uint8_t *, cJU_JPLEAF7, JL_LEAF7VALUEAREA,
1428
+ JU_IMMSET_01_COPY_ODD,
1429
+ JU_COPY7_LONG_TO_PINDEX, j__udyAllocJLL7);
1430
+#endif // JUDYL
1431
+#endif // JU_64BIT
1432
+
1433
+// cJU_JPIMMED_1_* cases that can grow in place:
1434
+//
1435
+// (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL)
1436
+
1437
+ case cJU_JPIMMED_1_02:
1438
+#if (defined(JUDY1) || defined(JU_64BIT))
1439
+ case cJU_JPIMMED_1_03:
1440
+ case cJU_JPIMMED_1_04:
1441
+ case cJU_JPIMMED_1_05:
1442
+ case cJU_JPIMMED_1_06:
1443
+#endif
1444
+#if (defined(JUDY1) && defined(JU_64BIT))
1445
+ case cJU_JPIMMED_1_07:
1446
+ case cJ1_JPIMMED_1_08:
1447
+ case cJ1_JPIMMED_1_09:
1448
+ case cJ1_JPIMMED_1_10:
1449
+ case cJ1_JPIMMED_1_11:
1450
+ case cJ1_JPIMMED_1_12:
1451
+ case cJ1_JPIMMED_1_13:
1452
+ case cJ1_JPIMMED_1_14:
1453
+#endif
1454
+ JU_IMMSETINPLACE(1, uint8_t *, cJU_JPIMMED_1_02, j__udySearchLeaf1,
1455
+ JU_INSERTINPLACE);
1456
+
1457
+// cJU_JPIMMED_1_* cases that must cascade:
1458
+//
1459
+// (1_01 => 1_02 => 1_03 => [ 1_04 => ... => 1_07 => [ 1_08..15 => ]] LeafL)
1460
+
1461
+#if (defined(JUDYL) && (! defined(JU_64BIT)))
1462
+ case cJU_JPIMMED_1_03:
1463
+ JU_IMMSETCASCADE(1, 3, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA,
1464
+ j__udySearchLeaf1, JU_INSERTCOPY,
1465
+ j__udyAllocJLL1);
1466
+#endif
1467
+#if (defined(JUDY1) && (! defined(JU_64BIT)))
1468
+ case cJU_JPIMMED_1_07:
1469
+ JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, ignore,
1470
+ j__udySearchLeaf1, JU_INSERTCOPY,
1471
+ j__udyAllocJLL1);
1472
+
1473
+#endif
1474
+#if (defined(JUDYL) && defined(JU_64BIT))
1475
+ case cJU_JPIMMED_1_07:
1476
+ JU_IMMSETCASCADE(1, 7, uint8_t *, cJU_JPLEAF1, JL_LEAF1VALUEAREA,
1477
+ j__udySearchLeaf1, JU_INSERTCOPY,
1478
+ j__udyAllocJLL1);
1479
+
1480
+#endif
1481
+#if (defined(JUDY1) && defined(JU_64BIT))
1482
+// Special case, as described above, go directly from Immed to LeafB1:
1483
+
1484
+ case cJ1_JPIMMED_1_15:
1485
+ {
1486
+ Word_t DcdP0;
1487
+ int offset;
1488
+ Pjlb_t PjlbRaw;
1489
+ Pjlb_t Pjlb;
1490
+
1491
+ offset = j__udySearchLeaf1((Pjll_t) Pjp->jp_1Index, 15, Index);
1492
+
1493
+ JU_CHECK_IF_EXISTS(offset, ignore, Pjpm);
1494
+
1495
+// Create a bitmap leaf (special case for Judy1 64-bit only, see usage): Set
1496
+// new Index in bitmap, copy an Immed1_15 to the bitmap, and set the parent JP
1497
+// EXCEPT jp_DcdPopO, leaving any followup to the caller:
1498
+
1499
+ if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL)
1500
+ return(-1);
1501
+ Pjlb = P_JLB(PjlbRaw);
1502
+
1503
+ JU_BITMAPSETL(Pjlb, Index);
1504
+
1505
+ for (offset = 0; offset < 15; ++offset)
1506
+ JU_BITMAPSETL(Pjlb, Pjp->jp_1Index[offset]);
1507
+
1508
+// Set jp_DcdPopO including the current pop0; incremented later:
1509
+ DcdP0 = (Index & cJU_DCDMASK(1)) + 15 - 1;
1510
+ JU_JPSETADT(Pjp, (Word_t)PjlbRaw, DcdP0, cJU_JPLEAF_B1);
1511
+
1512
+ return(1);
1513
+ }
1514
+#endif
1515
+
1516
+// cJU_JPIMMED_[2..7]_[02..15] cases that grow in place or cascade:
1517
+//
1518
+// (2_01 => [ 2_02 => 2_03 => [ 2_04..07 => ]] LeafL)
1519
+
1520
+#if (defined(JUDY1) || defined(JU_64BIT))
1521
+ case cJU_JPIMMED_2_02:
1522
+#endif
1523
+#if (defined(JUDY1) && defined(JU_64BIT))
1524
+ case cJU_JPIMMED_2_03:
1525
+ case cJ1_JPIMMED_2_04:
1526
+ case cJ1_JPIMMED_2_05:
1527
+ case cJ1_JPIMMED_2_06:
1528
+#endif
1529
+#if (defined(JUDY1) || defined(JU_64BIT))
1530
+ JU_IMMSETINPLACE(2, uint16_t *, cJU_JPIMMED_2_02, j__udySearchLeaf2,
1531
+ JU_INSERTINPLACE);
1532
+#endif
1533
+
1534
+#undef OLDPOP1
1535
+#if ((defined(JUDY1) && (! defined(JU_64BIT))) || (defined(JUDYL) && defined(JU_64BIT)))
1536
+ case cJU_JPIMMED_2_03:
1537
+#define OLDPOP1 3
1538
+#endif
1539
+#if (defined(JUDY1) && defined(JU_64BIT))
1540
+ case cJ1_JPIMMED_2_07:
1541
+#define OLDPOP1 7
1542
+#endif
1543
+#if (defined(JUDY1) || defined(JU_64BIT))
1544
+ JU_IMMSETCASCADE(2, OLDPOP1, uint16_t *, cJU_JPLEAF2,
1545
+ JL_LEAF2VALUEAREA, j__udySearchLeaf2,
1546
+ JU_INSERTCOPY, j__udyAllocJLL2);
1547
+#endif
1548
+
1549
+// (3_01 => [ 3_02 => [ 3_03..05 => ]] LeafL)
1550
+
1551
+#if (defined(JUDY1) && defined(JU_64BIT))
1552
+ case cJU_JPIMMED_3_02:
1553
+ case cJ1_JPIMMED_3_03:
1554
+ case cJ1_JPIMMED_3_04:
1555
+
1556
+ JU_IMMSETINPLACE(3, uint8_t *, cJU_JPIMMED_3_02, j__udySearchLeaf3,
1557
+ JU_INSERTINPLACE3);
1558
+#endif
1559
+
1560
+#undef OLDPOP1
1561
+#if ((defined(JUDY1) && (! defined(JU_64BIT))) || (defined(JUDYL) && defined(JU_64BIT)))
1562
+ case cJU_JPIMMED_3_02:
1563
+#define OLDPOP1 2
1564
+#endif
1565
+#if (defined(JUDY1) && defined(JU_64BIT))
1566
+ case cJ1_JPIMMED_3_05:
1567
+#define OLDPOP1 5
1568
+#endif
1569
+#if (defined(JUDY1) || defined(JU_64BIT))
1570
+ JU_IMMSETCASCADE(3, OLDPOP1, uint8_t *, cJU_JPLEAF3,
1571
+ JL_LEAF3VALUEAREA, j__udySearchLeaf3,
1572
+ JU_INSERTCOPY3, j__udyAllocJLL3);
1573
+#endif
1574
+
1575
+#if (defined(JUDY1) && defined(JU_64BIT))
1576
+
1577
+// (4_01 => [[ 4_02..03 => ]] LeafL)
1578
+
1579
+ case cJ1_JPIMMED_4_02:
1580
+
1581
+ JU_IMMSETINPLACE(4, uint32_t *, cJ1_JPIMMED_4_02, j__udySearchLeaf4,
1582
+ JU_INSERTINPLACE);
1583
+
1584
+ case cJ1_JPIMMED_4_03:
1585
+
1586
+ JU_IMMSETCASCADE(4, 3, uint32_t *, cJU_JPLEAF4, ignore,
1587
+ j__udySearchLeaf4, JU_INSERTCOPY,
1588
+ j__udyAllocJLL4);
1589
+
1590
+// (5_01 => [[ 5_02..03 => ]] LeafL)
1591
+
1592
+ case cJ1_JPIMMED_5_02:
1593
+
1594
+ JU_IMMSETINPLACE(5, uint8_t *, cJ1_JPIMMED_5_02, j__udySearchLeaf5,
1595
+ JU_INSERTINPLACE5);
1596
+
1597
+ case cJ1_JPIMMED_5_03:
1598
+
1599
+ JU_IMMSETCASCADE(5, 3, uint8_t *, cJU_JPLEAF5, ignore,
1600
+ j__udySearchLeaf5, JU_INSERTCOPY5,
1601
+ j__udyAllocJLL5);
1602
+
1603
+// (6_01 => [[ 6_02 => ]] LeafL)
1604
+
1605
+ case cJ1_JPIMMED_6_02:
1606
+
1607
+ JU_IMMSETCASCADE(6, 2, uint8_t *, cJU_JPLEAF6, ignore,
1608
+ j__udySearchLeaf6, JU_INSERTCOPY6,
1609
+ j__udyAllocJLL6);
1610
+
1611
+// (7_01 => [[ 7_02 => ]] LeafL)
1612
+
1613
+ case cJ1_JPIMMED_7_02:
1614
+
1615
+ JU_IMMSETCASCADE(7, 2, uint8_t *, cJU_JPLEAF7, ignore,
1616
+ j__udySearchLeaf7, JU_INSERTCOPY7,
1617
+ j__udyAllocJLL7);
1618
+
1619
+#endif // (JUDY1 && JU_64BIT)
1620
+
1621
+
1622
+// ****************************************************************************
1623
+// INVALID JP TYPE:
1624
+
1625
+ default: JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT); return(-1);
1626
+
1627
+ } // switch on JP type
1628
+
1629
+ {
1630
+
1631
+#ifdef SUBEXPCOUNTS
1632
+
1633
+// This code might seem strange here. However it saves some memory read time
1634
+// during insert (~70nS) because a pipelined processor does not need to "stall"
1635
+// waiting for the memory read to complete. Hope the compiler is not too smart
1636
+// or dumb and moves the code down to where it looks like it belongs (below a
1637
+// few lines).
1638
+
1639
+ Word_t SubExpCount = 0; // current subexpanse counter.
1640
+
1641
+ if (PSubExp != (PWord_t) NULL) // only if BranchB/U.
1642
+ SubExpCount = PSubExp[0];
1643
+#endif
1644
+
1645
+// PROCESS JP -- RECURSIVELY:
1646
+//
1647
+// For non-Immed JP types, if successful, post-increment the population count
1648
+// at this Level.
1649
+
1650
+ retcode = j__udyInsWalk(Pjp, Index, Pjpm);
1651
+
1652
+// Successful insert, increment JP and subexpanse count:
1653
+
1654
+ if ((JU_JPTYPE(Pjp) < cJU_JPIMMED_1_01) && (retcode == 1))
1655
+ {
1656
+ jp_t JP;
1657
+ Word_t DcdP0;
1658
+#ifdef SUBEXPCOUNTS
1659
+
1660
+// Note: Pjp must be a pointer to a BranchB/U:
1661
+
1662
+ if (PSubExp != (PWord_t) NULL) PSubExp[0] = SubExpCount + 1;
1663
+#endif
1664
+
1665
+ JP = *Pjp;
1666
+ DcdP0 = JU_JPDCDPOP0(Pjp) + 1;
1667
+ JU_JPSETADT(Pjp, JP.jp_Addr, DcdP0, JU_JPTYPE(&JP));
1668
+ }
1669
+ }
1670
+ return(retcode);
1671
+
1672
+} // j__udyInsWalk()
1673
+
1674
+
1675
+// ****************************************************************************
1676
+// J U D Y 1 S E T
1677
+// J U D Y L I N S
1678
+//
1679
+// Main entry point. See the manual entry for details.
1680
+
1681
+#ifdef JUDY1
1682
+FUNCTION int Judy1Set
1683
+#else
1684
+FUNCTION PPvoid_t JudyLIns
1685
+#endif
1686
+ (
1687
+ PPvoid_t PPArray, // in which to insert.
1688
+ Word_t Index, // to insert.
1689
+ PJError_t PJError // optional, for returning error info.
1690
+ )
1691
+{
1692
+#ifdef JUDY1
1693
+#define Pjv ignore // placeholders for macros.
1694
+#define Pjvnew ignore
1695
+#else
1696
+ Pjv_t Pjv; // value area in old leaf.
1697
+ Pjv_t Pjvnew; // value area in new leaf.
1698
+#endif
1699
+ Pjpm_t Pjpm; // array-global info.
1700
+ int offset; // position in which to store new Index.
1701
+ Pjlw_t Pjlw;
1702
+
1703
+
1704
+// CHECK FOR NULL POINTER (error by caller):
1705
+
1706
+ if (PPArray == (PPvoid_t) NULL)
1707
+ {
1708
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
1709
+ JUDY1CODE(return(JERRI );)
1710
+ JUDYLCODE(return(PPJERR);)
1711
+ }
1712
+
1713
+ Pjlw = P_JLW(*PPArray); // first word of leaf.
1714
+
1715
+// ****************************************************************************
1716
+// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAVES:
1717
+
1718
+// ****************************************************************************
1719
+// JRPNULL (EMPTY ARRAY): BUILD A LEAFW WITH ONE INDEX:
1720
+
1721
+// if a valid empty array (null pointer), so create an array of population == 1:
1722
+
1723
+ if (Pjlw == (Pjlw_t)NULL)
1724
+ {
1725
+ Pjlw_t Pjlwnew;
1726
+
1727
+ Pjlwnew = j__udyAllocJLW(1);
1728
+ JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );)
1729
+ JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);)
1730
+
1731
+ Pjlwnew[0] = 1 - 1; // pop0 = 0.
1732
+ Pjlwnew[1] = Index;
1733
+
1734
+ *PPArray = (Pvoid_t) Pjlwnew;
1735
+ DBGCODE(JudyCheckPop(*PPArray);)
1736
+
1737
+ JUDY1CODE(return(1); )
1738
+ JUDYLCODE(Pjlwnew[2] = 0; ) // value area.
1739
+ JUDYLCODE(return((PPvoid_t) (Pjlwnew + 2)); )
1740
+
1741
+ } // NULL JRP
1742
+
1743
+// ****************************************************************************
1744
+// LEAFW, OTHER SIZE:
1745
+
1746
+ if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
1747
+ {
1748
+ Pjlw_t Pjlwnew;
1749
+ Word_t pop1;
1750
+
1751
+ Pjlw = P_JLW(*PPArray); // first word of leaf.
1752
+ pop1 = Pjlw[0] + 1;
1753
+
1754
+#ifdef JUDYL
1755
+ Pjv = JL_LEAFWVALUEAREA(Pjlw, pop1);
1756
+#endif
1757
+ offset = j__udySearchLeafW(Pjlw + 1, pop1, Index);
1758
+
1759
+ if (offset >= 0) // index is already valid:
1760
+ {
1761
+ DBGCODE(JudyCheckPop(*PPArray);)
1762
+ JUDY1CODE(return(0); )
1763
+ JUDYLCODE(return((PPvoid_t) (Pjv + offset)); )
1764
+ }
1765
+
1766
+ offset = ~offset;
1767
+
1768
+// Insert index in cases where no new memory is needed:
1769
+
1770
+ if (JU_LEAFWGROWINPLACE(pop1))
1771
+ {
1772
+ ++Pjlw[0]; // increase population.
1773
+
1774
+ JU_INSERTINPLACE(Pjlw + 1, pop1, offset, Index);
1775
+#ifdef JUDYL
1776
+ JU_INSERTINPLACE(Pjv, pop1, offset, 0);
1777
+#endif
1778
+ DBGCODE(JudyCheckPop(*PPArray);)
1779
+ DBGCODE(JudyCheckSorted(Pjlw + 1, pop1 + 1, cJU_ROOTSTATE);)
1780
+
1781
+ JUDY1CODE(return(1); )
1782
+ JUDYLCODE(return((PPvoid_t) (Pjv + offset)); )
1783
+ }
1784
+
1785
+// Insert index into a new, larger leaf:
1786
+
1787
+ if (pop1 < cJU_LEAFW_MAXPOP1) // can grow to a larger leaf.
1788
+ {
1789
+ Pjlwnew = j__udyAllocJLW(pop1 + 1);
1790
+ JUDY1CODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, JERRI );)
1791
+ JUDYLCODE(JU_CHECKALLOC(Pjlw_t, Pjlwnew, PPJERR);)
1792
+
1793
+ Pjlwnew[0] = pop1; // set pop0 in new leaf.
1794
+
1795
+ JU_INSERTCOPY(Pjlwnew + 1, Pjlw + 1, pop1, offset, Index);
1796
+#ifdef JUDYL
1797
+ Pjvnew = JL_LEAFWVALUEAREA(Pjlwnew, pop1 + 1);
1798
+ JU_INSERTCOPY(Pjvnew, Pjv, pop1, offset, 0);
1799
+#endif
1800
+ DBGCODE(JudyCheckSorted(Pjlwnew + 1, pop1 + 1, cJU_ROOTSTATE);)
1801
+
1802
+ j__udyFreeJLW(Pjlw, pop1, NULL);
1803
+
1804
+ *PPArray = (Pvoid_t) Pjlwnew;
1805
+ DBGCODE(JudyCheckPop(*PPArray);)
1806
+
1807
+ JUDY1CODE(return(1); )
1808
+ JUDYLCODE(return((PPvoid_t) (Pjvnew + offset)); )
1809
+ }
1810
+
1811
+ assert(pop1 == cJU_LEAFW_MAXPOP1);
1812
+
1813
+// Leaf at max size => cannot insert new index, so cascade instead:
1814
+//
1815
+// Upon cascading from a LEAFW leaf to the first branch, must allocate and
1816
+// initialize a JPM.
1817
+
1818
+ Pjpm = j__udyAllocJPM();
1819
+ JUDY1CODE(JU_CHECKALLOC(Pjpm_t, Pjpm, JERRI );)
1820
+ JUDYLCODE(JU_CHECKALLOC(Pjpm_t, Pjpm, PPJERR);)
1821
+
1822
+ (Pjpm->jpm_Pop0) = cJU_LEAFW_MAXPOP1 - 1;
1823
+ (Pjpm->jpm_JP.jp_Addr) = (Word_t) Pjlw;
1824
+
1825
+ if (j__udyCascadeL(&(Pjpm->jpm_JP), Pjpm) == -1)
1826
+ {
1827
+ JU_COPY_ERRNO(PJError, Pjpm);
1828
+ JUDY1CODE(return(JERRI );)
1829
+ JUDYLCODE(return(PPJERR);)
1830
+ }
1831
+
1832
+// Note: No need to pass Pjpm for memory decrement; LEAFW memory is never
1833
+// counted in a JPM at all:
1834
+
1835
+ j__udyFreeJLW(Pjlw, cJU_LEAFW_MAXPOP1, NULL);
1836
+ *PPArray = (Pvoid_t) Pjpm;
1837
+
1838
+ } // JU_LEAFW
1839
+
1840
+// ****************************************************************************
1841
+// BRANCH:
1842
+
1843
+ {
1844
+ int retcode; // really only needed for Judy1, but free for JudyL.
1845
+
1846
+ Pjpm = P_JPM(*PPArray);
1847
+ retcode = j__udyInsWalk(&(Pjpm->jpm_JP), Index, Pjpm);
1848
+
1849
+ if (retcode == -1)
1850
+ {
1851
+ JU_COPY_ERRNO(PJError, Pjpm);
1852
+ JUDY1CODE(return(JERRI );)
1853
+ JUDYLCODE(return(PPJERR);)
1854
+ }
1855
+
1856
+ if (retcode == 1) ++(Pjpm->jpm_Pop0); // incr total array popu.
1857
+
1858
+ assert(((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_L)
1859
+ || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_B)
1860
+ || ((Pjpm->jpm_JP.jp_Type) == cJU_JPBRANCH_U));
1861
+ DBGCODE(JudyCheckPop(*PPArray);)
1862
+
1863
+#ifdef JUDY1
1864
+ assert((retcode == 0) || (retcode == 1));
1865
+ return(retcode); // == JU_RET_*_JPM().
1866
+#else
1867
+ assert(Pjpm->jpm_PValue != (Pjv_t) NULL);
1868
+ return((PPvoid_t) Pjpm->jpm_PValue);
1869
+#endif
1870
+ }
1871
+ /*NOTREACHED*/
1872
+
1873
+} // Judy1Set() / JudyLIns()
libnetdata/libjudy/src/JudyL/JudyLInsArray.c
new
+1178
@@ -0,0 +1,1178 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// TBD: It would probably be faster for the caller if the JudyL version took
19
+// PIndex as an interleaved array of indexes and values rather than just
20
+// indexes with a separate values array (PValue), especially considering
21
+// indexes and values are copied here with for-loops anyway and not the
22
+// equivalent of memcpy(). All code could be revised to simply count by two
23
+// words for JudyL? Supports "streaming" the data to/from disk better later?
24
+// In which case get rid of JU_ERRNO_NULLPVALUE, no longer needed, and simplify
25
+// the API to this code.
26
+// _________________
27
+
28
+// @(#) $Revision: 4.21 $ $Source: /judy/src/JudyCommon/JudyInsArray.c $
29
+//
30
+// Judy1SetArray() and JudyLInsArray() functions for Judy1 and JudyL.
31
+// Compile with one of -DJUDY1 or -DJUDYL.
32
+
33
+#if (! (defined(JUDY1) || defined(JUDYL)))
34
+#error: One of -DJUDY1 or -DJUDYL must be specified.
35
+#endif
36
+
37
+#ifdef JUDY1
38
+#include "Judy1.h"
39
+#else
40
+#include "JudyL.h"
41
+#endif
42
+
43
+#include "JudyPrivate1L.h"
44
+
45
+DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
46
+
47
+
48
+// IMMED AND LEAF SIZE AND BRANCH TYPE ARRAYS:
49
+//
50
+// These support fast and easy lookup by level.
51
+
52
+static uint8_t immed_maxpop1[] = {
53
+ 0,
54
+ cJU_IMMED1_MAXPOP1,
55
+ cJU_IMMED2_MAXPOP1,
56
+ cJU_IMMED3_MAXPOP1,
57
+#ifdef JU_64BIT
58
+ cJU_IMMED4_MAXPOP1,
59
+ cJU_IMMED5_MAXPOP1,
60
+ cJU_IMMED6_MAXPOP1,
61
+ cJU_IMMED7_MAXPOP1,
62
+#endif
63
+ // note: There are no IMMEDs for whole words.
64
+};
65
+
66
+static uint8_t leaf_maxpop1[] = {
67
+ 0,
68
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
69
+ cJU_LEAF1_MAXPOP1,
70
+#else
71
+ 0, // 64-bit Judy1 has no Leaf1.
72
+#endif
73
+ cJU_LEAF2_MAXPOP1,
74
+ cJU_LEAF3_MAXPOP1,
75
+#ifdef JU_64BIT
76
+ cJU_LEAF4_MAXPOP1,
77
+ cJU_LEAF5_MAXPOP1,
78
+ cJU_LEAF6_MAXPOP1,
79
+ cJU_LEAF7_MAXPOP1,
80
+#endif
81
+ // note: Root-level leaves are handled differently.
82
+};
83
+
84
+static uint8_t branchL_JPtype[] = {
85
+ 0,
86
+ 0,
87
+ cJU_JPBRANCH_L2,
88
+ cJU_JPBRANCH_L3,
89
+#ifdef JU_64BIT
90
+ cJU_JPBRANCH_L4,
91
+ cJU_JPBRANCH_L5,
92
+ cJU_JPBRANCH_L6,
93
+ cJU_JPBRANCH_L7,
94
+#endif
95
+ cJU_JPBRANCH_L,
96
+};
97
+
98
+static uint8_t branchB_JPtype[] = {
99
+ 0,
100
+ 0,
101
+ cJU_JPBRANCH_B2,
102
+ cJU_JPBRANCH_B3,
103
+#ifdef JU_64BIT
104
+ cJU_JPBRANCH_B4,
105
+ cJU_JPBRANCH_B5,
106
+ cJU_JPBRANCH_B6,
107
+ cJU_JPBRANCH_B7,
108
+#endif
109
+ cJU_JPBRANCH_B,
110
+};
111
+
112
+static uint8_t branchU_JPtype[] = {
113
+ 0,
114
+ 0,
115
+ cJU_JPBRANCH_U2,
116
+ cJU_JPBRANCH_U3,
117
+#ifdef JU_64BIT
118
+ cJU_JPBRANCH_U4,
119
+ cJU_JPBRANCH_U5,
120
+ cJU_JPBRANCH_U6,
121
+ cJU_JPBRANCH_U7,
122
+#endif
123
+ cJU_JPBRANCH_U,
124
+};
125
+
126
+// Subexpanse masks are similer to JU_DCDMASK() but without the need to clear
127
+// the first digits bits. Avoid doing variable shifts by precomputing a
128
+// lookup array.
129
+
130
+static Word_t subexp_mask[] = {
131
+ 0,
132
+ ~cJU_POP0MASK(1),
133
+ ~cJU_POP0MASK(2),
134
+ ~cJU_POP0MASK(3),
135
+#ifdef JU_64BIT
136
+ ~cJU_POP0MASK(4),
137
+ ~cJU_POP0MASK(5),
138
+ ~cJU_POP0MASK(6),
139
+ ~cJU_POP0MASK(7),
140
+#endif
141
+};
142
+
143
+
144
+// FUNCTION PROTOTYPES:
145
+
146
+static bool_t j__udyInsArray(Pjp_t PjpParent, int Level, PWord_t PPop1,
147
+ PWord_t PIndex,
148
+#ifdef JUDYL
149
+ Pjv_t PValue,
150
+#endif
151
+ Pjpm_t Pjpm);
152
+
153
+
154
+// ****************************************************************************
155
+// J U D Y 1 S E T A R R A Y
156
+// J U D Y L I N S A R R A Y
157
+//
158
+// Main entry point. See the manual entry for external overview.
159
+//
160
+// TBD: Until thats written, note that the function returns 1 for success or
161
+// JERRI for serious error, including insufficient memory to build whole array;
162
+// use Judy*Count() to see how many were stored, the first N of the total
163
+// Count. Also, since it takes Count == Pop1, it cannot handle a full array.
164
+// Also, "sorted" means ascending without duplicates, otherwise you get the
165
+// "unsorted" error.
166
+//
167
+// The purpose of these functions is to allow rapid construction of a large
168
+// Judy array given a sorted list of indexes (and for JudyL, corresponding
169
+// values). At least one customer saw this as useful, and probably it would
170
+// also be useful as a sufficient workaround for fast(er) unload/reload to/from
171
+// disk.
172
+//
173
+// This code is written recursively for simplicity, until/unless someone
174
+// decides to make it faster and more complex. Hopefully recursion is fast
175
+// enough simply because the function is so much faster than a series of
176
+// Set/Ins calls.
177
+
178
+#ifdef JUDY1
179
+FUNCTION int Judy1SetArray
180
+#else
181
+FUNCTION int JudyLInsArray
182
+#endif
183
+ (
184
+ PPvoid_t PPArray, // in which to insert, initially empty.
185
+ Word_t Count, // number of indexes (and values) to insert.
186
+const Word_t * const PIndex, // list of indexes to insert.
187
+#ifdef JUDYL
188
+const Word_t * const PValue, // list of corresponding values.
189
+#endif
190
+ PJError_t PJError // optional, for returning error info.
191
+ )
192
+{
193
+ Pjlw_t Pjlw; // new root-level leaf.
194
+ Pjlw_t Pjlwindex; // first index in root-level leaf.
195
+ int offset; // in PIndex.
196
+
197
+
198
+// CHECK FOR NULL OR NON-NULL POINTER (error by caller):
199
+
200
+ if (PPArray == (PPvoid_t) NULL)
201
+ { JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY); return(JERRI); }
202
+
203
+ if (*PPArray != (Pvoid_t) NULL)
204
+ { JU_SET_ERRNO(PJError, JU_ERRNO_NONNULLPARRAY); return(JERRI); }
205
+
206
+ if (PIndex == (PWord_t) NULL)
207
+ { JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); return(JERRI); }
208
+
209
+#ifdef JUDYL
210
+ if (PValue == (PWord_t) NULL)
211
+ { JU_SET_ERRNO(PJError, JU_ERRNO_NULLPVALUE); return(JERRI); }
212
+#endif
213
+
214
+
215
+// HANDLE LARGE COUNT (= POP1) (typical case):
216
+//
217
+// Allocate and initialize a JPM, set the root pointer to point to it, and then
218
+// build the tree underneath it.
219
+
220
+// Common code for unusual error handling when no JPM available:
221
+
222
+ if (Count > cJU_LEAFW_MAXPOP1) // too big for root-level leaf.
223
+ {
224
+ Pjpm_t Pjpm; // new, to allocate.
225
+
226
+// Allocate JPM:
227
+
228
+ Pjpm = j__udyAllocJPM();
229
+ JU_CHECKALLOC(Pjpm_t, Pjpm, JERRI);
230
+ *PPArray = (Pvoid_t) Pjpm;
231
+
232
+// Set some JPM fields:
233
+
234
+ (Pjpm->jpm_Pop0) = Count - 1;
235
+ // note: (Pjpm->jpm_TotalMemWords) is now initialized.
236
+
237
+// Build Judy tree:
238
+//
239
+// In case of error save the final Count, possibly modified, unless modified to
240
+// 0, in which case free the JPM itself:
241
+
242
+ if (! j__udyInsArray(&(Pjpm->jpm_JP), cJU_ROOTSTATE, &Count,
243
+ (PWord_t) PIndex,
244
+#ifdef JUDYL
245
+ (Pjv_t) PValue,
246
+#endif
247
+ Pjpm))
248
+ {
249
+ JU_COPY_ERRNO(PJError, Pjpm);
250
+
251
+ if (Count) // partial success, adjust pop0:
252
+ {
253
+ (Pjpm->jpm_Pop0) = Count - 1;
254
+ }
255
+ else // total failure, free JPM:
256
+ {
257
+ j__udyFreeJPM(Pjpm, (Pjpm_t) NULL);
258
+ *PPArray = (Pvoid_t) NULL;
259
+ }
260
+
261
+ DBGCODE(JudyCheckPop(*PPArray);)
262
+ return(JERRI);
263
+ }
264
+
265
+ DBGCODE(JudyCheckPop(*PPArray);)
266
+ return(1);
267
+
268
+ } // large count
269
+
270
+
271
+// HANDLE SMALL COUNT (= POP1):
272
+//
273
+// First ensure indexes are in sorted order:
274
+
275
+ for (offset = 1; offset < Count; ++offset)
276
+ {
277
+ if (PIndex[offset - 1] >= PIndex[offset])
278
+ { JU_SET_ERRNO(PJError, JU_ERRNO_UNSORTED); return(JERRI); }
279
+ }
280
+
281
+ if (Count == 0) return(1); // *PPArray remains null.
282
+
283
+ {
284
+ Pjlw = j__udyAllocJLW(Count + 1);
285
+ JU_CHECKALLOC(Pjlw_t, Pjlw, JERRI);
286
+ *PPArray = (Pvoid_t) Pjlw;
287
+ Pjlw[0] = Count - 1; // set pop0.
288
+ Pjlwindex = Pjlw + 1;
289
+ }
290
+
291
+// Copy whole-word indexes (and values) to the root-level leaf:
292
+
293
+ JU_COPYMEM(Pjlwindex, PIndex, Count);
294
+JUDYLCODE(JU_COPYMEM(JL_LEAFWVALUEAREA(Pjlw, Count), PValue, Count));
295
+
296
+ DBGCODE(JudyCheckPop(*PPArray);)
297
+ return(1);
298
+
299
+} // Judy1SetArray() / JudyLInsArray()
300
+
301
+
302
+// ****************************************************************************
303
+// __ J U D Y I N S A R R A Y
304
+//
305
+// Given:
306
+//
307
+// - a pointer to a JP
308
+//
309
+// - the JPs level in the tree, that is, the number of digits left to decode
310
+// in the indexes under the JP (one less than the level of the JPM or branch
311
+// in which the JP resides); cJU_ROOTSTATE on first entry (when JP is the one
312
+// in the JPM), down to 1 for a Leaf1, LeafB1, or FullPop
313
+//
314
+// - a pointer to the number of indexes (and corresponding values) to store in
315
+// this subtree, to modify in case of partial success
316
+//
317
+// - a list of indexes (and for JudyL, corresponding values) to store in this
318
+// subtree
319
+//
320
+// - a JPM for tracking memory usage and returning errors
321
+//
322
+// Recursively build a subtree (immediate indexes, leaf, or branch with
323
+// subtrees) and modify the JP accordingly. On the way down, build a BranchU
324
+// (only) for any expanse with *PPop1 too high for a leaf; on the way out,
325
+// convert the BranchU to a BranchL or BranchB if appropriate. Keep memory
326
+// statistics in the JPM.
327
+//
328
+// Return TRUE for success, or FALSE with error information set in the JPM in
329
+// case of error, in which case leave a partially constructed but healthy tree,
330
+// and modify parent population counts on the way out.
331
+//
332
+// Note: Each call of this function makes all modifications to the PjpParent
333
+// it receives; neither the parent nor child calls do this.
334
+
335
+FUNCTION static bool_t j__udyInsArray(
336
+ Pjp_t PjpParent, // parent JP in/under which to store.
337
+ int Level, // initial digits remaining to decode.
338
+ PWord_t PPop1, // number of indexes to store.
339
+ PWord_t PIndex, // list of indexes to store.
340
+#ifdef JUDYL
341
+ Pjv_t PValue, // list of corresponding values.
342
+#endif
343
+ Pjpm_t Pjpm) // for memory and errors.
344
+{
345
+ Pjp_t Pjp; // lower-level JP.
346
+ Word_t Pjbany; // any type of branch.
347
+ int levelsub; // actual, of Pjps node, <= Level.
348
+ Word_t pop1 = *PPop1; // fast local value.
349
+ Word_t pop1sub; // population of one subexpanse.
350
+ uint8_t JPtype; // current JP type.
351
+ uint8_t JPtype_null; // precomputed value for new branch.
352
+ jp_t JPnull; // precomputed for speed.
353
+ Pjbu_t PjbuRaw; // constructed BranchU.
354
+ Pjbu_t Pjbu;
355
+ int digit; // in BranchU.
356
+ Word_t digitmask; // for a digit in a BranchU.
357
+ Word_t digitshifted; // shifted to correct offset.
358
+ Word_t digitshincr; // increment for digitshifted.
359
+ int offset; // in PIndex, or a bitmap subexpanse.
360
+ int numJPs; // number non-null in a BranchU.
361
+ bool_t retval; // to return from this func.
362
+JUDYLCODE(Pjv_t PjvRaw); // destination value area.
363
+JUDYLCODE(Pjv_t Pjv);
364
+
365
+
366
+// MACROS FOR COMMON CODE:
367
+//
368
+// Note: These use function and local parameters from the context.
369
+// Note: Assume newly allocated memory is zeroed.
370
+
371
+// Indicate whether a sorted list of indexes in PIndex, based on the first and
372
+// last indexes in the list using pop1, are in the same subexpanse between
373
+// Level and L_evel:
374
+//
375
+// This can be confusing! Note that SAMESUBEXP(L) == TRUE means the indexes
376
+// are the same through level L + 1, and it says nothing about level L and
377
+// lower; they might be the same or they might differ.
378
+//
379
+// Note: In principle SAMESUBEXP needs a mask for the digits from Level,
380
+// inclusive, to L_evel, exclusive. But in practice, since the indexes are all
381
+// known to be identical above Level, it just uses a mask for the digits
382
+// through L_evel + 1; see subexp_mask[].
383
+
384
+#define SAMESUBEXP(L_evel) \
385
+ (! ((PIndex[0] ^ PIndex[pop1 - 1]) & subexp_mask[L_evel]))
386
+
387
+// Set PjpParent to a null JP appropriate for the level of the node to which it
388
+// points, which is 1 less than the level of the node in which the JP resides,
389
+// which is by definition Level:
390
+//
391
+// Note: This can set the JPMs JP to an invalid jp_Type, but it doesnt
392
+// matter because the JPM is deleted by the caller.
393
+
394
+#define SETJPNULL_PARENT \
395
+ JU_JPSETADT(PjpParent, 0, 0, cJU_JPNULL1 + Level - 1);
396
+
397
+// Variation to set a specified JP (in a branch being built) to a precomputed
398
+// null JP:
399
+
400
+#define SETJPNULL(Pjp) *(Pjp) = JPnull
401
+
402
+// Handle complete (as opposed to partial) memory allocation failure: Set the
403
+// parent JP to an appropriate null type (to leave a consistent tree), zero the
404
+// callers population count, and return FALSE:
405
+//
406
+// Note: At Level == cJU_ROOTSTATE this sets the JPMs JPs jp_Type to a bogus
407
+// value, but it doesnt matter because the JPM should be deleted by the
408
+// caller.
409
+
410
+#define NOMEM { SETJPNULL_PARENT; *PPop1 = 0; return(FALSE); }
411
+
412
+// Allocate a Leaf1-N and save the address in Pjll; in case of failure, NOMEM:
413
+
414
+#define ALLOCLEAF(AllocLeaf) \
415
+ if ((PjllRaw = AllocLeaf(pop1, Pjpm)) == (Pjll_t) NULL) NOMEM; \
416
+ Pjll = P_JLL(PjllRaw);
417
+
418
+// Copy indexes smaller than words (and values which are whole words) from
419
+// given arrays to immediate indexes or a leaf:
420
+//
421
+// TBD: These macros overlap with some of the code in JudyCascade.c; do some
422
+// merging? That file has functions while these are macros.
423
+
424
+#define COPYTOLEAF_EVEN_SUB(Pjll,LeafType) \
425
+ { \
426
+ LeafType * P_leaf = (LeafType *) (Pjll); \
427
+ Word_t p_op1 = pop1; \
428
+ PWord_t P_Index = PIndex; \
429
+ \
430
+ assert(pop1 > 0); \
431
+ \
432
+ do { *P_leaf++ = *P_Index++; /* truncates */\
433
+ } while (--(p_op1)); \
434
+ }
435
+
436
+#define COPYTOLEAF_ODD_SUB(cLevel,Pjll,Copy) \
437
+ { \
438
+ uint8_t * P_leaf = (uint8_t *) (Pjll); \
439
+ Word_t p_op1 = pop1; \
440
+ PWord_t P_Index = PIndex; \
441
+ \
442
+ assert(pop1 > 0); \
443
+ \
444
+ do { \
445
+ Copy(P_leaf, *P_Index); \
446
+ P_leaf += (cLevel); ++P_Index; \
447
+ } while (--(p_op1)); \
448
+ }
449
+
450
+#ifdef JUDY1
451
+
452
+#define COPYTOLEAF_EVEN(Pjll,LeafType) COPYTOLEAF_EVEN_SUB(Pjll,LeafType)
453
+#define COPYTOLEAF_ODD(cLevel,Pjll,Copy) COPYTOLEAF_ODD_SUB(cLevel,Pjll,Copy)
454
+
455
+#else // JUDYL adds copying of values:
456
+
457
+#define COPYTOLEAF_EVEN(Pjll,LeafType) \
458
+ { \
459
+ COPYTOLEAF_EVEN_SUB(Pjll,LeafType) \
460
+ JU_COPYMEM(Pjv, PValue, pop1); \
461
+ }
462
+
463
+#define COPYTOLEAF_ODD(cLevel,Pjll,Copy) \
464
+ { \
465
+ COPYTOLEAF_ODD_SUB( cLevel,Pjll,Copy) \
466
+ JU_COPYMEM(Pjv, PValue, pop1); \
467
+ }
468
+
469
+#endif
470
+
471
+// Set the JP type for an immediate index, where BaseJPType is JPIMMED_*_02:
472
+
473
+#define SETIMMTYPE(BaseJPType) (PjpParent->jp_Type) = (BaseJPType) + pop1 - 2
474
+
475
+// Allocate and populate a Leaf1-N:
476
+//
477
+// Build MAKELEAF_EVEN() and MAKELEAF_ODD() using macros for common code.
478
+
479
+#define MAKELEAF_SUB1(AllocLeaf,ValueArea,LeafType) \
480
+ ALLOCLEAF(AllocLeaf); \
481
+ JUDYLCODE(Pjv = ValueArea(Pjll, pop1))
482
+
483
+
484
+#define MAKELEAF_SUB2(cLevel,JPType) \
485
+{ \
486
+ Word_t D_cdP0; \
487
+ assert(pop1 - 1 <= cJU_POP0MASK(cLevel)); \
488
+ D_cdP0 = (*PIndex & cJU_DCDMASK(cLevel)) | (pop1 - 1); \
489
+ JU_JPSETADT(PjpParent, (Word_t)PjllRaw, D_cdP0, JPType); \
490
+}
491
+
492
+
493
+#define MAKELEAF_EVEN(cLevel,JPType,AllocLeaf,ValueArea,LeafType) \
494
+ MAKELEAF_SUB1(AllocLeaf,ValueArea,LeafType); \
495
+ COPYTOLEAF_EVEN(Pjll, LeafType); \
496
+ MAKELEAF_SUB2(cLevel, JPType)
497
+
498
+#define MAKELEAF_ODD(cLevel,JPType,AllocLeaf,ValueArea,Copy) \
499
+ MAKELEAF_SUB1(AllocLeaf,ValueArea,LeafType); \
500
+ COPYTOLEAF_ODD(cLevel, Pjll, Copy); \
501
+ MAKELEAF_SUB2(cLevel, JPType)
502
+
503
+// Ensure that the indexes to be stored in immediate indexes or a leaf are
504
+// sorted:
505
+//
506
+// This check is pure overhead, but required in order to protect the Judy array
507
+// against caller error, to avoid a later corruption or core dump from a
508
+// seemingly valid Judy array. Do this check piecemeal at the leaf level while
509
+// the indexes are already in the cache. Higher-level order-checking occurs
510
+// while building branches.
511
+//
512
+// Note: Any sorting error in the expanse of a single immediate indexes JP or
513
+// a leaf => save no indexes in that expanse.
514
+
515
+#define CHECKLEAFORDER \
516
+ { \
517
+ for (offset = 1; offset < pop1; ++offset) \
518
+ { \
519
+ if (PIndex[offset - 1] >= PIndex[offset]) \
520
+ { \
521
+ SETJPNULL_PARENT; \
522
+ *PPop1 = 0; \
523
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_UNSORTED); \
524
+ return(FALSE); \
525
+ } \
526
+ } \
527
+ }
528
+
529
+
530
+// ------ START OF CODE ------
531
+
532
+ assert( Level >= 1);
533
+ assert( Level <= cJU_ROOTSTATE);
534
+ assert((Level < cJU_ROOTSTATE) || (pop1 > cJU_LEAFW_MAXPOP1));
535
+
536
+
537
+// CHECK FOR TOP LEVEL:
538
+//
539
+// Special case: If at the top level (PjpParent is in the JPM), a top-level
540
+// branch must be created, even if its a BranchL with just one JP. (The JPM
541
+// cannot point to a leaf because the leaf would have to be a lower-level,
542
+// higher-capacity leaf under a narrow pointer (otherwise a root-level leaf
543
+// would suffice), and the JPMs JP cant handle a narrow pointer because the
544
+// jp_DcdPopO field isnt big enough.) Otherwise continue to check for a pop1
545
+// small enough to support immediate indexes or a leaf before giving up and
546
+// making a lower-level branch.
547
+
548
+ if (Level == cJU_ROOTSTATE)
549
+ {
550
+ levelsub = cJU_ROOTSTATE;
551
+ goto BuildBranch2;
552
+ }
553
+ assert(Level < cJU_ROOTSTATE);
554
+
555
+
556
+// SKIP JPIMMED_*_01:
557
+//
558
+// Immeds with pop1 == 1 should be handled in-line during branch construction.
559
+
560
+ assert(pop1 > 1);
561
+
562
+
563
+// BUILD JPIMMED_*_02+:
564
+//
565
+// The starting address of the indexes depends on Judy1 or JudyL; also, JudyL
566
+// includes a pointer to a values-only leaf.
567
+
568
+ if (pop1 <= immed_maxpop1[Level]) // note: always < root level.
569
+ {
570
+ JUDY1CODE(uint8_t * Pjll = (uint8_t *) (PjpParent->jp_1Index);)
571
+ JUDYLCODE(uint8_t * Pjll = (uint8_t *) (PjpParent->jp_LIndex);)
572
+
573
+ CHECKLEAFORDER; // indexes to be stored are sorted.
574
+
575
+#ifdef JUDYL
576
+ if ((PjvRaw = j__udyLAllocJV(pop1, Pjpm)) == (Pjv_t) NULL)
577
+ NOMEM;
578
+ (PjpParent->jp_Addr) = (Word_t) PjvRaw;
579
+ Pjv = P_JV(PjvRaw);
580
+#endif
581
+
582
+ switch (Level)
583
+ {
584
+ case 1: COPYTOLEAF_EVEN(Pjll, uint8_t);
585
+ SETIMMTYPE(cJU_JPIMMED_1_02);
586
+ break;
587
+#if (defined(JUDY1) || defined(JU_64BIT))
588
+ case 2: COPYTOLEAF_EVEN(Pjll, uint16_t);
589
+ SETIMMTYPE(cJU_JPIMMED_2_02);
590
+ break;
591
+ case 3: COPYTOLEAF_ODD(3, Pjll, JU_COPY3_LONG_TO_PINDEX);
592
+ SETIMMTYPE(cJU_JPIMMED_3_02);
593
+ break;
594
+#endif
595
+#if (defined(JUDY1) && defined(JU_64BIT))
596
+ case 4: COPYTOLEAF_EVEN(Pjll, uint32_t);
597
+ SETIMMTYPE(cJ1_JPIMMED_4_02);
598
+ break;
599
+ case 5: COPYTOLEAF_ODD(5, Pjll, JU_COPY5_LONG_TO_PINDEX);
600
+ SETIMMTYPE(cJ1_JPIMMED_5_02);
601
+ break;
602
+ case 6: COPYTOLEAF_ODD(6, Pjll, JU_COPY6_LONG_TO_PINDEX);
603
+ SETIMMTYPE(cJ1_JPIMMED_6_02);
604
+ break;
605
+ case 7: COPYTOLEAF_ODD(7, Pjll, JU_COPY7_LONG_TO_PINDEX);
606
+ SETIMMTYPE(cJ1_JPIMMED_7_02);
607
+ break;
608
+#endif
609
+ default: assert(FALSE); // should be impossible.
610
+ }
611
+
612
+ return(TRUE); // note: no children => no *PPop1 mods.
613
+
614
+ } // JPIMMED_*_02+
615
+
616
+
617
+// BUILD JPLEAF*:
618
+//
619
+// This code is a little tricky. The method is: For each level starting at
620
+// the present Level down through levelsub = 1, and then as a special case for
621
+// LeafB1 and FullPop (which are also at levelsub = 1 but have different
622
+// capacity, see later), check if pop1 fits in a leaf (using leaf_maxpop1[])
623
+// at that level. If so, except for Level == levelsub, check if all of the
624
+// current indexes to be stored are in the same (narrow) subexpanse, that is,
625
+// the digits from Level to levelsub + 1, inclusive, are identical between the
626
+// first and last index in the (sorted) list (in PIndex). If this condition is
627
+// satisfied at any level, build a leaf at that level (under a narrow pointer
628
+// if Level > levelsub).
629
+//
630
+// Note: Doing the search in this order results in storing the indexes in
631
+// "least compressed form."
632
+
633
+ for (levelsub = Level; levelsub >= 1; --levelsub)
634
+ {
635
+ Pjll_t PjllRaw;
636
+ Pjll_t Pjll;
637
+
638
+// Check if pop1 is too large to fit in a leaf at levelsub; if so, try the next
639
+// lower level:
640
+
641
+ if (pop1 > leaf_maxpop1[levelsub]) continue;
642
+
643
+// If pop1 fits in a leaf at levelsub, but levelsub is lower than Level, must
644
+// also check whether all the indexes in the expanse to store can in fact be
645
+// placed under a narrow pointer; if not, a leaf cannot be used, at this or any
646
+// lower level (levelsub):
647
+
648
+ if ((levelsub < Level) && (! SAMESUBEXP(levelsub)))
649
+ goto BuildBranch; // cant use a narrow, need a branch.
650
+
651
+// Ensure valid pop1 and all indexes are in fact common through Level:
652
+
653
+ assert(pop1 <= cJU_POP0MASK(Level) + 1);
654
+ assert(! ((PIndex[0] ^ PIndex[pop1 - 1]) & cJU_DCDMASK(Level)));
655
+
656
+ CHECKLEAFORDER; // indexes to be stored are sorted.
657
+
658
+// Build correct type of leaf:
659
+//
660
+// Note: The jp_DcdPopO and jp_Type assignments in MAKELEAF_* happen correctly
661
+// for the levelsub (not Level) of the new leaf, even if its under a narrow
662
+// pointer.
663
+
664
+ switch (levelsub)
665
+ {
666
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
667
+ case 1: MAKELEAF_EVEN(1, cJU_JPLEAF1, j__udyAllocJLL1,
668
+ JL_LEAF1VALUEAREA, uint8_t);
669
+ break;
670
+#endif
671
+ case 2: MAKELEAF_EVEN(2, cJU_JPLEAF2, j__udyAllocJLL2,
672
+ JL_LEAF2VALUEAREA, uint16_t);
673
+ break;
674
+ case 3: MAKELEAF_ODD( 3, cJU_JPLEAF3, j__udyAllocJLL3,
675
+ JL_LEAF3VALUEAREA, JU_COPY3_LONG_TO_PINDEX);
676
+ break;
677
+#ifdef JU_64BIT
678
+ case 4: MAKELEAF_EVEN(4, cJU_JPLEAF4, j__udyAllocJLL4,
679
+ JL_LEAF4VALUEAREA, uint32_t);
680
+ break;
681
+ case 5: MAKELEAF_ODD( 5, cJU_JPLEAF5, j__udyAllocJLL5,
682
+ JL_LEAF5VALUEAREA, JU_COPY5_LONG_TO_PINDEX);
683
+ break;
684
+ case 6: MAKELEAF_ODD( 6, cJU_JPLEAF6, j__udyAllocJLL6,
685
+ JL_LEAF6VALUEAREA, JU_COPY6_LONG_TO_PINDEX);
686
+ break;
687
+ case 7: MAKELEAF_ODD( 7, cJU_JPLEAF7, j__udyAllocJLL7,
688
+ JL_LEAF7VALUEAREA, JU_COPY7_LONG_TO_PINDEX);
689
+ break;
690
+#endif
691
+ default: assert(FALSE); // should be impossible.
692
+ }
693
+
694
+ return(TRUE); // note: no children => no *PPop1 mods.
695
+
696
+ } // JPLEAF*
697
+
698
+
699
+// BUILD JPLEAF_B1 OR JPFULLPOPU1:
700
+//
701
+// See above about JPLEAF*. If pop1 doesnt fit in any level of linear leaf,
702
+// it might still fit in a LeafB1 or FullPop, perhaps under a narrow pointer.
703
+
704
+ if ((Level == 1) || SAMESUBEXP(1)) // same until last digit.
705
+ {
706
+ Pjlb_t PjlbRaw; // for bitmap leaf.
707
+ Pjlb_t Pjlb;
708
+
709
+ assert(pop1 <= cJU_JPFULLPOPU1_POP0 + 1);
710
+ CHECKLEAFORDER; // indexes to be stored are sorted.
711
+
712
+#ifdef JUDY1
713
+
714
+// JPFULLPOPU1:
715
+
716
+ if (pop1 == cJU_JPFULLPOPU1_POP0 + 1)
717
+ {
718
+ Word_t Addr = PjpParent->jp_Addr;
719
+ Word_t DcdP0 = (*PIndex & cJU_DCDMASK(1))
720
+ | cJU_JPFULLPOPU1_POP0;
721
+ JU_JPSETADT(PjpParent, Addr, DcdP0, cJ1_JPFULLPOPU1);
722
+
723
+ return(TRUE);
724
+ }
725
+#endif
726
+
727
+// JPLEAF_B1:
728
+
729
+ if ((PjlbRaw = j__udyAllocJLB1(Pjpm)) == (Pjlb_t) NULL)
730
+ NOMEM;
731
+ Pjlb = P_JLB(PjlbRaw);
732
+
733
+ for (offset = 0; offset < pop1; ++offset)
734
+ JU_BITMAPSETL(Pjlb, PIndex[offset]);
735
+
736
+ retval = TRUE; // default.
737
+
738
+#ifdef JUDYL
739
+
740
+// Build subexpanse values-only leaves (LeafVs) under LeafB1:
741
+
742
+ for (offset = 0; offset < cJU_NUMSUBEXPL; ++offset)
743
+ {
744
+ if (! (pop1sub = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, offset))))
745
+ continue; // skip empty subexpanse.
746
+
747
+// Allocate one LeafV = JP subarray; if out of memory, clear bitmaps for higher
748
+// subexpanses and adjust *PPop1:
749
+
750
+ if ((PjvRaw = j__udyLAllocJV(pop1sub, Pjpm))
751
+ == (Pjv_t) NULL)
752
+ {
753
+ for (/* null */; offset < cJU_NUMSUBEXPL; ++offset)
754
+ {
755
+ *PPop1 -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, offset));
756
+ JU_JLB_BITMAP(Pjlb, offset) = 0;
757
+ }
758
+
759
+ retval = FALSE;
760
+ break;
761
+ }
762
+
763
+// Populate values-only leaf and save the pointer to it:
764
+
765
+ Pjv = P_JV(PjvRaw);
766
+ JU_COPYMEM(Pjv, PValue, pop1sub);
767
+ JL_JLB_PVALUE(Pjlb, offset) = PjvRaw; // first-tier pointer.
768
+ PValue += pop1sub;
769
+
770
+ } // for each subexpanse
771
+
772
+#endif // JUDYL
773
+
774
+// Attach new LeafB1 to parent JP; note use of *PPop1 possibly < pop1:
775
+
776
+ JU_JPSETADT(PjpParent, (Word_t) PjlbRaw,
777
+ (*PIndex & cJU_DCDMASK(1)) | (*PPop1 - 1), cJU_JPLEAF_B1);
778
+
779
+ return(retval);
780
+
781
+ } // JPLEAF_B1 or JPFULLPOPU1
782
+
783
+
784
+// BUILD JPBRANCH_U*:
785
+//
786
+// Arriving at BuildBranch means Level < top level but the pop1 is too large
787
+// for immediate indexes or a leaf, even under a narrow pointer, including a
788
+// LeafB1 or FullPop at level 1. This implies SAMESUBEXP(1) == FALSE, that is,
789
+// the indexes to be stored "branch" at level 2 or higher.
790
+
791
+BuildBranch: // come here directly if a leaf wont work.
792
+
793
+ assert(Level >= 2);
794
+ assert(Level < cJU_ROOTSTATE);
795
+ assert(! SAMESUBEXP(1)); // sanity check, see above.
796
+
797
+// Determine the appropriate level for a new branch node; see if a narrow
798
+// pointer can be used:
799
+//
800
+// This can be confusing. The branch is required at the lowest level L where
801
+// the indexes to store are not in the same subexpanse at level L-1. Work down
802
+// from Level to tree level 3, which is 1 above the lowest tree level = 2 at
803
+// which a branch can be used. Theres no need to check SAMESUBEXP at level 2
804
+// because its known to be false at level 2-1 = 1.
805
+//
806
+// Note: Unlike for a leaf node, a narrow pointer is always used for a branch
807
+// if possible, that is, maximum compression is always used, except at the top
808
+// level of the tree, where a JPM cannot support a narrow pointer, meaning a
809
+// top BranchL can have a single JP (fanout = 1); but that case jumps directly
810
+// to BuildBranch2.
811
+//
812
+// Note: For 32-bit systems the only usable values for a narrow pointer are
813
+// Level = 3 and levelsub = 2; 64-bit systems have many more choices; but
814
+// hopefully this for-loop is fast enough even on a 32-bit system.
815
+//
816
+// TBD: If not fast enough, #ifdef JU_64BIT and handle the 32-bit case faster.
817
+
818
+ for (levelsub = Level; levelsub >= 3; --levelsub) // see above.
819
+ if (! SAMESUBEXP(levelsub - 1)) // at limit of narrow pointer.
820
+ break; // put branch at levelsub.
821
+
822
+BuildBranch2: // come here directly for Level = levelsub = cJU_ROOTSTATE.
823
+
824
+ assert(levelsub >= 2);
825
+ assert(levelsub <= Level);
826
+
827
+// Initially build a BranchU:
828
+//
829
+// Always start with a BranchU because the number of populated subexpanses is
830
+// not yet known. Use digitmask, digitshifted, and digitshincr to avoid
831
+// expensive variable shifts within JU_DIGITATSTATE within the loop.
832
+//
833
+// TBD: The use of digitmask, etc. results in more increment operations per
834
+// loop, is there an even faster way?
835
+//
836
+// TBD: Would it pay to pre-count the populated JPs (subexpanses) and
837
+// pre-compress the branch, that is, build a BranchL or BranchB immediately,
838
+// also taking account of opportunistic uncompression rules? Probably not
839
+// because at high levels of the tree there might be huge numbers of indexes
840
+// (hence cache lines) to scan in the PIndex array to determine the fanout
841
+// (number of JPs) needed.
842
+
843
+ if ((PjbuRaw = j__udyAllocJBU(Pjpm)) == (Pjbu_t) NULL) NOMEM;
844
+ Pjbu = P_JBU(PjbuRaw);
845
+
846
+ JPtype_null = cJU_JPNULL1 + levelsub - 2; // in new BranchU.
847
+ JU_JPSETADT(&JPnull, 0, 0, JPtype_null);
848
+
849
+ Pjp = Pjbu->jbu_jp; // for convenience in loop.
850
+ numJPs = 0; // non-null in the BranchU.
851
+ digitmask = cJU_MASKATSTATE(levelsub); // see above.
852
+ digitshincr = 1UL << (cJU_BITSPERBYTE * (levelsub - 1));
853
+ retval = TRUE;
854
+
855
+// Scan and populate JPs (subexpanses):
856
+//
857
+// Look for all indexes matching each digit in the BranchU (at the correct
858
+// levelsub), and meanwhile notice any sorting error. Increment PIndex (and
859
+// PValue) and reduce pop1 for each subexpanse handled successfully.
860
+
861
+ for (digit = digitshifted = 0;
862
+ digit < cJU_BRANCHUNUMJPS;
863
+ ++digit, digitshifted += digitshincr, ++Pjp)
864
+ {
865
+ DBGCODE(Word_t pop1subprev;)
866
+ assert(pop1 != 0); // end of indexes is handled elsewhere.
867
+
868
+// Count indexes in digits subexpanse:
869
+
870
+ for (pop1sub = 0; pop1sub < pop1; ++pop1sub)
871
+ if (digitshifted != (PIndex[pop1sub] & digitmask)) break;
872
+
873
+// Empty subexpanse (typical, performance path) or sorting error (rare):
874
+
875
+ if (pop1sub == 0)
876
+ {
877
+ if (digitshifted < (PIndex[0] & digitmask))
878
+ { SETJPNULL(Pjp); continue; } // empty subexpanse.
879
+
880
+ assert(pop1 < *PPop1); // did save >= 1 index and decr pop1.
881
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_UNSORTED);
882
+ goto AbandonBranch;
883
+ }
884
+
885
+// Non-empty subexpanse:
886
+//
887
+// First shortcut by handling pop1sub == 1 (JPIMMED_*_01) inline locally.
888
+
889
+ if (pop1sub == 1) // note: can be at root level.
890
+ {
891
+ Word_t Addr = 0;
892
+ JUDYLCODE(Addr = (Word_t) (*PValue++);)
893
+ JU_JPSETADT(Pjp, Addr, *PIndex, cJU_JPIMMED_1_01 + levelsub -2);
894
+
895
+ ++numJPs;
896
+
897
+ if (--pop1) { ++PIndex; continue; } // more indexes to store.
898
+
899
+ ++digit; ++Pjp; // skip JP just saved.
900
+ goto ClearBranch; // save time.
901
+ }
902
+
903
+// Recurse to populate one digits (subexpanses) JP; if successful, skip
904
+// indexes (and values) just stored (performance path), except when expanse is
905
+// completely stored:
906
+
907
+ DBGCODE(pop1subprev = pop1sub;)
908
+
909
+ if (j__udyInsArray(Pjp, levelsub - 1, &pop1sub, (PWord_t) PIndex,
910
+#ifdef JUDYL
911
+ (Pjv_t) PValue,
912
+#endif
913
+ Pjpm))
914
+ { // complete success.
915
+ ++numJPs;
916
+ assert(pop1subprev == pop1sub);
917
+ assert(pop1 >= pop1sub);
918
+
919
+ if ((pop1 -= pop1sub) != 0) // more indexes to store:
920
+ {
921
+ PIndex += pop1sub; // skip indexes just stored.
922
+ JUDYLCODE(PValue += pop1sub;)
923
+ continue;
924
+ }
925
+ // else leave PIndex in BranchUs expanse.
926
+
927
+// No more indexes to store in BranchUs expanse:
928
+
929
+ ++digit; ++Pjp; // skip JP just saved.
930
+ goto ClearBranch; // save time.
931
+ }
932
+
933
+// Handle any error at a lower level of recursion:
934
+//
935
+// In case of partial success, pop1sub != 0, but it was reduced from the value
936
+// passed to j__udyInsArray(); skip this JP later during ClearBranch.
937
+
938
+ assert(pop1subprev > pop1sub); // check j__udyInsArray().
939
+ assert(pop1 > pop1sub); // check j__udyInsArray().
940
+
941
+ if (pop1sub) // partial success.
942
+ { ++digit; ++Pjp; ++numJPs; } // skip JP just saved.
943
+
944
+ pop1 -= pop1sub; // deduct saved indexes if any.
945
+
946
+// Same-level sorting error, or any lower-level error; abandon the rest of the
947
+// branch:
948
+//
949
+// Arrive here with pop1 = remaining unsaved indexes (always non-zero). Adjust
950
+// the *PPop1 value to record and return, modify retval, and use ClearBranch to
951
+// finish up.
952
+
953
+AbandonBranch:
954
+ assert(pop1 != 0); // more to store, see above.
955
+ assert(pop1 <= *PPop1); // sanity check.
956
+
957
+ *PPop1 -= pop1; // deduct unsaved indexes.
958
+ pop1 = 0; // to avoid error later.
959
+ retval = FALSE;
960
+
961
+// Error (rare), or end of indexes while traversing new BranchU (performance
962
+// path); either way, mark the remaining JPs, if any, in the BranchU as nulls
963
+// and exit the loop:
964
+//
965
+// Arrive here with digit and Pjp set to the first JP to set to null.
966
+
967
+ClearBranch:
968
+ for (/* null */; digit < cJU_BRANCHUNUMJPS; ++digit, ++Pjp)
969
+ SETJPNULL(Pjp);
970
+ break; // saves one more compare.
971
+
972
+ } // for each digit
973
+
974
+
975
+// FINISH JPBRANCH_U*:
976
+//
977
+// Arrive here with a BranchU built under Pjbu, numJPs set, and either: retval
978
+// == TRUE and *PPop1 unmodified, or else retval == FALSE, *PPop1 set to the
979
+// actual number of indexes saved (possibly 0 for complete failure at a lower
980
+// level upon the first call of j__udyInsArray()), and the Judy error set in
981
+// Pjpm. Either way, PIndex points to an index within the expanse just
982
+// handled.
983
+
984
+ Pjbany = (Word_t) PjbuRaw; // default = use this BranchU.
985
+ JPtype = branchU_JPtype[levelsub];
986
+
987
+// Check for complete failure above:
988
+
989
+ assert((! retval) || *PPop1); // sanity check.
990
+
991
+ if ((! retval) && (*PPop1 == 0)) // nothing stored, full failure.
992
+ {
993
+ j__udyFreeJBU(PjbuRaw, Pjpm);
994
+ SETJPNULL_PARENT;
995
+ return(FALSE);
996
+ }
997
+
998
+// Complete or partial success so far; watch for sorting error after the
999
+// maximum digit (255) in the BranchU, which is indicated by having more
1000
+// indexes to store in the BranchUs expanse:
1001
+//
1002
+// For example, if an index to store has a digit of 255 at levelsub, followed
1003
+// by an index with a digit of 254, the for-loop above runs out of digits
1004
+// without reducing pop1 to 0.
1005
+
1006
+ if (pop1 != 0)
1007
+ {
1008
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_UNSORTED);
1009
+ *PPop1 -= pop1; // deduct unsaved indexes.
1010
+ retval = FALSE;
1011
+ }
1012
+ assert(*PPop1 != 0); // branch (still) cannot be empty.
1013
+
1014
+
1015
+// OPTIONALLY COMPRESS JPBRANCH_U*:
1016
+//
1017
+// See if the BranchU should be compressed to a BranchL or BranchB; if so, do
1018
+// that and free the BranchU; otherwise just use the existing BranchU. Follow
1019
+// the same rules as in JudyIns.c (version 4.95): Only check local population
1020
+// (cJU_OPP_UNCOMP_POP0) for BranchL, and only check global memory efficiency
1021
+// (JU_OPP_UNCOMPRESS) for BranchB. TBD: Have the rules changed?
1022
+//
1023
+// Note: Because of differing order of operations, the latter compression
1024
+// might not result in the same set of branch nodes as a series of sequential
1025
+// insertions.
1026
+//
1027
+// Note: Allocating a BranchU only to sometimes convert it to a BranchL or
1028
+// BranchB is unfortunate, but attempting to work with a temporary BranchU on
1029
+// the stack and then allocate and keep it as a BranchU in many cases is worse
1030
+// in terms of error handling.
1031
+
1032
+
1033
+// COMPRESS JPBRANCH_U* TO JPBRANCH_L*:
1034
+
1035
+ if (numJPs <= cJU_BRANCHLMAXJPS) // JPs fit in a BranchL.
1036
+ {
1037
+ Pjbl_t PjblRaw = (Pjbl_t) NULL; // new BranchL; init for cc.
1038
+ Pjbl_t Pjbl;
1039
+
1040
+ if ((*PPop1 > JU_BRANCHL_MAX_POP) // pop too high.
1041
+ || ((PjblRaw = j__udyAllocJBL(Pjpm)) == (Pjbl_t) NULL))
1042
+ { // cant alloc BranchL.
1043
+ goto SetParent; // just keep BranchU.
1044
+ }
1045
+
1046
+ Pjbl = P_JBL(PjblRaw);
1047
+
1048
+// Copy BranchU JPs to BranchL:
1049
+
1050
+ (Pjbl->jbl_NumJPs) = numJPs;
1051
+ offset = 0;
1052
+
1053
+ for (digit = 0; digit < cJU_BRANCHUNUMJPS; ++digit)
1054
+ {
1055
+ if ((((Pjbu->jbu_jp) + digit)->jp_Type) == JPtype_null)
1056
+ continue;
1057
+
1058
+ (Pjbl->jbl_Expanse[offset ]) = digit;
1059
+ (Pjbl->jbl_jp [offset++]) = Pjbu->jbu_jp[digit];
1060
+ }
1061
+ assert(offset == numJPs); // found same number.
1062
+
1063
+// Free the BranchU and prepare to use the new BranchL instead:
1064
+
1065
+ j__udyFreeJBU(PjbuRaw, Pjpm);
1066
+
1067
+ Pjbany = (Word_t) PjblRaw;
1068
+ JPtype = branchL_JPtype[levelsub];
1069
+
1070
+ } // compress to BranchL
1071
+
1072
+
1073
+// COMPRESS JPBRANCH_U* TO JPBRANCH_B*:
1074
+//
1075
+// If unable to allocate the BranchB or any JP subarray, free all related
1076
+// memory and just keep the BranchU.
1077
+//
1078
+// Note: This use of JU_OPP_UNCOMPRESS is a bit conservative because the
1079
+// BranchU is already allocated while the (presumably smaller) BranchB is not,
1080
+// the opposite of how its used in single-insert code.
1081
+
1082
+ else
1083
+ {
1084
+ Pjbb_t PjbbRaw = (Pjbb_t) NULL; // new BranchB; init for cc.
1085
+ Pjbb_t Pjbb;
1086
+ Pjp_t Pjp2; // in BranchU.
1087
+
1088
+ if ((*PPop1 > JU_BRANCHB_MAX_POP) // pop too high.
1089
+ || ((PjbbRaw = j__udyAllocJBB(Pjpm)) == (Pjbb_t) NULL))
1090
+ { // cant alloc BranchB.
1091
+ goto SetParent; // just keep BranchU.
1092
+ }
1093
+
1094
+ Pjbb = P_JBB(PjbbRaw);
1095
+
1096
+// Set bits in bitmap for populated subexpanses:
1097
+
1098
+ Pjp2 = Pjbu->jbu_jp;
1099
+
1100
+ for (digit = 0; digit < cJU_BRANCHUNUMJPS; ++digit)
1101
+ if ((((Pjbu->jbu_jp) + digit)->jp_Type) != JPtype_null)
1102
+ JU_BITMAPSETB(Pjbb, digit);
1103
+
1104
+// Copy non-null JPs to BranchB JP subarrays:
1105
+
1106
+ for (offset = 0; offset < cJU_NUMSUBEXPB; ++offset)
1107
+ {
1108
+ Pjp_t PjparrayRaw;
1109
+ Pjp_t Pjparray;
1110
+
1111
+ if (! (numJPs = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, offset))))
1112
+ continue; // skip empty subexpanse.
1113
+
1114
+// If unable to allocate a JP subarray, free all BranchB memory so far and
1115
+// continue to use the BranchU:
1116
+
1117
+ if ((PjparrayRaw = j__udyAllocJBBJP(numJPs, Pjpm))
1118
+ == (Pjp_t) NULL)
1119
+ {
1120
+ while (offset-- > 0)
1121
+ {
1122
+ if (JU_JBB_PJP(Pjbb, offset) == (Pjp_t) NULL) continue;
1123
+
1124
+ j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, offset),
1125
+ j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, offset)),
1126
+ Pjpm);
1127
+ }
1128
+ j__udyFreeJBB(PjbbRaw, Pjpm);
1129
+ goto SetParent; // keep BranchU.
1130
+ }
1131
+
1132
+// Set one JP subarray pointer and copy the subexpanses JPs to the subarray:
1133
+//
1134
+// Scan the BranchU for non-null JPs until numJPs JPs are copied.
1135
+
1136
+ JU_JBB_PJP(Pjbb, offset) = PjparrayRaw;
1137
+ Pjparray = P_JP(PjparrayRaw);
1138
+
1139
+ while (numJPs-- > 0)
1140
+ {
1141
+ while ((Pjp2->jp_Type) == JPtype_null)
1142
+ {
1143
+ ++Pjp2;
1144
+ assert(Pjp2 < (Pjbu->jbu_jp) + cJU_BRANCHUNUMJPS);
1145
+ }
1146
+ *Pjparray++ = *Pjp2++;
1147
+ }
1148
+ } // for each subexpanse
1149
+
1150
+// Free the BranchU and prepare to use the new BranchB instead:
1151
+
1152
+ j__udyFreeJBU(PjbuRaw, Pjpm);
1153
+
1154
+ Pjbany = (Word_t) PjbbRaw;
1155
+ JPtype = branchB_JPtype[levelsub];
1156
+
1157
+ } // compress to BranchB
1158
+
1159
+
1160
+// COMPLETE OR PARTIAL SUCCESS:
1161
+//
1162
+// Attach new branch (under Pjp, with JPtype) to parent JP; note use of *PPop1,
1163
+// possibly reduced due to partial failure.
1164
+
1165
+SetParent:
1166
+ (PjpParent->jp_Addr) = Pjbany;
1167
+ (PjpParent->jp_Type) = JPtype;
1168
+
1169
+ if (Level < cJU_ROOTSTATE) // PjpParent not in JPM:
1170
+ {
1171
+ Word_t DcdP0 = (*PIndex & cJU_DCDMASK(levelsub)) | (*PPop1 - 1);
1172
+
1173
+ JU_JPSETADT(PjpParent ,Pjbany, DcdP0, JPtype);
1174
+ }
1175
+
1176
+ return(retval);
1177
+
1178
+} // j__udyInsArray()
libnetdata/libjudy/src/JudyL/JudyLInsertBranch.c
new
+135
@@ -0,0 +1,135 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.17 $ $Source: /judy/src/JudyCommon/JudyInsertBranch.c $
19
+
20
+// BranchL insertion functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+
23
+#if (! (defined(JUDY1) || defined(JUDYL)))
24
+#error: One of -DJUDY1 or -DJUDYL must be specified.
25
+#endif
26
+
27
+#ifdef JUDY1
28
+#include "Judy1.h"
29
+#else
30
+#include "JudyL.h"
31
+#endif
32
+
33
+#include "JudyPrivate1L.h"
34
+
35
+extern int j__udyCreateBranchL(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
36
+
37
+
38
+// ****************************************************************************
39
+// __ J U D Y I N S E R T B R A N C H
40
+//
41
+// Insert 2-element BranchL in between Pjp and Pjp->jp_Addr.
42
+//
43
+// Return -1 if out of memory, otherwise return 1.
44
+
45
+FUNCTION int j__udyInsertBranch(
46
+ Pjp_t Pjp, // JP containing narrow pointer.
47
+ Word_t Index, // outlier to Pjp.
48
+ Word_t BranchLevel, // of what JP points to, mapped from JP type.
49
+ Pjpm_t Pjpm) // for global accounting.
50
+{
51
+ jp_t JP2 [2];
52
+ jp_t JP;
53
+ Pjp_t PjpNull;
54
+ Word_t XorExp;
55
+ Word_t Inew, Iold;
56
+ Word_t DCDMask; // initially for original BranchLevel.
57
+ int Ret;
58
+ uint8_t Exp2[2];
59
+ uint8_t DecodeByteN, DecodeByteO;
60
+
61
+// Get the current mask for the DCD digits:
62
+
63
+ DCDMask = cJU_DCDMASK(BranchLevel);
64
+
65
+// Obtain Dcd bits that differ between Index and JP, shifted so the
66
+// digit for BranchLevel is the LSB:
67
+
68
+ XorExp = ((Index ^ JU_JPDCDPOP0(Pjp)) & (cJU_ALLONES >> cJU_BITSPERBYTE))
69
+ >> (BranchLevel * cJU_BITSPERBYTE);
70
+ assert(XorExp); // Index must be an outlier.
71
+
72
+// Count levels between object under narrow pointer and the level at which
73
+// the outlier diverges from it, which is always at least initial
74
+// BranchLevel + 1, to end up with the level (JP type) at which to insert
75
+// the new intervening BranchL:
76
+
77
+ do { ++BranchLevel; } while ((XorExp >>= cJU_BITSPERBYTE));
78
+ assert((BranchLevel > 1) && (BranchLevel < cJU_ROOTSTATE));
79
+
80
+// Get the MSB (highest digit) that differs between the old expanse and
81
+// the new Index to insert:
82
+
83
+ DecodeByteO = JU_DIGITATSTATE(JU_JPDCDPOP0(Pjp), BranchLevel);
84
+ DecodeByteN = JU_DIGITATSTATE(Index, BranchLevel);
85
+
86
+ assert(DecodeByteO != DecodeByteN);
87
+
88
+// Determine sorted order for old expanse and new Index digits:
89
+
90
+ if (DecodeByteN > DecodeByteO) { Iold = 0; Inew = 1; }
91
+ else { Iold = 1; Inew = 0; }
92
+
93
+// Copy old JP into staging area for new Branch
94
+ JP2 [Iold] = *Pjp;
95
+ Exp2[Iold] = DecodeByteO;
96
+ Exp2[Inew] = DecodeByteN;
97
+
98
+// Create a 2 Expanse Linear branch
99
+//
100
+// Note: Pjp->jp_Addr is set by j__udyCreateBranchL()
101
+
102
+ Ret = j__udyCreateBranchL(Pjp, JP2, Exp2, 2, Pjpm);
103
+ if (Ret == -1) return(-1);
104
+
105
+// Get Pjp to the NULL of where to do insert
106
+ PjpNull = ((P_JBL(Pjp->jp_Addr))->jbl_jp) + Inew;
107
+
108
+// Convert to a cJU_JPIMMED_*_01 at the correct level:
109
+// Build JP and set type below to: cJU_JPIMMED_X_01
110
+ JU_JPSETADT(PjpNull, 0, Index, cJU_JPIMMED_1_01 - 2 + BranchLevel);
111
+
112
+// Return pointer to Value area in cJU_JPIMMED_X_01
113
+ JUDYLCODE(Pjpm->jpm_PValue = (Pjv_t) PjpNull;)
114
+
115
+// The old JP now points to a BranchL that is at higher level. Therefore
116
+// it contains excess DCD bits (in the least significant position) that
117
+// must be removed (zeroed); that is, they become part of the Pop0
118
+// subfield. Note that the remaining (lower) bytes in the Pop0 field do
119
+// not change.
120
+//
121
+// Take from the old DCDMask, which went "down" to a lower BranchLevel,
122
+// and zero any high bits that are still in the mask at the new, higher
123
+// BranchLevel; then use this mask to zero the bits in jp_DcdPopO:
124
+
125
+// Set old JP to a BranchL at correct level
126
+
127
+ Pjp->jp_Type = cJU_JPBRANCH_L2 - 2 + BranchLevel;
128
+ DCDMask ^= cJU_DCDMASK(BranchLevel);
129
+ DCDMask = ~DCDMask & JU_JPDCDPOP0(Pjp);
130
+ JP = *Pjp;
131
+ JU_JPSETADT(Pjp, JP.jp_Addr, DCDMask, JP.jp_Type);
132
+
133
+ return(1);
134
+
135
+} // j__udyInsertBranch()
libnetdata/libjudy/src/JudyL/JudyLMallocIF.c
new
+782
@@ -0,0 +1,782 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.45 $ $Source: /judy/src/JudyCommon/JudyMallocIF.c $
19
+//
20
+// Judy malloc/free interface functions for Judy1 and JudyL.
21
+//
22
+// Compile with one of -DJUDY1 or -DJUDYL.
23
+//
24
+// Compile with -DTRACEMI (Malloc Interface) to turn on tracing of malloc/free
25
+// calls at the interface level. (See also TRACEMF in lower-level code.)
26
+// Use -DTRACEMI2 for a terser format suitable for trace analysis.
27
+//
28
+// There can be malloc namespace bits in the LSBs of "raw" addresses from most,
29
+// but not all, of the j__udy*Alloc*() functions; see also JudyPrivate.h. To
30
+// test the Judy code, compile this file with -DMALLOCBITS and use debug flavor
31
+// only (for assertions). This test ensures that (a) all callers properly mask
32
+// the namespace bits out before dereferencing a pointer (or else a core dump
33
+// occurs), and (b) all callers send "raw" (unmasked) addresses to
34
+// j__udy*Free*() calls.
35
+//
36
+// Note: Currently -DDEBUG turns on MALLOCBITS automatically.
37
+
38
+#if (! (defined(JUDY1) || defined(JUDYL)))
39
+#error: One of -DJUDY1 or -DJUDYL must be specified.
40
+#endif
41
+
42
+#ifdef JUDY1
43
+#include "Judy1.h"
44
+#else
45
+#include "JudyL.h"
46
+#endif
47
+
48
+#include "JudyPrivate1L.h"
49
+
50
+// Set "hidden" global j__uMaxWords to the maximum number of words to allocate
51
+// to any one array (large enough to have a JPM, otherwise j__uMaxWords is
52
+// ignored), to trigger a fake malloc error when the number is exceeded. Note,
53
+// this code is always executed, not #ifdefd, because its virtually free.
54
+//
55
+// Note: To keep the MALLOC macro faster and simpler, set j__uMaxWords to
56
+// MAXINT, not zero, by default.
57
+
58
+Word_t j__uMaxWords = ~0UL;
59
+
60
+// This macro hides the faking of a malloc failure:
61
+//
62
+// Note: To keep this fast, just compare WordsPrev to j__uMaxWords without the
63
+// complexity of first adding WordsNow, meaning the trigger point is not
64
+// exactly where you might assume, but it shouldnt matter.
65
+
66
+#define MALLOC(MallocFunc,WordsPrev,WordsNow) \
67
+ (((WordsPrev) > j__uMaxWords) ? 0UL : MallocFunc(WordsNow))
68
+
69
+// Clear words starting at address:
70
+//
71
+// Note: Only use this for objects that care; in other cases, it doesnt
72
+// matter if the objects memory is pre-zeroed.
73
+
74
+#define ZEROWORDS(Addr,Words) \
75
+ { \
76
+ Word_t Words__ = (Words); \
77
+ PWord_t Addr__ = (PWord_t) (Addr); \
78
+ while (Words__--) *Addr__++ = 0UL; \
79
+ }
80
+
81
+#ifdef TRACEMI
82
+
83
+// TRACING SUPPORT:
84
+//
85
+// Note: For TRACEMI, use a format for address printing compatible with other
86
+// tracing facilities; in particular, %x not %lx, to truncate the "noisy" high
87
+// part on 64-bit systems.
88
+//
89
+// TBD: The trace macros need fixing for alternate address types.
90
+//
91
+// Note: TRACEMI2 supports trace analysis no matter the underlying malloc/free
92
+// engine used.
93
+
94
+#include <stdio.h>
95
+
96
+static Word_t j__udyMemSequence = 0L; // event sequence number.
97
+
98
+#define TRACE_ALLOC5(a,b,c,d,e) (void) printf(a, (b), c, d)
99
+#define TRACE_FREE5( a,b,c,d,e) (void) printf(a, (b), c, d)
100
+#define TRACE_ALLOC6(a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
101
+#define TRACE_FREE6( a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
102
+
103
+#else
104
+
105
+#ifdef TRACEMI2
106
+
107
+#include <stdio.h>
108
+
109
+#define b_pw cJU_BYTESPERWORD
110
+
111
+#define TRACE_ALLOC5(a,b,c,d,e) \
112
+ (void) printf("a %lx %lx %lx\n", (b), (d) * b_pw, e)
113
+#define TRACE_FREE5( a,b,c,d,e) \
114
+ (void) printf("f %lx %lx %lx\n", (b), (d) * b_pw, e)
115
+#define TRACE_ALLOC6(a,b,c,d,e,f) \
116
+ (void) printf("a %lx %lx %lx\n", (b), (e) * b_pw, f)
117
+#define TRACE_FREE6( a,b,c,d,e,f) \
118
+ (void) printf("f %lx %lx %lx\n", (b), (e) * b_pw, f)
119
+
120
+static Word_t j__udyMemSequence = 0L; // event sequence number.
121
+
122
+#else
123
+
124
+#define TRACE_ALLOC5(a,b,c,d,e) // null.
125
+#define TRACE_FREE5( a,b,c,d,e) // null.
126
+#define TRACE_ALLOC6(a,b,c,d,e,f) // null.
127
+#define TRACE_FREE6( a,b,c,d,e,f) // null.
128
+
129
+#endif // ! TRACEMI2
130
+#endif // ! TRACEMI
131
+
132
+
133
+// MALLOC NAMESPACE SUPPORT:
134
+
135
+#if (defined(DEBUG) && (! defined(MALLOCBITS))) // for now, DEBUG => MALLOCBITS:
136
+#define MALLOCBITS 1
137
+#endif
138
+
139
+#ifdef MALLOCBITS
140
+#define MALLOCBITS_VALUE 0x3 // bit pattern to use.
141
+#define MALLOCBITS_MASK 0x7 // note: matches mask__ in JudyPrivate.h.
142
+
143
+#define MALLOCBITS_SET( Type,Addr) \
144
+ ((Addr) = (Type) ((Word_t) (Addr) | MALLOCBITS_VALUE))
145
+#define MALLOCBITS_TEST(Type,Addr) \
146
+ assert((((Word_t) (Addr)) & MALLOCBITS_MASK) == MALLOCBITS_VALUE); \
147
+ ((Addr) = (Type) ((Word_t) (Addr) & ~MALLOCBITS_VALUE))
148
+#else
149
+#define MALLOCBITS_SET( Type,Addr) // null.
150
+#define MALLOCBITS_TEST(Type,Addr) // null.
151
+#endif
152
+
153
+
154
+// SAVE ERROR INFORMATION IN A Pjpm:
155
+//
156
+// "Small" (invalid) Addr values are used to distinguish overrun and no-mem
157
+// errors. (TBD, non-zero invalid values are no longer returned from
158
+// lower-level functions, that is, JU_ERRNO_OVERRUN is no longer detected.)
159
+
160
+#define J__UDYSETALLOCERROR(Addr) \
161
+ { \
162
+ JU_ERRID(Pjpm) = __LINE__; \
163
+ if ((Word_t) (Addr) > 0) JU_ERRNO(Pjpm) = JU_ERRNO_OVERRUN; \
164
+ else JU_ERRNO(Pjpm) = JU_ERRNO_NOMEM; \
165
+ return(0); \
166
+ }
167
+
168
+
169
+// ****************************************************************************
170
+// ALLOCATION FUNCTIONS:
171
+//
172
+// To help the compiler catch coding errors, each function returns a specific
173
+// object type.
174
+//
175
+// Note: Only j__udyAllocJPM() and j__udyAllocJLW() return multiple values <=
176
+// sizeof(Word_t) to indicate the type of memory allocation failure. Other
177
+// allocation functions convert this failure to a JU_ERRNO.
178
+
179
+
180
+// Note: Unlike other j__udyAlloc*() functions, Pjpms are returned non-raw,
181
+// that is, without malloc namespace or root pointer type bits:
182
+
183
+FUNCTION Pjpm_t j__udyAllocJPM(void)
184
+{
185
+ Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD;
186
+ Pjpm_t Pjpm = (Pjpm_t) MALLOC(JudyMalloc, Words, Words);
187
+
188
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jpm_t));
189
+
190
+ if ((Word_t) Pjpm > sizeof(Word_t))
191
+ {
192
+ ZEROWORDS(Pjpm, Words);
193
+ Pjpm->jpm_TotalMemWords = Words;
194
+ }
195
+
196
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJPM(), Words = %lu\n",
197
+ Pjpm, j__udyMemSequence++, Words, cJU_LEAFW_MAXPOP1 + 1);
198
+ // MALLOCBITS_SET(Pjpm_t, Pjpm); // see above.
199
+ return(Pjpm);
200
+
201
+} // j__udyAllocJPM()
202
+
203
+
204
+FUNCTION Pjbl_t j__udyAllocJBL(Pjpm_t Pjpm)
205
+{
206
+ Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
207
+ Pjbl_t PjblRaw = (Pjbl_t) MALLOC(JudyMallocVirtual,
208
+ Pjpm->jpm_TotalMemWords, Words);
209
+
210
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jbl_t));
211
+
212
+ if ((Word_t) PjblRaw > sizeof(Word_t))
213
+ {
214
+ ZEROWORDS(P_JBL(PjblRaw), Words);
215
+ Pjpm->jpm_TotalMemWords += Words;
216
+ }
217
+ else { J__UDYSETALLOCERROR(PjblRaw); }
218
+
219
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBL(), Words = %lu\n", PjblRaw,
220
+ j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
221
+ MALLOCBITS_SET(Pjbl_t, PjblRaw);
222
+ return(PjblRaw);
223
+
224
+} // j__udyAllocJBL()
225
+
226
+
227
+FUNCTION Pjbb_t j__udyAllocJBB(Pjpm_t Pjpm)
228
+{
229
+ Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
230
+ Pjbb_t PjbbRaw = (Pjbb_t) MALLOC(JudyMallocVirtual,
231
+ Pjpm->jpm_TotalMemWords, Words);
232
+
233
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jbb_t));
234
+
235
+ if ((Word_t) PjbbRaw > sizeof(Word_t))
236
+ {
237
+ ZEROWORDS(P_JBB(PjbbRaw), Words);
238
+ Pjpm->jpm_TotalMemWords += Words;
239
+ }
240
+ else { J__UDYSETALLOCERROR(PjbbRaw); }
241
+
242
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBB(), Words = %lu\n", PjbbRaw,
243
+ j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
244
+ MALLOCBITS_SET(Pjbb_t, PjbbRaw);
245
+ return(PjbbRaw);
246
+
247
+} // j__udyAllocJBB()
248
+
249
+
250
+FUNCTION Pjp_t j__udyAllocJBBJP(Word_t NumJPs, Pjpm_t Pjpm)
251
+{
252
+ Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
253
+ Pjp_t PjpRaw;
254
+
255
+ PjpRaw = (Pjp_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
256
+
257
+ if ((Word_t) PjpRaw > sizeof(Word_t))
258
+ {
259
+ Pjpm->jpm_TotalMemWords += Words;
260
+ }
261
+ else { J__UDYSETALLOCERROR(PjpRaw); }
262
+
263
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJBBJP(%lu), Words = %lu\n", PjpRaw,
264
+ j__udyMemSequence++, NumJPs, Words, (Pjpm->jpm_Pop0) + 2);
265
+ MALLOCBITS_SET(Pjp_t, PjpRaw);
266
+ return(PjpRaw);
267
+
268
+} // j__udyAllocJBBJP()
269
+
270
+
271
+FUNCTION Pjbu_t j__udyAllocJBU(Pjpm_t Pjpm)
272
+{
273
+ Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
274
+ Pjbu_t PjbuRaw = (Pjbu_t) MALLOC(JudyMallocVirtual,
275
+ Pjpm->jpm_TotalMemWords, Words);
276
+
277
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jbu_t));
278
+
279
+ if ((Word_t) PjbuRaw > sizeof(Word_t))
280
+ {
281
+ Pjpm->jpm_TotalMemWords += Words;
282
+ }
283
+ else { J__UDYSETALLOCERROR(PjbuRaw); }
284
+
285
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBU(), Words = %lu\n", PjbuRaw,
286
+ j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
287
+ MALLOCBITS_SET(Pjbu_t, PjbuRaw);
288
+ return(PjbuRaw);
289
+
290
+} // j__udyAllocJBU()
291
+
292
+
293
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
294
+
295
+FUNCTION Pjll_t j__udyAllocJLL1(Word_t Pop1, Pjpm_t Pjpm)
296
+{
297
+ Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
298
+ Pjll_t PjllRaw;
299
+
300
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
301
+
302
+ if ((Word_t) PjllRaw > sizeof(Word_t))
303
+ {
304
+ Pjpm->jpm_TotalMemWords += Words;
305
+ }
306
+ else { J__UDYSETALLOCERROR(PjllRaw); }
307
+
308
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL1(%lu), Words = %lu\n", PjllRaw,
309
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
310
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
311
+ return(PjllRaw);
312
+
313
+} // j__udyAllocJLL1()
314
+
315
+#endif // (JUDYL || (! JU_64BIT))
316
+
317
+
318
+FUNCTION Pjll_t j__udyAllocJLL2(Word_t Pop1, Pjpm_t Pjpm)
319
+{
320
+ Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
321
+ Pjll_t PjllRaw;
322
+
323
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
324
+
325
+ if ((Word_t) PjllRaw > sizeof(Word_t))
326
+ {
327
+ Pjpm->jpm_TotalMemWords += Words;
328
+ }
329
+ else { J__UDYSETALLOCERROR(PjllRaw); }
330
+
331
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL2(%lu), Words = %lu\n", PjllRaw,
332
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
333
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
334
+ return(PjllRaw);
335
+
336
+} // j__udyAllocJLL2()
337
+
338
+
339
+FUNCTION Pjll_t j__udyAllocJLL3(Word_t Pop1, Pjpm_t Pjpm)
340
+{
341
+ Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
342
+ Pjll_t PjllRaw;
343
+
344
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
345
+
346
+ if ((Word_t) PjllRaw > sizeof(Word_t))
347
+ {
348
+ Pjpm->jpm_TotalMemWords += Words;
349
+ }
350
+ else { J__UDYSETALLOCERROR(PjllRaw); }
351
+
352
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL3(%lu), Words = %lu\n", PjllRaw,
353
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
354
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
355
+ return(PjllRaw);
356
+
357
+} // j__udyAllocJLL3()
358
+
359
+
360
+#ifdef JU_64BIT
361
+
362
+FUNCTION Pjll_t j__udyAllocJLL4(Word_t Pop1, Pjpm_t Pjpm)
363
+{
364
+ Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
365
+ Pjll_t PjllRaw;
366
+
367
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
368
+
369
+ if ((Word_t) PjllRaw > sizeof(Word_t))
370
+ {
371
+ Pjpm->jpm_TotalMemWords += Words;
372
+ }
373
+ else { J__UDYSETALLOCERROR(PjllRaw); }
374
+
375
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL4(%lu), Words = %lu\n", PjllRaw,
376
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
377
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
378
+ return(PjllRaw);
379
+
380
+} // j__udyAllocJLL4()
381
+
382
+
383
+FUNCTION Pjll_t j__udyAllocJLL5(Word_t Pop1, Pjpm_t Pjpm)
384
+{
385
+ Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
386
+ Pjll_t PjllRaw;
387
+
388
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
389
+
390
+ if ((Word_t) PjllRaw > sizeof(Word_t))
391
+ {
392
+ Pjpm->jpm_TotalMemWords += Words;
393
+ }
394
+ else { J__UDYSETALLOCERROR(PjllRaw); }
395
+
396
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL5(%lu), Words = %lu\n", PjllRaw,
397
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
398
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
399
+ return(PjllRaw);
400
+
401
+} // j__udyAllocJLL5()
402
+
403
+
404
+FUNCTION Pjll_t j__udyAllocJLL6(Word_t Pop1, Pjpm_t Pjpm)
405
+{
406
+ Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
407
+ Pjll_t PjllRaw;
408
+
409
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
410
+
411
+ if ((Word_t) PjllRaw > sizeof(Word_t))
412
+ {
413
+ Pjpm->jpm_TotalMemWords += Words;
414
+ }
415
+ else { J__UDYSETALLOCERROR(PjllRaw); }
416
+
417
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL6(%lu), Words = %lu\n", PjllRaw,
418
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
419
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
420
+ return(PjllRaw);
421
+
422
+} // j__udyAllocJLL6()
423
+
424
+
425
+FUNCTION Pjll_t j__udyAllocJLL7(Word_t Pop1, Pjpm_t Pjpm)
426
+{
427
+ Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
428
+ Pjll_t PjllRaw;
429
+
430
+ PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
431
+
432
+ if ((Word_t) PjllRaw > sizeof(Word_t))
433
+ {
434
+ Pjpm->jpm_TotalMemWords += Words;
435
+ }
436
+ else { J__UDYSETALLOCERROR(PjllRaw); }
437
+
438
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL7(%lu), Words = %lu\n", PjllRaw,
439
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
440
+ MALLOCBITS_SET(Pjll_t, PjllRaw);
441
+ return(PjllRaw);
442
+
443
+} // j__udyAllocJLL7()
444
+
445
+#endif // JU_64BIT
446
+
447
+
448
+// Note: Root-level leaf addresses are always whole words (Pjlw_t), and unlike
449
+// other j__udyAlloc*() functions, they are returned non-raw, that is, without
450
+// malloc namespace or root pointer type bits (the latter are added later by
451
+// the caller):
452
+
453
+FUNCTION Pjlw_t j__udyAllocJLW(Word_t Pop1)
454
+{
455
+ Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
456
+ Pjlw_t Pjlw = (Pjlw_t) MALLOC(JudyMalloc, Words, Words);
457
+
458
+ TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLW(%lu), Words = %lu\n", Pjlw,
459
+ j__udyMemSequence++, Pop1, Words, Pop1);
460
+ // MALLOCBITS_SET(Pjlw_t, Pjlw); // see above.
461
+ return(Pjlw);
462
+
463
+} // j__udyAllocJLW()
464
+
465
+
466
+FUNCTION Pjlb_t j__udyAllocJLB1(Pjpm_t Pjpm)
467
+{
468
+ Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
469
+ Pjlb_t PjlbRaw;
470
+
471
+ PjlbRaw = (Pjlb_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
472
+
473
+ assert((Words * cJU_BYTESPERWORD) == sizeof(jlb_t));
474
+
475
+ if ((Word_t) PjlbRaw > sizeof(Word_t))
476
+ {
477
+ ZEROWORDS(P_JLB(PjlbRaw), Words);
478
+ Pjpm->jpm_TotalMemWords += Words;
479
+ }
480
+ else { J__UDYSETALLOCERROR(PjlbRaw); }
481
+
482
+ TRACE_ALLOC5("0x%x %8lu = j__udyAllocJLB1(), Words = %lu\n", PjlbRaw,
483
+ j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
484
+ MALLOCBITS_SET(Pjlb_t, PjlbRaw);
485
+ return(PjlbRaw);
486
+
487
+} // j__udyAllocJLB1()
488
+
489
+
490
+#ifdef JUDYL
491
+
492
+FUNCTION Pjv_t j__udyLAllocJV(Word_t Pop1, Pjpm_t Pjpm)
493
+{
494
+ Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
495
+ Pjv_t PjvRaw;
496
+
497
+ PjvRaw = (Pjv_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
498
+
499
+ if ((Word_t) PjvRaw > sizeof(Word_t))
500
+ {
501
+ Pjpm->jpm_TotalMemWords += Words;
502
+ }
503
+ else { J__UDYSETALLOCERROR(PjvRaw); }
504
+
505
+ TRACE_ALLOC6("0x%x %8lu = j__udyLAllocJV(%lu), Words = %lu\n", PjvRaw,
506
+ j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
507
+ MALLOCBITS_SET(Pjv_t, PjvRaw);
508
+ return(PjvRaw);
509
+
510
+} // j__udyLAllocJV()
511
+
512
+#endif // JUDYL
513
+
514
+
515
+// ****************************************************************************
516
+// FREE FUNCTIONS:
517
+//
518
+// To help the compiler catch coding errors, each function takes a specific
519
+// object type to free.
520
+
521
+
522
+// Note: j__udyFreeJPM() receives a root pointer with NO root pointer type
523
+// bits present, that is, they must be stripped by the caller using P_JPM():
524
+
525
+FUNCTION void j__udyFreeJPM(Pjpm_t PjpmFree, Pjpm_t PjpmStats)
526
+{
527
+ Word_t Words = (sizeof(jpm_t) + cJU_BYTESPERWORD - 1) / cJU_BYTESPERWORD;
528
+
529
+ // MALLOCBITS_TEST(Pjpm_t, PjpmFree); // see above.
530
+ JudyFree((Pvoid_t) PjpmFree, Words);
531
+
532
+ if (PjpmStats != (Pjpm_t) NULL) PjpmStats->jpm_TotalMemWords -= Words;
533
+
534
+// Note: Log PjpmFree->jpm_Pop0, similar to other j__udyFree*() functions, not
535
+// an assumed value of cJU_LEAFW_MAXPOP1, for when the caller is
536
+// Judy*FreeArray(), jpm_Pop0 is set to 0, and the population after the free
537
+// really will be 0, not cJU_LEAFW_MAXPOP1.
538
+
539
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJPM(%lu), Words = %lu\n", PjpmFree,
540
+ j__udyMemSequence++, Words, Words, PjpmFree->jpm_Pop0);
541
+
542
+
543
+} // j__udyFreeJPM()
544
+
545
+
546
+FUNCTION void j__udyFreeJBL(Pjbl_t Pjbl, Pjpm_t Pjpm)
547
+{
548
+ Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
549
+
550
+ MALLOCBITS_TEST(Pjbl_t, Pjbl);
551
+ JudyFreeVirtual((Pvoid_t) Pjbl, Words);
552
+
553
+ Pjpm->jpm_TotalMemWords -= Words;
554
+
555
+ TRACE_FREE5("0x%x %8lu = j__udyFreeJBL(), Words = %lu\n", Pjbl,
556
+ j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
557
+
558
+
559
+} // j__udyFreeJBL()
560
+
561
+
562
+FUNCTION void j__udyFreeJBB(Pjbb_t Pjbb, Pjpm_t Pjpm)
563
+{
564
+ Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
565
+
566
+ MALLOCBITS_TEST(Pjbb_t, Pjbb);
567
+ JudyFreeVirtual((Pvoid_t) Pjbb, Words);
568
+
569
+ Pjpm->jpm_TotalMemWords -= Words;
570
+
571
+ TRACE_FREE5("0x%x %8lu = j__udyFreeJBB(), Words = %lu\n", Pjbb,
572
+ j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
573
+
574
+
575
+} // j__udyFreeJBB()
576
+
577
+
578
+FUNCTION void j__udyFreeJBBJP(Pjp_t Pjp, Word_t NumJPs, Pjpm_t Pjpm)
579
+{
580
+ Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
581
+
582
+ MALLOCBITS_TEST(Pjp_t, Pjp);
583
+ JudyFree((Pvoid_t) Pjp, Words);
584
+
585
+ Pjpm->jpm_TotalMemWords -= Words;
586
+
587
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJBBJP(%lu), Words = %lu\n", Pjp,
588
+ j__udyMemSequence++, NumJPs, Words, Pjpm->jpm_Pop0);
589
+
590
+
591
+} // j__udyFreeJBBJP()
592
+
593
+
594
+FUNCTION void j__udyFreeJBU(Pjbu_t Pjbu, Pjpm_t Pjpm)
595
+{
596
+ Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
597
+
598
+ MALLOCBITS_TEST(Pjbu_t, Pjbu);
599
+ JudyFreeVirtual((Pvoid_t) Pjbu, Words);
600
+
601
+ Pjpm->jpm_TotalMemWords -= Words;
602
+
603
+ TRACE_FREE5("0x%x %8lu = j__udyFreeJBU(), Words = %lu\n", Pjbu,
604
+ j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
605
+
606
+
607
+} // j__udyFreeJBU()
608
+
609
+
610
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
611
+
612
+FUNCTION void j__udyFreeJLL1(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
613
+{
614
+ Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
615
+
616
+ MALLOCBITS_TEST(Pjll_t, Pjll);
617
+ JudyFree((Pvoid_t) Pjll, Words);
618
+
619
+ Pjpm->jpm_TotalMemWords -= Words;
620
+
621
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL1(%lu), Words = %lu\n", Pjll,
622
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
623
+
624
+
625
+} // j__udyFreeJLL1()
626
+
627
+#endif // (JUDYL || (! JU_64BIT))
628
+
629
+
630
+FUNCTION void j__udyFreeJLL2(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
631
+{
632
+ Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
633
+
634
+ MALLOCBITS_TEST(Pjll_t, Pjll);
635
+ JudyFree((Pvoid_t) Pjll, Words);
636
+
637
+ Pjpm->jpm_TotalMemWords -= Words;
638
+
639
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL2(%lu), Words = %lu\n", Pjll,
640
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
641
+
642
+
643
+} // j__udyFreeJLL2()
644
+
645
+
646
+FUNCTION void j__udyFreeJLL3(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
647
+{
648
+ Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
649
+
650
+ MALLOCBITS_TEST(Pjll_t, Pjll);
651
+ JudyFree((Pvoid_t) Pjll, Words);
652
+
653
+ Pjpm->jpm_TotalMemWords -= Words;
654
+
655
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL3(%lu), Words = %lu\n", Pjll,
656
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
657
+
658
+
659
+} // j__udyFreeJLL3()
660
+
661
+
662
+#ifdef JU_64BIT
663
+
664
+FUNCTION void j__udyFreeJLL4(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
665
+{
666
+ Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
667
+
668
+ MALLOCBITS_TEST(Pjll_t, Pjll);
669
+ JudyFree((Pvoid_t) Pjll, Words);
670
+
671
+ Pjpm->jpm_TotalMemWords -= Words;
672
+
673
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL4(%lu), Words = %lu\n", Pjll,
674
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
675
+
676
+
677
+} // j__udyFreeJLL4()
678
+
679
+
680
+FUNCTION void j__udyFreeJLL5(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
681
+{
682
+ Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
683
+
684
+ MALLOCBITS_TEST(Pjll_t, Pjll);
685
+ JudyFree((Pvoid_t) Pjll, Words);
686
+
687
+ Pjpm->jpm_TotalMemWords -= Words;
688
+
689
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL5(%lu), Words = %lu\n", Pjll,
690
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
691
+
692
+
693
+} // j__udyFreeJLL5()
694
+
695
+
696
+FUNCTION void j__udyFreeJLL6(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
697
+{
698
+ Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
699
+
700
+ MALLOCBITS_TEST(Pjll_t, Pjll);
701
+ JudyFree((Pvoid_t) Pjll, Words);
702
+
703
+ Pjpm->jpm_TotalMemWords -= Words;
704
+
705
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL6(%lu), Words = %lu\n", Pjll,
706
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
707
+
708
+
709
+} // j__udyFreeJLL6()
710
+
711
+
712
+FUNCTION void j__udyFreeJLL7(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
713
+{
714
+ Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
715
+
716
+ MALLOCBITS_TEST(Pjll_t, Pjll);
717
+ JudyFree((Pvoid_t) Pjll, Words);
718
+
719
+ Pjpm->jpm_TotalMemWords -= Words;
720
+
721
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLL7(%lu), Words = %lu\n", Pjll,
722
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
723
+
724
+
725
+} // j__udyFreeJLL7()
726
+
727
+#endif // JU_64BIT
728
+
729
+
730
+// Note: j__udyFreeJLW() receives a root pointer with NO root pointer type
731
+// bits present, that is, they are stripped by P_JLW():
732
+
733
+FUNCTION void j__udyFreeJLW(Pjlw_t Pjlw, Word_t Pop1, Pjpm_t Pjpm)
734
+{
735
+ Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
736
+
737
+ // MALLOCBITS_TEST(Pjlw_t, Pjlw); // see above.
738
+ JudyFree((Pvoid_t) Pjlw, Words);
739
+
740
+ if (Pjpm) Pjpm->jpm_TotalMemWords -= Words;
741
+
742
+ TRACE_FREE6("0x%x %8lu = j__udyFreeJLW(%lu), Words = %lu\n", Pjlw,
743
+ j__udyMemSequence++, Pop1, Words, Pop1 - 1);
744
+
745
+
746
+} // j__udyFreeJLW()
747
+
748
+
749
+FUNCTION void j__udyFreeJLB1(Pjlb_t Pjlb, Pjpm_t Pjpm)
750
+{
751
+ Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
752
+
753
+ MALLOCBITS_TEST(Pjlb_t, Pjlb);
754
+ JudyFree((Pvoid_t) Pjlb, Words);
755
+
756
+ Pjpm->jpm_TotalMemWords -= Words;
757
+
758
+ TRACE_FREE5("0x%x %8lu = j__udyFreeJLB1(), Words = %lu\n", Pjlb,
759
+ j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
760
+
761
+
762
+} // j__udyFreeJLB1()
763
+
764
+
765
+#ifdef JUDYL
766
+
767
+FUNCTION void j__udyLFreeJV(Pjv_t Pjv, Word_t Pop1, Pjpm_t Pjpm)
768
+{
769
+ Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
770
+
771
+ MALLOCBITS_TEST(Pjv_t, Pjv);
772
+ JudyFree((Pvoid_t) Pjv, Words);
773
+
774
+ Pjpm->jpm_TotalMemWords -= Words;
775
+
776
+ TRACE_FREE6("0x%x %8lu = j__udyLFreeJV(%lu), Words = %lu\n", Pjv,
777
+ j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
778
+
779
+
780
+} // j__udyLFreeJV()
781
+
782
+#endif // JUDYL
libnetdata/libjudy/src/JudyL/JudyLMemActive.c
new
+259
@@ -0,0 +1,259 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.7 $ $Source: /judy/src/JudyCommon/JudyMemActive.c $
19
+//
20
+// Return number of bytes of memory used to support a Judy1/L array.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+
23
+#if (! (defined(JUDY1) || defined(JUDYL)))
24
+#error: One of -DJUDY1 or -DJUDYL must be specified.
25
+#endif
26
+
27
+#ifdef JUDY1
28
+#include "Judy1.h"
29
+#else
30
+#include "JudyL.h"
31
+#endif
32
+
33
+#include "JudyPrivate1L.h"
34
+
35
+FUNCTION static Word_t j__udyGetMemActive(Pjp_t);
36
+
37
+
38
+// ****************************************************************************
39
+// J U D Y 1 M E M A C T I V E
40
+// J U D Y L M E M A C T I V E
41
+
42
+#ifdef JUDY1
43
+FUNCTION Word_t Judy1MemActive
44
+#else
45
+FUNCTION Word_t JudyLMemActive
46
+#endif
47
+ (
48
+ Pcvoid_t PArray // from which to retrieve.
49
+ )
50
+{
51
+ if (PArray == (Pcvoid_t)NULL) return(0);
52
+
53
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
54
+ {
55
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
56
+ Word_t Words = Pjlw[0] + 1; // population.
57
+#ifdef JUDY1
58
+ return((Words + 1) * sizeof(Word_t));
59
+#else
60
+ return(((Words * 2) + 1) * sizeof(Word_t));
61
+#endif
62
+ }
63
+ else
64
+ {
65
+ Pjpm_t Pjpm = P_JPM(PArray);
66
+ return(j__udyGetMemActive(&Pjpm->jpm_JP) + sizeof(jpm_t));
67
+ }
68
+
69
+} // JudyMemActive()
70
+
71
+
72
+// ****************************************************************************
73
+// __ J U D Y G E T M E M A C T I V E
74
+
75
+FUNCTION static Word_t j__udyGetMemActive(
76
+ Pjp_t Pjp) // top of subtree.
77
+{
78
+ Word_t offset; // in a branch.
79
+ Word_t Bytes = 0; // actual bytes used at this level.
80
+ Word_t IdxSz; // bytes per index in leaves
81
+
82
+ switch (JU_JPTYPE(Pjp))
83
+ {
84
+
85
+ case cJU_JPBRANCH_L2:
86
+ case cJU_JPBRANCH_L3:
87
+#ifdef JU_64BIT
88
+ case cJU_JPBRANCH_L4:
89
+ case cJU_JPBRANCH_L5:
90
+ case cJU_JPBRANCH_L6:
91
+ case cJU_JPBRANCH_L7:
92
+#endif
93
+ case cJU_JPBRANCH_L:
94
+ {
95
+ Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
96
+
97
+ for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
98
+ Bytes += j__udyGetMemActive((Pjbl->jbl_jp) + offset);
99
+
100
+ return(Bytes + sizeof(jbl_t));
101
+ }
102
+
103
+ case cJU_JPBRANCH_B2:
104
+ case cJU_JPBRANCH_B3:
105
+#ifdef JU_64BIT
106
+ case cJU_JPBRANCH_B4:
107
+ case cJU_JPBRANCH_B5:
108
+ case cJU_JPBRANCH_B6:
109
+ case cJU_JPBRANCH_B7:
110
+#endif
111
+ case cJU_JPBRANCH_B:
112
+ {
113
+ Word_t subexp;
114
+ Word_t jpcount;
115
+ Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
116
+
117
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
118
+ {
119
+ jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
120
+ Bytes += jpcount * sizeof(jp_t);
121
+
122
+ for (offset = 0; offset < jpcount; ++offset)
123
+ {
124
+ Bytes += j__udyGetMemActive(P_JP(JU_JBB_PJP(Pjbb, subexp))
125
+ + offset);
126
+ }
127
+ }
128
+
129
+ return(Bytes + sizeof(jbb_t));
130
+ }
131
+
132
+ case cJU_JPBRANCH_U2:
133
+ case cJU_JPBRANCH_U3:
134
+#ifdef JU_64BIT
135
+ case cJU_JPBRANCH_U4:
136
+ case cJU_JPBRANCH_U5:
137
+ case cJU_JPBRANCH_U6:
138
+ case cJU_JPBRANCH_U7:
139
+#endif
140
+ case cJU_JPBRANCH_U:
141
+ {
142
+ Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
143
+
144
+ for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
145
+ {
146
+ if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
147
+ && ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
148
+ {
149
+ continue; // skip null JP to save time.
150
+ }
151
+
152
+ Bytes += j__udyGetMemActive(Pjbu->jbu_jp + offset);
153
+ }
154
+
155
+ return(Bytes + sizeof(jbu_t));
156
+ }
157
+
158
+
159
+// -- Cases below here terminate and do not recurse. --
160
+
161
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
162
+ case cJU_JPLEAF1: IdxSz = 1; goto LeafWords;
163
+#endif
164
+ case cJU_JPLEAF2: IdxSz = 2; goto LeafWords;
165
+ case cJU_JPLEAF3: IdxSz = 3; goto LeafWords;
166
+#ifdef JU_64BIT
167
+ case cJU_JPLEAF4: IdxSz = 4; goto LeafWords;
168
+ case cJU_JPLEAF5: IdxSz = 5; goto LeafWords;
169
+ case cJU_JPLEAF6: IdxSz = 6; goto LeafWords;
170
+ case cJU_JPLEAF7: IdxSz = 7; goto LeafWords;
171
+#endif
172
+LeafWords:
173
+
174
+#ifdef JUDY1
175
+ return(IdxSz * (JU_JPLEAF_POP0(Pjp) + 1));
176
+#else
177
+ return((IdxSz + sizeof(Word_t))
178
+ * (JU_JPLEAF_POP0(Pjp) + 1));
179
+#endif
180
+ case cJU_JPLEAF_B1:
181
+ {
182
+#ifdef JUDY1
183
+ return(sizeof(jlb_t));
184
+#else
185
+ Bytes = (JU_JPLEAF_POP0(Pjp) + 1) * sizeof(Word_t);
186
+
187
+ return(Bytes + sizeof(jlb_t));
188
+#endif
189
+ }
190
+
191
+ JUDY1CODE(case cJ1_JPFULLPOPU1: return(0);)
192
+
193
+#ifdef JUDY1
194
+#define J__Mpy 0
195
+#else
196
+#define J__Mpy sizeof(Word_t)
197
+#endif
198
+
199
+ case cJU_JPIMMED_1_01: return(0);
200
+ case cJU_JPIMMED_2_01: return(0);
201
+ case cJU_JPIMMED_3_01: return(0);
202
+#ifdef JU_64BIT
203
+ case cJU_JPIMMED_4_01: return(0);
204
+ case cJU_JPIMMED_5_01: return(0);
205
+ case cJU_JPIMMED_6_01: return(0);
206
+ case cJU_JPIMMED_7_01: return(0);
207
+#endif
208
+
209
+ case cJU_JPIMMED_1_02: return(J__Mpy * 2);
210
+ case cJU_JPIMMED_1_03: return(J__Mpy * 3);
211
+#if (defined(JUDY1) || defined(JU_64BIT))
212
+ case cJU_JPIMMED_1_04: return(J__Mpy * 4);
213
+ case cJU_JPIMMED_1_05: return(J__Mpy * 5);
214
+ case cJU_JPIMMED_1_06: return(J__Mpy * 6);
215
+ case cJU_JPIMMED_1_07: return(J__Mpy * 7);
216
+#endif
217
+#if (defined(JUDY1) && defined(JU_64BIT))
218
+ case cJ1_JPIMMED_1_08: return(0);
219
+ case cJ1_JPIMMED_1_09: return(0);
220
+ case cJ1_JPIMMED_1_10: return(0);
221
+ case cJ1_JPIMMED_1_11: return(0);
222
+ case cJ1_JPIMMED_1_12: return(0);
223
+ case cJ1_JPIMMED_1_13: return(0);
224
+ case cJ1_JPIMMED_1_14: return(0);
225
+ case cJ1_JPIMMED_1_15: return(0);
226
+#endif
227
+
228
+#if (defined(JUDY1) || defined(JU_64BIT))
229
+ case cJU_JPIMMED_2_02: return(J__Mpy * 2);
230
+ case cJU_JPIMMED_2_03: return(J__Mpy * 3);
231
+#endif
232
+#if (defined(JUDY1) && defined(JU_64BIT))
233
+ case cJ1_JPIMMED_2_04: return(0);
234
+ case cJ1_JPIMMED_2_05: return(0);
235
+ case cJ1_JPIMMED_2_06: return(0);
236
+ case cJ1_JPIMMED_2_07: return(0);
237
+#endif
238
+
239
+#if (defined(JUDY1) || defined(JU_64BIT))
240
+ case cJU_JPIMMED_3_02: return(J__Mpy * 2);
241
+#endif
242
+#if (defined(JUDY1) && defined(JU_64BIT))
243
+ case cJ1_JPIMMED_3_03: return(0);
244
+ case cJ1_JPIMMED_3_04: return(0);
245
+ case cJ1_JPIMMED_3_05: return(0);
246
+
247
+ case cJ1_JPIMMED_4_02: return(0);
248
+ case cJ1_JPIMMED_4_03: return(0);
249
+ case cJ1_JPIMMED_5_02: return(0);
250
+ case cJ1_JPIMMED_5_03: return(0);
251
+ case cJ1_JPIMMED_6_02: return(0);
252
+ case cJ1_JPIMMED_7_02: return(0);
253
+#endif
254
+
255
+ } // switch (JU_JPTYPE(Pjp))
256
+
257
+ return(0); // to make some compilers happy.
258
+
259
+} // j__udyGetMemActive()
libnetdata/libjudy/src/JudyL/JudyLMemUsed.c
new
+61
@@ -0,0 +1,61 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.5 $ $Source: /judy/src/JudyCommon/JudyMemUsed.c $
19
+//
20
+// Return number of bytes of memory used to support a Judy1/L array.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+
23
+#if (! (defined(JUDY1) || defined(JUDYL)))
24
+#error: One of -DJUDY1 or -DJUDYL must be specified.
25
+#endif
26
+
27
+#ifdef JUDY1
28
+#include "Judy1.h"
29
+#else
30
+#include "JudyL.h"
31
+#endif
32
+
33
+#include "JudyPrivate1L.h"
34
+
35
+#ifdef JUDY1
36
+FUNCTION Word_t Judy1MemUsed
37
+#else // JUDYL
38
+FUNCTION Word_t JudyLMemUsed
39
+#endif
40
+ (
41
+ Pcvoid_t PArray // from which to retrieve.
42
+ )
43
+{
44
+ Word_t Words = 0;
45
+
46
+ if (PArray == (Pcvoid_t) NULL) return(0);
47
+
48
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
49
+ {
50
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
51
+ Words = JU_LEAFWPOPTOWORDS(Pjlw[0] + 1); // based on pop1.
52
+ }
53
+ else
54
+ {
55
+ Pjpm_t Pjpm = P_JPM(PArray);
56
+ Words = Pjpm->jpm_TotalMemWords;
57
+ }
58
+
59
+ return(Words * sizeof(Word_t)); // convert to bytes.
60
+
61
+} // Judy1MemUsed() / JudyLMemUsed()
libnetdata/libjudy/src/JudyL/JudyLNext.c
new
+1890
@@ -0,0 +1,1890 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.54 $ $Source: /judy/src/JudyCommon/JudyPrevNext.c $
19
+//
20
+// Judy*Prev() and Judy*Next() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// Compile with -DJUDYNEXT for the Judy*Next() function; otherwise defaults to
24
+// Judy*Prev().
25
+
26
+#if (! (defined(JUDY1) || defined(JUDYL)))
27
+#error: One of -DJUDY1 or -DJUDYL must be specified.
28
+#endif
29
+
30
+#ifndef JUDYNEXT
31
+#ifndef JUDYPREV
32
+#define JUDYPREV 1 // neither set => use default.
33
+#endif
34
+#endif
35
+
36
+#ifdef JUDY1
37
+#include "Judy1.h"
38
+#else
39
+#include "JudyL.h"
40
+#endif
41
+
42
+#include "JudyPrivate1L.h"
43
+
44
+
45
+// ****************************************************************************
46
+// J U D Y 1 P R E V
47
+// J U D Y 1 N E X T
48
+// J U D Y L P R E V
49
+// J U D Y L N E X T
50
+//
51
+// See the manual entry for the API.
52
+//
53
+// OVERVIEW OF Judy*Prev():
54
+//
55
+// Use a reentrant switch statement (state machine, SM1 = "get") to decode the
56
+// callers *PIndex-1, starting with the (PArray), through branches, if
57
+// any, down to an immediate or a leaf. Look for *PIndex-1 in that leaf, and
58
+// if found, return it.
59
+//
60
+// A dead end is either a branch that does not contain a JP for the appropriate
61
+// digit in *PIndex-1, or a leaf that does not contain the undecoded digits of
62
+// *PIndex-1. Upon reaching a dead end, backtrack through the leaf/branches
63
+// that were just traversed, using a list (history) of parent JPs that is built
64
+// while going forward in SM1Get. Start with the current leaf or branch. In a
65
+// backtracked leaf, look for an Index less than *PIndex-1. In each
66
+// backtracked branch, look "sideways" for the next JP, if any, lower than the
67
+// one for the digit (from *PIndex-1) that was previously decoded. While
68
+// backtracking, if a leaf has no previous Index or a branch has no lower JP,
69
+// go to its parent branch in turn. Upon reaching the JRP, return failure, "no
70
+// previous Index". The backtrack process is sufficiently different from
71
+// SM1Get to merit its own separate reentrant switch statement (SM2 =
72
+// "backtrack").
73
+//
74
+// While backtracking, upon finding a lower JP in a branch, there is certain to
75
+// be a "prev" Index under that JP (unless the Judy array is corrupt).
76
+// Traverse forward again, this time taking the last (highest, right-most) JP
77
+// in each branch, and the last (highest) Index upon reaching an immediate or a
78
+// leaf. This traversal is sufficiently different from SM1Get and SM2Backtrack
79
+// to merit its own separate reentrant switch statement (SM3 = "findlimit").
80
+//
81
+// "Decode" bytes in JPs complicate this process a little. In SM1Get, when a
82
+// JP is a narrow pointer, that is, when states are skipped (so the skipped
83
+// digits are stored in jp_DcdPopO), compare the relevant digits to the same
84
+// digits in *PIndex-1. If they are EQUAL, proceed in SM1Get as before. If
85
+// jp_DcdPopOs digits are GREATER, treat the JP as a dead end and proceed in
86
+// SM2Backtrack. If jp_DcdPopOs digits are LESS, treat the JP as if it had
87
+// just been found during a backtrack and proceed directly in SM3Findlimit.
88
+//
89
+// Note that Decode bytes can be ignored in SM3Findlimit; they dont matter.
90
+// Also note that in practice the Decode bytes are routinely compared with
91
+// *PIndex-1 because thats simpler and no slower than first testing for
92
+// narrowness.
93
+//
94
+// Decode bytes also make it unnecessary to construct the Index to return (the
95
+// revised *PIndex) during the search. This step is deferred until finding an
96
+// Index during backtrack or findlimit, before returning it. The first digit
97
+// of *PIndex is derived (saved) based on which JP is used in a JRP branch.
98
+// The remaining digits are obtained from the jp_DcdPopO field in the JP (if
99
+// any) above the immediate or leaf containing the found (prev) Index, plus the
100
+// remaining digit(s) in the immediate or leaf itself. In the case of a LEAFW,
101
+// the Index to return is found directly in the leaf.
102
+//
103
+// Note: Theoretically, as described above, upon reaching a dead end, SM1Get
104
+// passes control to SM2Backtrack to look sideways, even in a leaf. Actually
105
+// its a little more efficient for the SM1Get leaf cases to shortcut this and
106
+// take care of the sideways searches themselves. Hence the history list only
107
+// contains branch JPs, and SM2Backtrack only handles branches. In fact, even
108
+// the branch handling cases in SM1Get do some shortcutting (sideways
109
+// searching) to avoid pushing history and calling SM2Backtrack unnecessarily.
110
+//
111
+// Upon reaching an Index to return after backtracking, *PIndex must be
112
+// modified to the found Index. In principle this could be done by building
113
+// the Index from a saved rootdigit (in the top branch) plus the Dcd bytes from
114
+// the parent JP plus the appropriate Index bytes from the leaf. However,
115
+// Immediates are difficult because their parent JPs lack one (last) digit. So
116
+// instead just build the *PIndex to return "top down" while backtracking and
117
+// findlimiting.
118
+//
119
+// This function is written iteratively for speed, rather than recursively.
120
+//
121
+// CAVEATS:
122
+//
123
+// Why use a backtrack list (history stack), since it has finite size? The
124
+// size is small for Judy on both 32-bit and 64-bit systems, and a list (really
125
+// just an array) is fast to maintain and use. Other alternatives include
126
+// doing a lookahead (lookaside) in each branch while traversing forward
127
+// (decoding), and restarting from the top upon a dead end.
128
+//
129
+// A lookahead means noting the last branch traversed which contained a
130
+// non-null JP lower than the one specified by a digit in *PIndex-1, and
131
+// returning to that point for SM3Findlimit. This seems like a good idea, and
132
+// should be pretty cheap for linear and bitmap branches, but it could result
133
+// in up to 31 unnecessary additional cache line fills (in extreme cases) for
134
+// every uncompressed branch traversed. We have considered means of attaching
135
+// to or hiding within an uncompressed branch (in null JPs) a "cache line map"
136
+// or other structure, such as an offset to the next non-null JP, that would
137
+// speed this up, but it seems unnecessary merely to avoid having a
138
+// finite-length list (array). (If JudySL is ever made "native", the finite
139
+// list length will be an issue.)
140
+//
141
+// Restarting at the top of the Judy array after a dead end requires a careful
142
+// modification of *PIndex-1 to decrement the digit for the parent branch and
143
+// set the remaining lower digits to all 1s. This must be repeated each time a
144
+// parent branch contains another dead end, so even though it should all happen
145
+// in cache, the CPU time can be excessive. (For JudySL or an equivalent
146
+// "infinitely deep" Judy array, consider a hybrid of a large, finite,
147
+// "circular" list and a restart-at-top when the list is backtracked to
148
+// exhaustion.)
149
+//
150
+// Why search for *PIndex-1 instead of *PIndex during SM1Get? In rare
151
+// instances this prevents an unnecessary decode down the wrong path followed
152
+// by a backtrack; its pretty cheap to set up initially; and it means the
153
+// SM1Get machine can simply return if/when it finds that Index.
154
+//
155
+// TBD: Wed like to enhance this function to make successive searches faster.
156
+// This would require saving some previous state, including the previous Index
157
+// returned, and in which leaf it was found. If the next call is for the same
158
+// Index and the array has not been modified, start at the same leaf. This
159
+// should be much easier to implement since this is iterative rather than
160
+// recursive code.
161
+//
162
+// VARIATIONS FOR Judy*Next():
163
+//
164
+// The Judy*Next() code is nearly a perfect mirror of the Judy*Prev() code.
165
+// See the Judy*Prev() overview comments, and mentally switch the following:
166
+//
167
+// - "*PIndex-1" => "*PIndex+1"
168
+// - "less than" => "greater than"
169
+// - "lower" => "higher"
170
+// - "lowest" => "highest"
171
+// - "next-left" => "next-right"
172
+// - "right-most" => "left-most"
173
+//
174
+// Note: SM3Findlimit could be called SM3Findmax/SM3Findmin, but a common name
175
+// for both Prev and Next means many fewer ifdefs in this code.
176
+//
177
+// TBD: Currently this code traverses a JP whether its expanse is partially or
178
+// completely full (populated). For Judy1 (only), since there is no value area
179
+// needed, consider shortcutting to a "success" return upon encountering a full
180
+// JP in SM1Get (or even SM3Findlimit?) A full JP looks like this:
181
+//
182
+// (((JU_JPDCDPOP0(Pjp) ^ cJU_ALLONES) & cJU_POP0MASK(cLevel)) == 0)
183
+
184
+#ifdef JUDY1
185
+#ifdef JUDYPREV
186
+FUNCTION int Judy1Prev
187
+#else
188
+FUNCTION int Judy1Next
189
+#endif
190
+#else
191
+#ifdef JUDYPREV
192
+FUNCTION PPvoid_t JudyLPrev
193
+#else
194
+FUNCTION PPvoid_t JudyLNext
195
+#endif
196
+#endif
197
+ (
198
+ Pcvoid_t PArray, // Judy array to search.
199
+ Word_t * PIndex, // starting point and result.
200
+ PJError_t PJError // optional, for returning error info.
201
+ )
202
+{
203
+ Pjp_t Pjp, Pjp2; // current JPs.
204
+ Pjbl_t Pjbl; // Pjp->jp_Addr masked and cast to types:
205
+ Pjbb_t Pjbb;
206
+ Pjbu_t Pjbu;
207
+
208
+// Note: The following initialization is not strictly required but it makes
209
+// gcc -Wall happy because there is an "impossible" path from Immed handling to
210
+// SM1LeafLImm code that looks like Pjll might be used before set:
211
+
212
+ Pjll_t Pjll = (Pjll_t) NULL;
213
+ Word_t state; // current state in SM.
214
+ Word_t digit; // next digit to decode from Index.
215
+
216
+// Note: The following initialization is not strictly required but it makes
217
+// gcc -Wall happy because there is an "impossible" path from Immed handling to
218
+// SM1LeafLImm code (for JudyL & JudyPrev only) that looks like pop1 might be
219
+// used before set:
220
+
221
+#if (defined(JUDYL) && defined(JUDYPREV))
222
+ Word_t pop1 = 0; // in a leaf.
223
+#else
224
+ Word_t pop1; // in a leaf.
225
+#endif
226
+ int offset; // linear branch/leaf, from j__udySearchLeaf*().
227
+ int subexp; // subexpanse in a bitmap branch.
228
+ Word_t bitposmask; // bit in bitmap for Index.
229
+
230
+// History for SM2Backtrack:
231
+//
232
+// For a given histnum, APjphist[histnum] is a parent JP that points to a
233
+// branch, and Aoffhist[histnum] is the offset of the NEXT JP in the branch to
234
+// which the parent JP points. The meaning of Aoffhist[histnum] depends on the
235
+// type of branch to which the parent JP points:
236
+//
237
+// Linear: Offset of the next JP in the JP list.
238
+//
239
+// Bitmap: Which subexpanse, plus the offset of the next JP in the
240
+// subexpanses JP list (to avoid bit-counting again), plus for Judy*Next(),
241
+// hidden one byte to the left, which digit, because Judy*Next() also needs
242
+// this.
243
+//
244
+// Uncompressed: Digit, which is actually the offset of the JP in the branch.
245
+//
246
+// Note: Only branch JPs are stored in APjphist[] because, as explained
247
+// earlier, SM1Get shortcuts sideways searches in leaves (and even in branches
248
+// in some cases), so SM2Backtrack only handles branches.
249
+
250
+#define HISTNUMMAX cJU_ROOTSTATE // maximum branches traversable.
251
+ Pjp_t APjphist[HISTNUMMAX]; // list of branch JPs traversed.
252
+ int Aoffhist[HISTNUMMAX]; // list of next JP offsets; see above.
253
+ int histnum = 0; // number of JPs now in list.
254
+
255
+
256
+// ----------------------------------------------------------------------------
257
+// M A C R O S
258
+//
259
+// These are intended to make the code a bit more readable and less redundant.
260
+
261
+
262
+// "PUSH" AND "POP" Pjp AND offset ON HISTORY STACKS:
263
+//
264
+// Note: Ensure a corrupt Judy array does not overflow *hist[]. Meanwhile,
265
+// underflowing *hist[] simply means theres no more room to backtrack =>
266
+// "no previous/next Index".
267
+
268
+#define HISTPUSH(Pjp,Offset) \
269
+ APjphist[histnum] = (Pjp); \
270
+ Aoffhist[histnum] = (Offset); \
271
+ \
272
+ if (++histnum >= HISTNUMMAX) \
273
+ { \
274
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT) \
275
+ JUDY1CODE(return(JERRI );) \
276
+ JUDYLCODE(return(PPJERR);) \
277
+ }
278
+
279
+#define HISTPOP(Pjp,Offset) \
280
+ if ((histnum--) < 1) JU_RET_NOTFOUND; \
281
+ (Pjp) = APjphist[histnum]; \
282
+ (Offset) = Aoffhist[histnum]
283
+
284
+// How to pack/unpack Aoffhist[] values for bitmap branches:
285
+
286
+#ifdef JUDYPREV
287
+
288
+#define HISTPUSHBOFF(Subexp,Offset,Digit) \
289
+ (((Subexp) * cJU_BITSPERSUBEXPB) | (Offset))
290
+
291
+#define HISTPOPBOFF(Subexp,Offset,Digit) \
292
+ (Subexp) = (Offset) / cJU_BITSPERSUBEXPB; \
293
+ (Offset) %= cJU_BITSPERSUBEXPB
294
+#else
295
+
296
+#define HISTPUSHBOFF(Subexp,Offset,Digit) \
297
+ (((Digit) << cJU_BITSPERBYTE) \
298
+ | ((Subexp) * cJU_BITSPERSUBEXPB) | (Offset))
299
+
300
+#define HISTPOPBOFF(Subexp,Offset,Digit) \
301
+ (Digit) = (Offset) >> cJU_BITSPERBYTE; \
302
+ (Subexp) = ((Offset) & JU_LEASTBYTESMASK(1)) / cJU_BITSPERSUBEXPB; \
303
+ (Offset) %= cJU_BITSPERSUBEXPB
304
+#endif
305
+
306
+
307
+// CHECK FOR NULL JP:
308
+
309
+#define JPNULL(Type) (((Type) >= cJU_JPNULL1) && ((Type) <= cJU_JPNULLMAX))
310
+
311
+
312
+// SEARCH A BITMAP:
313
+//
314
+// This is a weak analog of j__udySearchLeaf*() for bitmaps. Return the actual
315
+// or next-left position, base 0, of Digit in the single uint32_t bitmap, also
316
+// given a Bitposmask for Digit.
317
+//
318
+// Unlike j__udySearchLeaf*(), the offset is not returned bit-complemented if
319
+// Digits bit is unset, because the caller can check the bitmap themselves to
320
+// determine that. Also, if Digits bit is unset, the returned offset is to
321
+// the next-left JP (including -1), not to the "ideal" position for the Index =
322
+// next-right JP.
323
+//
324
+// Shortcut and skip calling j__udyCountBits*() if the bitmap is full, in which
325
+// case (Digit % cJU_BITSPERSUBEXP*) itself is the base-0 offset.
326
+//
327
+// TBD for Judy*Next(): Should this return next-right instead of next-left?
328
+// That is, +1 from current value? Maybe not, if Digits bit IS set, +1 would
329
+// be wrong.
330
+
331
+#define SEARCHBITMAPB(Bitmap,Digit,Bitposmask) \
332
+ (((Bitmap) == cJU_FULLBITMAPB) ? (Digit % cJU_BITSPERSUBEXPB) : \
333
+ j__udyCountBitsB((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1)
334
+
335
+#define SEARCHBITMAPL(Bitmap,Digit,Bitposmask) \
336
+ (((Bitmap) == cJU_FULLBITMAPL) ? (Digit % cJU_BITSPERSUBEXPL) : \
337
+ j__udyCountBitsL((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1)
338
+
339
+#ifdef JUDYPREV
340
+// Equivalent to search for the highest offset in Bitmap:
341
+
342
+#define SEARCHBITMAPMAXB(Bitmap) \
343
+ (((Bitmap) == cJU_FULLBITMAPB) ? cJU_BITSPERSUBEXPB - 1 : \
344
+ j__udyCountBitsB(Bitmap) - 1)
345
+
346
+#define SEARCHBITMAPMAXL(Bitmap) \
347
+ (((Bitmap) == cJU_FULLBITMAPL) ? cJU_BITSPERSUBEXPL - 1 : \
348
+ j__udyCountBitsL(Bitmap) - 1)
349
+#endif
350
+
351
+
352
+// CHECK DECODE BYTES:
353
+//
354
+// Check Decode bytes in a JP against the equivalent portion of *PIndex. If
355
+// *PIndex is lower (for Judy*Prev()) or higher (for Judy*Next()), this JP is a
356
+// dead end (the same as if it had been absent in a linear or bitmap branch or
357
+// null in an uncompressed branch), enter SM2Backtrack; otherwise enter
358
+// SM3Findlimit to find the highest/lowest Index under this JP, as if the code
359
+// had already backtracked to this JP.
360
+
361
+#ifdef JUDYPREV
362
+#define CDcmp__ <
363
+#else
364
+#define CDcmp__ >
365
+#endif
366
+
367
+#define CHECKDCD(cState) \
368
+ if (JU_DCDNOTMATCHINDEX(*PIndex, Pjp, cState)) \
369
+ { \
370
+ if ((*PIndex & cJU_DCDMASK(cState)) \
371
+ CDcmp__(JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(cState))) \
372
+ { \
373
+ goto SM2Backtrack; \
374
+ } \
375
+ goto SM3Findlimit; \
376
+ }
377
+
378
+
379
+// PREPARE TO HANDLE A LEAFW OR JRP BRANCH IN SM1:
380
+//
381
+// Extract a state-dependent digit from Index in a "constant" way, then jump to
382
+// common code for multiple cases.
383
+
384
+#define SM1PREPB(cState,Next) \
385
+ state = (cState); \
386
+ digit = JU_DIGITATSTATE(*PIndex, cState); \
387
+ goto Next
388
+
389
+
390
+// PREPARE TO HANDLE A LEAFW OR JRP BRANCH IN SM3:
391
+//
392
+// Optionally save Dcd bytes into *PIndex, then save state and jump to common
393
+// code for multiple cases.
394
+
395
+#define SM3PREPB_DCD(cState,Next) \
396
+ JU_SETDCD(*PIndex, Pjp, cState); \
397
+ SM3PREPB(cState,Next)
398
+
399
+#define SM3PREPB(cState,Next) state = (cState); goto Next
400
+
401
+
402
+// ----------------------------------------------------------------------------
403
+// CHECK FOR SHORTCUTS:
404
+//
405
+// Error out if PIndex is null. Execute JU_RET_NOTFOUND if the Judy array is
406
+// empty or *PIndex is already the minimum/maximum Index possible.
407
+//
408
+// Note: As documented, in case of failure *PIndex may be modified.
409
+
410
+ if (PIndex == (PWord_t) NULL)
411
+ {
412
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
413
+ JUDY1CODE(return(JERRI );)
414
+ JUDYLCODE(return(PPJERR);)
415
+ }
416
+
417
+#ifdef JUDYPREV
418
+ if ((PArray == (Pvoid_t) NULL) || ((*PIndex)-- == 0))
419
+#else
420
+ if ((PArray == (Pvoid_t) NULL) || ((*PIndex)++ == cJU_ALLONES))
421
+#endif
422
+ JU_RET_NOTFOUND;
423
+
424
+
425
+// HANDLE JRP:
426
+//
427
+// Before even entering SM1Get, check the JRP type. For JRP branches, traverse
428
+// the JPM; handle LEAFW leaves directly; but look for the most common cases
429
+// first.
430
+
431
+// ROOT-STATE LEAF that starts with a Pop0 word; just look within the leaf:
432
+//
433
+// If *PIndex is in the leaf, return it; otherwise return the Index, if any,
434
+// below where it would belong.
435
+
436
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
437
+ {
438
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
439
+ pop1 = Pjlw[0] + 1;
440
+
441
+ if ((offset = j__udySearchLeafW(Pjlw + 1, pop1, *PIndex))
442
+ >= 0) // Index is present.
443
+ {
444
+ assert(offset < pop1); // in expected range.
445
+ JU_RET_FOUND_LEAFW(Pjlw, pop1, offset); // *PIndex is set.
446
+ }
447
+
448
+#ifdef JUDYPREV
449
+ if ((offset = ~offset) == 0) // no next-left Index.
450
+#else
451
+ if ((offset = ~offset) >= pop1) // no next-right Index.
452
+#endif
453
+ JU_RET_NOTFOUND;
454
+
455
+ assert(offset <= pop1); // valid result.
456
+
457
+#ifdef JUDYPREV
458
+ *PIndex = Pjlw[offset--]; // next-left Index, base 1.
459
+#else
460
+ *PIndex = Pjlw[offset + 1]; // next-right Index, base 1.
461
+#endif
462
+ JU_RET_FOUND_LEAFW(Pjlw, pop1, offset); // base 0.
463
+
464
+ }
465
+ else // JRP BRANCH
466
+ {
467
+ Pjpm_t Pjpm = P_JPM(PArray);
468
+ Pjp = &(Pjpm->jpm_JP);
469
+
470
+// goto SM1Get;
471
+ }
472
+
473
+// ============================================================================
474
+// STATE MACHINE 1 -- GET INDEX:
475
+//
476
+// Search for *PIndex (already decremented/incremented so as to be inclusive).
477
+// If found, return it. Otherwise in theory hand off to SM2Backtrack or
478
+// SM3Findlimit, but in practice "shortcut" by first sideways searching the
479
+// current branch or leaf upon hitting a dead end. During sideways search,
480
+// modify *PIndex to a new path taken.
481
+//
482
+// ENTRY: Pjp points to next JP to interpret, whose Decode bytes have not yet
483
+// been checked. This JP is not yet listed in history.
484
+//
485
+// Note: Check Decode bytes at the start of each loop, not after looking up a
486
+// new JP, so its easy to do constant shifts/masks, although this requires
487
+// cautious handling of Pjp, offset, and *hist[] for correct entry to
488
+// SM2Backtrack.
489
+//
490
+// EXIT: Return, or branch to SM2Backtrack or SM3Findlimit with correct
491
+// interface, as described elsewhere.
492
+//
493
+// WARNING: For run-time efficiency the following cases replicate code with
494
+// varying constants, rather than using common code with variable values!
495
+
496
+SM1Get: // return here for next branch/leaf.
497
+
498
+ switch (JU_JPTYPE(Pjp))
499
+ {
500
+
501
+
502
+// ----------------------------------------------------------------------------
503
+// LINEAR BRANCH:
504
+//
505
+// Check Decode bytes, if any, in the current JP, then search for a JP for the
506
+// next digit in *PIndex.
507
+
508
+ case cJU_JPBRANCH_L2: CHECKDCD(2); SM1PREPB(2, SM1BranchL);
509
+ case cJU_JPBRANCH_L3: CHECKDCD(3); SM1PREPB(3, SM1BranchL);
510
+#ifdef JU_64BIT
511
+ case cJU_JPBRANCH_L4: CHECKDCD(4); SM1PREPB(4, SM1BranchL);
512
+ case cJU_JPBRANCH_L5: CHECKDCD(5); SM1PREPB(5, SM1BranchL);
513
+ case cJU_JPBRANCH_L6: CHECKDCD(6); SM1PREPB(6, SM1BranchL);
514
+ case cJU_JPBRANCH_L7: CHECKDCD(7); SM1PREPB(7, SM1BranchL);
515
+#endif
516
+ case cJU_JPBRANCH_L: SM1PREPB(cJU_ROOTSTATE, SM1BranchL);
517
+
518
+// Common code (state-independent) for all cases of linear branches:
519
+
520
+SM1BranchL:
521
+ Pjbl = P_JBL(Pjp->jp_Addr);
522
+
523
+// Found JP matching current digit in *PIndex; record parent JP and the next
524
+// JPs offset, and iterate to the next JP:
525
+
526
+ if ((offset = j__udySearchLeaf1((Pjll_t) (Pjbl->jbl_Expanse),
527
+ Pjbl->jbl_NumJPs, digit)) >= 0)
528
+ {
529
+ HISTPUSH(Pjp, offset);
530
+ Pjp = (Pjbl->jbl_jp) + offset;
531
+ goto SM1Get;
532
+ }
533
+
534
+// Dead end, no JP in BranchL for next digit in *PIndex:
535
+//
536
+// Get the ideal location of digits JP, and if theres no next-left/right JP
537
+// in the BranchL, shortcut and start backtracking one level up; ignore the
538
+// current Pjp because it points to a BranchL with no next-left/right JP.
539
+
540
+#ifdef JUDYPREV
541
+ if ((offset = (~offset) - 1) < 0) // no next-left JP in BranchL.
542
+#else
543
+ if ((offset = (~offset)) >= Pjbl->jbl_NumJPs) // no next-right.
544
+#endif
545
+ goto SM2Backtrack;
546
+
547
+// Theres a next-left/right JP in the current BranchL; save its digit in
548
+// *PIndex and shortcut to SM3Findlimit:
549
+
550
+ JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state);
551
+ Pjp = (Pjbl->jbl_jp) + offset;
552
+ goto SM3Findlimit;
553
+
554
+
555
+// ----------------------------------------------------------------------------
556
+// BITMAP BRANCH:
557
+//
558
+// Check Decode bytes, if any, in the current JP, then look for a JP for the
559
+// next digit in *PIndex.
560
+
561
+ case cJU_JPBRANCH_B2: CHECKDCD(2); SM1PREPB(2, SM1BranchB);
562
+ case cJU_JPBRANCH_B3: CHECKDCD(3); SM1PREPB(3, SM1BranchB);
563
+#ifdef JU_64BIT
564
+ case cJU_JPBRANCH_B4: CHECKDCD(4); SM1PREPB(4, SM1BranchB);
565
+ case cJU_JPBRANCH_B5: CHECKDCD(5); SM1PREPB(5, SM1BranchB);
566
+ case cJU_JPBRANCH_B6: CHECKDCD(6); SM1PREPB(6, SM1BranchB);
567
+ case cJU_JPBRANCH_B7: CHECKDCD(7); SM1PREPB(7, SM1BranchB);
568
+#endif
569
+ case cJU_JPBRANCH_B: SM1PREPB(cJU_ROOTSTATE, SM1BranchB);
570
+
571
+// Common code (state-independent) for all cases of bitmap branches:
572
+
573
+SM1BranchB:
574
+ Pjbb = P_JBB(Pjp->jp_Addr);
575
+
576
+// Locate the digits JP in the subexpanse list, if present, otherwise the
577
+// offset of the next-left JP, if any:
578
+
579
+ subexp = digit / cJU_BITSPERSUBEXPB;
580
+ assert(subexp < cJU_NUMSUBEXPB); // falls in expected range.
581
+ bitposmask = JU_BITPOSMASKB(digit);
582
+ offset = SEARCHBITMAPB(JU_JBB_BITMAP(Pjbb, subexp), digit,
583
+ bitposmask);
584
+ // right range:
585
+ assert((offset >= -1) && (offset < (int) cJU_BITSPERSUBEXPB));
586
+
587
+// Found JP matching current digit in *PIndex:
588
+//
589
+// Record the parent JP and the next JPs offset; and iterate to the next JP.
590
+
591
+// if (JU_BITMAPTESTB(Pjbb, digit)) // slower.
592
+ if (JU_JBB_BITMAP(Pjbb, subexp) & bitposmask) // faster.
593
+ {
594
+ // not negative since at least one bit is set:
595
+ assert(offset >= 0);
596
+
597
+ HISTPUSH(Pjp, HISTPUSHBOFF(subexp, offset, digit));
598
+
599
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL)
600
+ {
601
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
602
+ JUDY1CODE(return(JERRI );)
603
+ JUDYLCODE(return(PPJERR);)
604
+ }
605
+
606
+ Pjp += offset;
607
+ goto SM1Get; // iterate to next JP.
608
+ }
609
+
610
+// Dead end, no JP in BranchB for next digit in *PIndex:
611
+//
612
+// If theres a next-left/right JP in the current BranchB, shortcut to
613
+// SM3Findlimit. Note: offset is already set to the correct value for the
614
+// next-left/right JP.
615
+
616
+#ifdef JUDYPREV
617
+ if (offset >= 0) // next-left JP is in this subexpanse.
618
+ goto SM1BranchBFindlimit;
619
+
620
+ while (--subexp >= 0) // search next-left subexpanses.
621
+#else
622
+ if (JU_JBB_BITMAP(Pjbb, subexp) & JU_MASKHIGHEREXC(bitposmask))
623
+ {
624
+ ++offset; // next-left => next-right.
625
+ goto SM1BranchBFindlimit;
626
+ }
627
+
628
+ while (++subexp < cJU_NUMSUBEXPB) // search next-right subexps.
629
+#endif
630
+ {
631
+ if (! JU_JBB_PJP(Pjbb, subexp)) continue; // empty subexpanse.
632
+
633
+#ifdef JUDYPREV
634
+ offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp));
635
+ // expected range:
636
+ assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB));
637
+#else
638
+ offset = 0;
639
+#endif
640
+
641
+// Save the next-left/right JPs digit in *PIndex:
642
+
643
+SM1BranchBFindlimit:
644
+ JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp),
645
+ offset);
646
+ JU_SETDIGIT(*PIndex, digit, state);
647
+
648
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL)
649
+ {
650
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
651
+ JUDY1CODE(return(JERRI );)
652
+ JUDYLCODE(return(PPJERR);)
653
+ }
654
+
655
+ Pjp += offset;
656
+ goto SM3Findlimit;
657
+ }
658
+
659
+// Theres no next-left/right JP in the BranchB:
660
+//
661
+// Shortcut and start backtracking one level up; ignore the current Pjp because
662
+// it points to a BranchB with no next-left/right JP.
663
+
664
+ goto SM2Backtrack;
665
+
666
+
667
+// ----------------------------------------------------------------------------
668
+// UNCOMPRESSED BRANCH:
669
+//
670
+// Check Decode bytes, if any, in the current JP, then look for a JP for the
671
+// next digit in *PIndex.
672
+
673
+ case cJU_JPBRANCH_U2: CHECKDCD(2); SM1PREPB(2, SM1BranchU);
674
+ case cJU_JPBRANCH_U3: CHECKDCD(3); SM1PREPB(3, SM1BranchU);
675
+#ifdef JU_64BIT
676
+ case cJU_JPBRANCH_U4: CHECKDCD(4); SM1PREPB(4, SM1BranchU);
677
+ case cJU_JPBRANCH_U5: CHECKDCD(5); SM1PREPB(5, SM1BranchU);
678
+ case cJU_JPBRANCH_U6: CHECKDCD(6); SM1PREPB(6, SM1BranchU);
679
+ case cJU_JPBRANCH_U7: CHECKDCD(7); SM1PREPB(7, SM1BranchU);
680
+#endif
681
+ case cJU_JPBRANCH_U: SM1PREPB(cJU_ROOTSTATE, SM1BranchU);
682
+
683
+// Common code (state-independent) for all cases of uncompressed branches:
684
+
685
+SM1BranchU:
686
+ Pjbu = P_JBU(Pjp->jp_Addr);
687
+ Pjp2 = (Pjbu->jbu_jp) + digit;
688
+
689
+// Found JP matching current digit in *PIndex:
690
+//
691
+// Record the parent JP and the next JPs digit, and iterate to the next JP.
692
+//
693
+// TBD: Instead of this, just goto SM1Get, and add cJU_JPNULL* cases to the
694
+// SM1Get state machine? Then backtrack? However, it means you cant detect
695
+// an inappropriate cJU_JPNULL*, when it occurs in other than a BranchU, and
696
+// return JU_RET_CORRUPT.
697
+
698
+ if (! JPNULL(JU_JPTYPE(Pjp2))) // digit has a JP.
699
+ {
700
+ HISTPUSH(Pjp, digit);
701
+ Pjp = Pjp2;
702
+ goto SM1Get;
703
+ }
704
+
705
+// Dead end, no JP in BranchU for next digit in *PIndex:
706
+//
707
+// Search for a next-left/right JP in the current BranchU, and if one is found,
708
+// save its digit in *PIndex and shortcut to SM3Findlimit:
709
+
710
+#ifdef JUDYPREV
711
+ while (digit >= 1)
712
+ {
713
+ Pjp = (Pjbu->jbu_jp) + (--digit);
714
+#else
715
+ while (digit < cJU_BRANCHUNUMJPS - 1)
716
+ {
717
+ Pjp = (Pjbu->jbu_jp) + (++digit);
718
+#endif
719
+ if (JPNULL(JU_JPTYPE(Pjp))) continue;
720
+
721
+ JU_SETDIGIT(*PIndex, digit, state);
722
+ goto SM3Findlimit;
723
+ }
724
+
725
+// Theres no next-left/right JP in the BranchU:
726
+//
727
+// Shortcut and start backtracking one level up; ignore the current Pjp because
728
+// it points to a BranchU with no next-left/right JP.
729
+
730
+ goto SM2Backtrack;
731
+
732
+
733
+// ----------------------------------------------------------------------------
734
+// LINEAR LEAF:
735
+//
736
+// Check Decode bytes, if any, in the current JP, then search the leaf for
737
+// *PIndex.
738
+
739
+#define SM1LEAFL(Func) \
740
+ Pjll = P_JLL(Pjp->jp_Addr); \
741
+ pop1 = JU_JPLEAF_POP0(Pjp) + 1; \
742
+ offset = Func(Pjll, pop1, *PIndex); \
743
+ goto SM1LeafLImm
744
+
745
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
746
+ case cJU_JPLEAF1: CHECKDCD(1); SM1LEAFL(j__udySearchLeaf1);
747
+#endif
748
+ case cJU_JPLEAF2: CHECKDCD(2); SM1LEAFL(j__udySearchLeaf2);
749
+ case cJU_JPLEAF3: CHECKDCD(3); SM1LEAFL(j__udySearchLeaf3);
750
+
751
+#ifdef JU_64BIT
752
+ case cJU_JPLEAF4: CHECKDCD(4); SM1LEAFL(j__udySearchLeaf4);
753
+ case cJU_JPLEAF5: CHECKDCD(5); SM1LEAFL(j__udySearchLeaf5);
754
+ case cJU_JPLEAF6: CHECKDCD(6); SM1LEAFL(j__udySearchLeaf6);
755
+ case cJU_JPLEAF7: CHECKDCD(7); SM1LEAFL(j__udySearchLeaf7);
756
+#endif
757
+
758
+// Common code (state-independent) for all cases of linear leaves and
759
+// immediates:
760
+
761
+SM1LeafLImm:
762
+ if (offset >= 0) // *PIndex is in LeafL / Immed.
763
+#ifdef JUDY1
764
+ JU_RET_FOUND;
765
+#else
766
+ { // JudyL is trickier...
767
+ switch (JU_JPTYPE(Pjp))
768
+ {
769
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
770
+ case cJU_JPLEAF1: JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
771
+#endif
772
+ case cJU_JPLEAF2: JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
773
+ case cJU_JPLEAF3: JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
774
+#ifdef JU_64BIT
775
+ case cJU_JPLEAF4: JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
776
+ case cJU_JPLEAF5: JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
777
+ case cJU_JPLEAF6: JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
778
+ case cJU_JPLEAF7: JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
779
+#endif
780
+
781
+ case cJU_JPIMMED_1_01:
782
+ case cJU_JPIMMED_2_01:
783
+ case cJU_JPIMMED_3_01:
784
+#ifdef JU_64BIT
785
+ case cJU_JPIMMED_4_01:
786
+ case cJU_JPIMMED_5_01:
787
+ case cJU_JPIMMED_6_01:
788
+ case cJU_JPIMMED_7_01:
789
+#endif
790
+ JU_RET_FOUND_IMM_01(Pjp);
791
+
792
+ case cJU_JPIMMED_1_02:
793
+ case cJU_JPIMMED_1_03:
794
+#ifdef JU_64BIT
795
+ case cJU_JPIMMED_1_04:
796
+ case cJU_JPIMMED_1_05:
797
+ case cJU_JPIMMED_1_06:
798
+ case cJU_JPIMMED_1_07:
799
+ case cJU_JPIMMED_2_02:
800
+ case cJU_JPIMMED_2_03:
801
+ case cJU_JPIMMED_3_02:
802
+#endif
803
+ JU_RET_FOUND_IMM(Pjp, offset);
804
+ }
805
+
806
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // impossible?
807
+ JUDY1CODE(return(JERRI );)
808
+ JUDYLCODE(return(PPJERR);)
809
+
810
+ } // found *PIndex
811
+
812
+#endif // JUDYL
813
+
814
+// Dead end, no Index in LeafL / Immed for remaining digit(s) in *PIndex:
815
+//
816
+// Get the ideal location of Index, and if theres no next-left/right Index in
817
+// the LeafL / Immed, shortcut and start backtracking one level up; ignore the
818
+// current Pjp because it points to a LeafL / Immed with no next-left/right
819
+// Index.
820
+
821
+#ifdef JUDYPREV
822
+ if ((offset = (~offset) - 1) < 0) // no next-left Index.
823
+#else
824
+ if ((offset = (~offset)) >= pop1) // no next-right Index.
825
+#endif
826
+ goto SM2Backtrack;
827
+
828
+// Theres a next-left/right Index in the current LeafL / Immed; shortcut by
829
+// copying its digit(s) to *PIndex and returning it.
830
+//
831
+// Unfortunately this is pretty hairy, especially avoiding endian issues.
832
+//
833
+// The cJU_JPLEAF* cases are very similar to same-index-size cJU_JPIMMED* cases
834
+// for *_02 and above, but must return differently, at least for JudyL, so
835
+// spell them out separately here at the cost of a little redundant code for
836
+// Judy1.
837
+
838
+ switch (JU_JPTYPE(Pjp))
839
+ {
840
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
841
+ case cJU_JPLEAF1:
842
+
843
+ JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
844
+ JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
845
+#endif
846
+
847
+ case cJU_JPLEAF2:
848
+
849
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
850
+ | ((uint16_t *) Pjll)[offset];
851
+ JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
852
+
853
+ case cJU_JPLEAF3:
854
+ {
855
+ Word_t lsb;
856
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
857
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
858
+ JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
859
+ }
860
+
861
+#ifdef JU_64BIT
862
+ case cJU_JPLEAF4:
863
+
864
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
865
+ | ((uint32_t *) Pjll)[offset];
866
+ JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
867
+
868
+ case cJU_JPLEAF5:
869
+ {
870
+ Word_t lsb;
871
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
872
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
873
+ JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
874
+ }
875
+
876
+ case cJU_JPLEAF6:
877
+ {
878
+ Word_t lsb;
879
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
880
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
881
+ JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
882
+ }
883
+
884
+ case cJU_JPLEAF7:
885
+ {
886
+ Word_t lsb;
887
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
888
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
889
+ JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
890
+ }
891
+
892
+#endif // JU_64BIT
893
+
894
+#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState)
895
+
896
+ case cJU_JPIMMED_1_01: SET_01(1); goto SM1Imm_01;
897
+ case cJU_JPIMMED_2_01: SET_01(2); goto SM1Imm_01;
898
+ case cJU_JPIMMED_3_01: SET_01(3); goto SM1Imm_01;
899
+#ifdef JU_64BIT
900
+ case cJU_JPIMMED_4_01: SET_01(4); goto SM1Imm_01;
901
+ case cJU_JPIMMED_5_01: SET_01(5); goto SM1Imm_01;
902
+ case cJU_JPIMMED_6_01: SET_01(6); goto SM1Imm_01;
903
+ case cJU_JPIMMED_7_01: SET_01(7); goto SM1Imm_01;
904
+#endif
905
+SM1Imm_01: JU_RET_FOUND_IMM_01(Pjp);
906
+
907
+// Shorthand for where to find start of Index bytes array:
908
+
909
+#ifdef JUDY1
910
+#define PJI (Pjp->jp_1Index)
911
+#else
912
+#define PJI (Pjp->jp_LIndex)
913
+#endif
914
+
915
+ case cJU_JPIMMED_1_02:
916
+ case cJU_JPIMMED_1_03:
917
+#if (defined(JUDY1) || defined(JU_64BIT))
918
+ case cJU_JPIMMED_1_04:
919
+ case cJU_JPIMMED_1_05:
920
+ case cJU_JPIMMED_1_06:
921
+ case cJU_JPIMMED_1_07:
922
+#endif
923
+#if (defined(JUDY1) && defined(JU_64BIT))
924
+ case cJ1_JPIMMED_1_08:
925
+ case cJ1_JPIMMED_1_09:
926
+ case cJ1_JPIMMED_1_10:
927
+ case cJ1_JPIMMED_1_11:
928
+ case cJ1_JPIMMED_1_12:
929
+ case cJ1_JPIMMED_1_13:
930
+ case cJ1_JPIMMED_1_14:
931
+ case cJ1_JPIMMED_1_15:
932
+#endif
933
+ JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
934
+ JU_RET_FOUND_IMM(Pjp, offset);
935
+
936
+#if (defined(JUDY1) || defined(JU_64BIT))
937
+ case cJU_JPIMMED_2_02:
938
+ case cJU_JPIMMED_2_03:
939
+#endif
940
+#if (defined(JUDY1) && defined(JU_64BIT))
941
+ case cJ1_JPIMMED_2_04:
942
+ case cJ1_JPIMMED_2_05:
943
+ case cJ1_JPIMMED_2_06:
944
+ case cJ1_JPIMMED_2_07:
945
+#endif
946
+#if (defined(JUDY1) || defined(JU_64BIT))
947
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
948
+ | ((uint16_t *) PJI)[offset];
949
+ JU_RET_FOUND_IMM(Pjp, offset);
950
+#endif
951
+
952
+#if (defined(JUDY1) || defined(JU_64BIT))
953
+ case cJU_JPIMMED_3_02:
954
+#endif
955
+#if (defined(JUDY1) && defined(JU_64BIT))
956
+ case cJ1_JPIMMED_3_03:
957
+ case cJ1_JPIMMED_3_04:
958
+ case cJ1_JPIMMED_3_05:
959
+#endif
960
+#if (defined(JUDY1) || defined(JU_64BIT))
961
+ {
962
+ Word_t lsb;
963
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
964
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
965
+ JU_RET_FOUND_IMM(Pjp, offset);
966
+ }
967
+#endif
968
+
969
+#if (defined(JUDY1) && defined(JU_64BIT))
970
+ case cJ1_JPIMMED_4_02:
971
+ case cJ1_JPIMMED_4_03:
972
+
973
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
974
+ | ((uint32_t *) PJI)[offset];
975
+ JU_RET_FOUND_IMM(Pjp, offset);
976
+
977
+ case cJ1_JPIMMED_5_02:
978
+ case cJ1_JPIMMED_5_03:
979
+ {
980
+ Word_t lsb;
981
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
982
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
983
+ JU_RET_FOUND_IMM(Pjp, offset);
984
+ }
985
+
986
+ case cJ1_JPIMMED_6_02:
987
+ {
988
+ Word_t lsb;
989
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
990
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
991
+ JU_RET_FOUND_IMM(Pjp, offset);
992
+ }
993
+
994
+ case cJ1_JPIMMED_7_02:
995
+ {
996
+ Word_t lsb;
997
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
998
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
999
+ JU_RET_FOUND_IMM(Pjp, offset);
1000
+ }
1001
+
1002
+#endif // (JUDY1 && JU_64BIT)
1003
+
1004
+ } // switch for not-found *PIndex
1005
+
1006
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // impossible?
1007
+ JUDY1CODE(return(JERRI );)
1008
+ JUDYLCODE(return(PPJERR);)
1009
+
1010
+
1011
+// ----------------------------------------------------------------------------
1012
+// BITMAP LEAF:
1013
+//
1014
+// Check Decode bytes, if any, in the current JP, then look in the leaf for
1015
+// *PIndex.
1016
+
1017
+ case cJU_JPLEAF_B1:
1018
+ {
1019
+ Pjlb_t Pjlb;
1020
+ CHECKDCD(1);
1021
+
1022
+ Pjlb = P_JLB(Pjp->jp_Addr);
1023
+ digit = JU_DIGITATSTATE(*PIndex, 1);
1024
+ subexp = JU_SUBEXPL(digit);
1025
+ bitposmask = JU_BITPOSMASKL(digit);
1026
+ assert(subexp < cJU_NUMSUBEXPL); // falls in expected range.
1027
+
1028
+// *PIndex exists in LeafB1:
1029
+
1030
+// if (JU_BITMAPTESTL(Pjlb, digit)) // slower.
1031
+ if (JU_JLB_BITMAP(Pjlb, subexp) & bitposmask) // faster.
1032
+ {
1033
+#ifdef JUDYL // needs offset at this point:
1034
+ offset = SEARCHBITMAPL(JU_JLB_BITMAP(Pjlb, subexp), digit, bitposmask);
1035
+#endif
1036
+ JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
1037
+// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset)));
1038
+ }
1039
+
1040
+// Dead end, no Index in LeafB1 for remaining digit in *PIndex:
1041
+//
1042
+// If theres a next-left/right Index in the current LeafB1, which for
1043
+// Judy*Next() is true if any bits are set for higher Indexes, shortcut by
1044
+// returning it. Note: For Judy*Prev(), offset is set here to the correct
1045
+// value for the next-left JP.
1046
+
1047
+ offset = SEARCHBITMAPL(JU_JLB_BITMAP(Pjlb, subexp), digit,
1048
+ bitposmask);
1049
+ // right range:
1050
+ assert((offset >= -1) && (offset < (int) cJU_BITSPERSUBEXPL));
1051
+
1052
+#ifdef JUDYPREV
1053
+ if (offset >= 0) // next-left JP is in this subexpanse.
1054
+ goto SM1LeafB1Findlimit;
1055
+
1056
+ while (--subexp >= 0) // search next-left subexpanses.
1057
+#else
1058
+ if (JU_JLB_BITMAP(Pjlb, subexp) & JU_MASKHIGHEREXC(bitposmask))
1059
+ {
1060
+ ++offset; // next-left => next-right.
1061
+ goto SM1LeafB1Findlimit;
1062
+ }
1063
+
1064
+ while (++subexp < cJU_NUMSUBEXPL) // search next-right subexps.
1065
+#endif
1066
+ {
1067
+ if (! JU_JLB_BITMAP(Pjlb, subexp)) continue; // empty subexp.
1068
+
1069
+#ifdef JUDYPREV
1070
+ offset = SEARCHBITMAPMAXL(JU_JLB_BITMAP(Pjlb, subexp));
1071
+ // expected range:
1072
+ assert((offset >= 0) && (offset < (int) cJU_BITSPERSUBEXPL));
1073
+#else
1074
+ offset = 0;
1075
+#endif
1076
+
1077
+// Save the next-left/right Indexess digit in *PIndex:
1078
+
1079
+SM1LeafB1Findlimit:
1080
+ JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
1081
+ JU_SETDIGIT1(*PIndex, digit);
1082
+ JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
1083
+// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset)));
1084
+ }
1085
+
1086
+// Theres no next-left/right Index in the LeafB1:
1087
+//
1088
+// Shortcut and start backtracking one level up; ignore the current Pjp because
1089
+// it points to a LeafB1 with no next-left/right Index.
1090
+
1091
+ goto SM2Backtrack;
1092
+
1093
+ } // case cJU_JPLEAF_B1
1094
+
1095
+#ifdef JUDY1
1096
+// ----------------------------------------------------------------------------
1097
+// FULL POPULATION:
1098
+//
1099
+// If the Decode bytes match, *PIndex is found (without modification).
1100
+
1101
+ case cJ1_JPFULLPOPU1:
1102
+
1103
+ CHECKDCD(1);
1104
+ JU_RET_FOUND_FULLPOPU1;
1105
+#endif
1106
+
1107
+
1108
+// ----------------------------------------------------------------------------
1109
+// IMMEDIATE:
1110
+
1111
+#ifdef JUDYPREV
1112
+#define SM1IMM_SETPOP1(cPop1)
1113
+#else
1114
+#define SM1IMM_SETPOP1(cPop1) pop1 = (cPop1)
1115
+#endif
1116
+
1117
+#define SM1IMM(Func,cPop1) \
1118
+ SM1IMM_SETPOP1(cPop1); \
1119
+ offset = Func((Pjll_t) (PJI), cPop1, *PIndex); \
1120
+ goto SM1LeafLImm
1121
+
1122
+// Special case for Pop1 = 1 Immediate JPs:
1123
+//
1124
+// If *PIndex is in the immediate, offset is 0, otherwise the binary NOT of the
1125
+// offset where it belongs, 0 or 1, same as from the search functions.
1126
+
1127
+#ifdef JUDYPREV
1128
+#define SM1IMM_01_SETPOP1
1129
+#else
1130
+#define SM1IMM_01_SETPOP1 pop1 = 1
1131
+#endif
1132
+
1133
+#define SM1IMM_01 \
1134
+ SM1IMM_01_SETPOP1; \
1135
+ offset = ((JU_JPDCDPOP0(Pjp) < JU_TRIMTODCDSIZE(*PIndex)) ? ~1 : \
1136
+ (JU_JPDCDPOP0(Pjp) == JU_TRIMTODCDSIZE(*PIndex)) ? 0 : \
1137
+ ~0); \
1138
+ goto SM1LeafLImm
1139
+
1140
+ case cJU_JPIMMED_1_01:
1141
+ case cJU_JPIMMED_2_01:
1142
+ case cJU_JPIMMED_3_01:
1143
+#ifdef JU_64BIT
1144
+ case cJU_JPIMMED_4_01:
1145
+ case cJU_JPIMMED_5_01:
1146
+ case cJU_JPIMMED_6_01:
1147
+ case cJU_JPIMMED_7_01:
1148
+#endif
1149
+ SM1IMM_01;
1150
+
1151
+// TBD: Doug says it would be OK to have fewer calls and calculate arg 2, here
1152
+// and in Judy*Count() also.
1153
+
1154
+ case cJU_JPIMMED_1_02: SM1IMM(j__udySearchLeaf1, 2);
1155
+ case cJU_JPIMMED_1_03: SM1IMM(j__udySearchLeaf1, 3);
1156
+#if (defined(JUDY1) || defined(JU_64BIT))
1157
+ case cJU_JPIMMED_1_04: SM1IMM(j__udySearchLeaf1, 4);
1158
+ case cJU_JPIMMED_1_05: SM1IMM(j__udySearchLeaf1, 5);
1159
+ case cJU_JPIMMED_1_06: SM1IMM(j__udySearchLeaf1, 6);
1160
+ case cJU_JPIMMED_1_07: SM1IMM(j__udySearchLeaf1, 7);
1161
+#endif
1162
+#if (defined(JUDY1) && defined(JU_64BIT))
1163
+ case cJ1_JPIMMED_1_08: SM1IMM(j__udySearchLeaf1, 8);
1164
+ case cJ1_JPIMMED_1_09: SM1IMM(j__udySearchLeaf1, 9);
1165
+ case cJ1_JPIMMED_1_10: SM1IMM(j__udySearchLeaf1, 10);
1166
+ case cJ1_JPIMMED_1_11: SM1IMM(j__udySearchLeaf1, 11);
1167
+ case cJ1_JPIMMED_1_12: SM1IMM(j__udySearchLeaf1, 12);
1168
+ case cJ1_JPIMMED_1_13: SM1IMM(j__udySearchLeaf1, 13);
1169
+ case cJ1_JPIMMED_1_14: SM1IMM(j__udySearchLeaf1, 14);
1170
+ case cJ1_JPIMMED_1_15: SM1IMM(j__udySearchLeaf1, 15);
1171
+#endif
1172
+
1173
+#if (defined(JUDY1) || defined(JU_64BIT))
1174
+ case cJU_JPIMMED_2_02: SM1IMM(j__udySearchLeaf2, 2);
1175
+ case cJU_JPIMMED_2_03: SM1IMM(j__udySearchLeaf2, 3);
1176
+#endif
1177
+#if (defined(JUDY1) && defined(JU_64BIT))
1178
+ case cJ1_JPIMMED_2_04: SM1IMM(j__udySearchLeaf2, 4);
1179
+ case cJ1_JPIMMED_2_05: SM1IMM(j__udySearchLeaf2, 5);
1180
+ case cJ1_JPIMMED_2_06: SM1IMM(j__udySearchLeaf2, 6);
1181
+ case cJ1_JPIMMED_2_07: SM1IMM(j__udySearchLeaf2, 7);
1182
+#endif
1183
+
1184
+#if (defined(JUDY1) || defined(JU_64BIT))
1185
+ case cJU_JPIMMED_3_02: SM1IMM(j__udySearchLeaf3, 2);
1186
+#endif
1187
+#if (defined(JUDY1) && defined(JU_64BIT))
1188
+ case cJ1_JPIMMED_3_03: SM1IMM(j__udySearchLeaf3, 3);
1189
+ case cJ1_JPIMMED_3_04: SM1IMM(j__udySearchLeaf3, 4);
1190
+ case cJ1_JPIMMED_3_05: SM1IMM(j__udySearchLeaf3, 5);
1191
+
1192
+ case cJ1_JPIMMED_4_02: SM1IMM(j__udySearchLeaf4, 2);
1193
+ case cJ1_JPIMMED_4_03: SM1IMM(j__udySearchLeaf4, 3);
1194
+
1195
+ case cJ1_JPIMMED_5_02: SM1IMM(j__udySearchLeaf5, 2);
1196
+ case cJ1_JPIMMED_5_03: SM1IMM(j__udySearchLeaf5, 3);
1197
+
1198
+ case cJ1_JPIMMED_6_02: SM1IMM(j__udySearchLeaf6, 2);
1199
+
1200
+ case cJ1_JPIMMED_7_02: SM1IMM(j__udySearchLeaf7, 2);
1201
+#endif
1202
+
1203
+
1204
+// ----------------------------------------------------------------------------
1205
+// INVALID JP TYPE:
1206
+
1207
+ default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1208
+ JUDY1CODE(return(JERRI );)
1209
+ JUDYLCODE(return(PPJERR);)
1210
+
1211
+ } // SM1Get switch.
1212
+
1213
+ /*NOTREACHED*/
1214
+
1215
+
1216
+// ============================================================================
1217
+// STATE MACHINE 2 -- BACKTRACK BRANCH TO PREVIOUS JP:
1218
+//
1219
+// Look for the next-left/right JP in a branch, backing up the history list as
1220
+// necessary. Upon finding a next-left/right JP, modify the corresponding
1221
+// digit in *PIndex before passing control to SM3Findlimit.
1222
+//
1223
+// Note: As described earlier, only branch JPs are expected here; other types
1224
+// fall into the default case.
1225
+//
1226
+// Note: If a found JP contains needed Dcd bytes, thats OK, theyre copied to
1227
+// *PIndex in SM3Findlimit.
1228
+//
1229
+// TBD: This code has a lot in common with similar code in the shortcut cases
1230
+// in SM1Get. Can combine this code somehow?
1231
+//
1232
+// ENTRY: List, possibly empty, of JPs and offsets in APjphist[] and
1233
+// Aoffhist[]; see earlier comments.
1234
+//
1235
+// EXIT: Execute JU_RET_NOTFOUND if no previous/next JP; otherwise jump to
1236
+// SM3Findlimit to resume a new but different downward search.
1237
+
1238
+SM2Backtrack: // come or return here for first/next sideways search.
1239
+
1240
+ HISTPOP(Pjp, offset);
1241
+
1242
+ switch (JU_JPTYPE(Pjp))
1243
+ {
1244
+
1245
+
1246
+// ----------------------------------------------------------------------------
1247
+// LINEAR BRANCH:
1248
+
1249
+ case cJU_JPBRANCH_L2: state = 2; goto SM2BranchL;
1250
+ case cJU_JPBRANCH_L3: state = 3; goto SM2BranchL;
1251
+#ifdef JU_64BIT
1252
+ case cJU_JPBRANCH_L4: state = 4; goto SM2BranchL;
1253
+ case cJU_JPBRANCH_L5: state = 5; goto SM2BranchL;
1254
+ case cJU_JPBRANCH_L6: state = 6; goto SM2BranchL;
1255
+ case cJU_JPBRANCH_L7: state = 7; goto SM2BranchL;
1256
+#endif
1257
+ case cJU_JPBRANCH_L: state = cJU_ROOTSTATE; goto SM2BranchL;
1258
+
1259
+SM2BranchL:
1260
+#ifdef JUDYPREV
1261
+ if (--offset < 0) goto SM2Backtrack; // no next-left JP in BranchL.
1262
+#endif
1263
+ Pjbl = P_JBL(Pjp->jp_Addr);
1264
+#ifdef JUDYNEXT
1265
+ if (++offset >= (Pjbl->jbl_NumJPs)) goto SM2Backtrack;
1266
+ // no next-right JP in BranchL.
1267
+#endif
1268
+
1269
+// Theres a next-left/right JP in the current BranchL; save its digit in
1270
+// *PIndex and continue with SM3Findlimit:
1271
+
1272
+ JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state);
1273
+ Pjp = (Pjbl->jbl_jp) + offset;
1274
+ goto SM3Findlimit;
1275
+
1276
+
1277
+// ----------------------------------------------------------------------------
1278
+// BITMAP BRANCH:
1279
+
1280
+ case cJU_JPBRANCH_B2: state = 2; goto SM2BranchB;
1281
+ case cJU_JPBRANCH_B3: state = 3; goto SM2BranchB;
1282
+#ifdef JU_64BIT
1283
+ case cJU_JPBRANCH_B4: state = 4; goto SM2BranchB;
1284
+ case cJU_JPBRANCH_B5: state = 5; goto SM2BranchB;
1285
+ case cJU_JPBRANCH_B6: state = 6; goto SM2BranchB;
1286
+ case cJU_JPBRANCH_B7: state = 7; goto SM2BranchB;
1287
+#endif
1288
+ case cJU_JPBRANCH_B: state = cJU_ROOTSTATE; goto SM2BranchB;
1289
+
1290
+SM2BranchB:
1291
+ Pjbb = P_JBB(Pjp->jp_Addr);
1292
+ HISTPOPBOFF(subexp, offset, digit); // unpack values.
1293
+
1294
+// If theres a next-left/right JP in the current BranchB, which for
1295
+// Judy*Next() is true if any bits are set for higher Indexes, continue to
1296
+// SM3Findlimit:
1297
+//
1298
+// Note: offset is set to the JP previously traversed; go one to the
1299
+// left/right.
1300
+
1301
+#ifdef JUDYPREV
1302
+ if (offset > 0) // next-left JP is in this subexpanse.
1303
+ {
1304
+ --offset;
1305
+ goto SM2BranchBFindlimit;
1306
+ }
1307
+
1308
+ while (--subexp >= 0) // search next-left subexpanses.
1309
+#else
1310
+ if (JU_JBB_BITMAP(Pjbb, subexp)
1311
+ & JU_MASKHIGHEREXC(JU_BITPOSMASKB(digit)))
1312
+ {
1313
+ ++offset; // next-left => next-right.
1314
+ goto SM2BranchBFindlimit;
1315
+ }
1316
+
1317
+ while (++subexp < cJU_NUMSUBEXPB) // search next-right subexps.
1318
+#endif
1319
+ {
1320
+ if (! JU_JBB_PJP(Pjbb, subexp)) continue; // empty subexpanse.
1321
+
1322
+#ifdef JUDYPREV
1323
+ offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp));
1324
+ // expected range:
1325
+ assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB));
1326
+#else
1327
+ offset = 0;
1328
+#endif
1329
+
1330
+// Save the next-left/right JPs digit in *PIndex:
1331
+
1332
+SM2BranchBFindlimit:
1333
+ JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp),
1334
+ offset);
1335
+ JU_SETDIGIT(*PIndex, digit, state);
1336
+
1337
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL)
1338
+ {
1339
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1340
+ JUDY1CODE(return(JERRI );)
1341
+ JUDYLCODE(return(PPJERR);)
1342
+ }
1343
+
1344
+ Pjp += offset;
1345
+ goto SM3Findlimit;
1346
+ }
1347
+
1348
+// Theres no next-left/right JP in the BranchB:
1349
+
1350
+ goto SM2Backtrack;
1351
+
1352
+
1353
+// ----------------------------------------------------------------------------
1354
+// UNCOMPRESSED BRANCH:
1355
+
1356
+ case cJU_JPBRANCH_U2: state = 2; goto SM2BranchU;
1357
+ case cJU_JPBRANCH_U3: state = 3; goto SM2BranchU;
1358
+#ifdef JU_64BIT
1359
+ case cJU_JPBRANCH_U4: state = 4; goto SM2BranchU;
1360
+ case cJU_JPBRANCH_U5: state = 5; goto SM2BranchU;
1361
+ case cJU_JPBRANCH_U6: state = 6; goto SM2BranchU;
1362
+ case cJU_JPBRANCH_U7: state = 7; goto SM2BranchU;
1363
+#endif
1364
+ case cJU_JPBRANCH_U: state = cJU_ROOTSTATE; goto SM2BranchU;
1365
+
1366
+SM2BranchU:
1367
+
1368
+// Search for a next-left/right JP in the current BranchU, and if one is found,
1369
+// save its digit in *PIndex and continue to SM3Findlimit:
1370
+
1371
+ Pjbu = P_JBU(Pjp->jp_Addr);
1372
+ digit = offset;
1373
+
1374
+#ifdef JUDYPREV
1375
+ while (digit >= 1)
1376
+ {
1377
+ Pjp = (Pjbu->jbu_jp) + (--digit);
1378
+#else
1379
+ while (digit < cJU_BRANCHUNUMJPS - 1)
1380
+ {
1381
+ Pjp = (Pjbu->jbu_jp) + (++digit);
1382
+#endif
1383
+ if (JPNULL(JU_JPTYPE(Pjp))) continue;
1384
+
1385
+ JU_SETDIGIT(*PIndex, digit, state);
1386
+ goto SM3Findlimit;
1387
+ }
1388
+
1389
+// Theres no next-left/right JP in the BranchU:
1390
+
1391
+ goto SM2Backtrack;
1392
+
1393
+
1394
+// ----------------------------------------------------------------------------
1395
+// INVALID JP TYPE:
1396
+
1397
+ default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1398
+ JUDY1CODE(return(JERRI );)
1399
+ JUDYLCODE(return(PPJERR);)
1400
+
1401
+ } // SM2Backtrack switch.
1402
+
1403
+ /*NOTREACHED*/
1404
+
1405
+
1406
+// ============================================================================
1407
+// STATE MACHINE 3 -- FIND LIMIT JP/INDEX:
1408
+//
1409
+// Look for the highest/lowest (right/left-most) JP in each branch and the
1410
+// highest/lowest Index in a leaf or immediate, and return it. While
1411
+// traversing, modify appropriate digit(s) in *PIndex to reflect the path
1412
+// taken, including Dcd bytes in each JP (which could hold critical missing
1413
+// digits for skipped branches).
1414
+//
1415
+// ENTRY: Pjp set to a JP under which to find max/min JPs (if a branch JP) or
1416
+// a max/min Index and return (if a leaf or immediate JP).
1417
+//
1418
+// EXIT: Execute JU_RET_FOUND* upon reaching a leaf or immediate. Should be
1419
+// impossible to fail, unless the Judy array is corrupt.
1420
+
1421
+SM3Findlimit: // come or return here for first/next branch/leaf.
1422
+
1423
+ switch (JU_JPTYPE(Pjp))
1424
+ {
1425
+// ----------------------------------------------------------------------------
1426
+// LINEAR BRANCH:
1427
+//
1428
+// Simply use the highest/lowest (right/left-most) JP in the BranchL, but first
1429
+// copy the Dcd bytes to *PIndex if there are any (only if state <
1430
+// cJU_ROOTSTATE - 1).
1431
+
1432
+ case cJU_JPBRANCH_L2: SM3PREPB_DCD(2, SM3BranchL);
1433
+#ifndef JU_64BIT
1434
+ case cJU_JPBRANCH_L3: SM3PREPB( 3, SM3BranchL);
1435
+#else
1436
+ case cJU_JPBRANCH_L3: SM3PREPB_DCD(3, SM3BranchL);
1437
+ case cJU_JPBRANCH_L4: SM3PREPB_DCD(4, SM3BranchL);
1438
+ case cJU_JPBRANCH_L5: SM3PREPB_DCD(5, SM3BranchL);
1439
+ case cJU_JPBRANCH_L6: SM3PREPB_DCD(6, SM3BranchL);
1440
+ case cJU_JPBRANCH_L7: SM3PREPB( 7, SM3BranchL);
1441
+#endif
1442
+ case cJU_JPBRANCH_L: SM3PREPB( cJU_ROOTSTATE, SM3BranchL);
1443
+
1444
+SM3BranchL:
1445
+ Pjbl = P_JBL(Pjp->jp_Addr);
1446
+
1447
+#ifdef JUDYPREV
1448
+ if ((offset = (Pjbl->jbl_NumJPs) - 1) < 0)
1449
+#else
1450
+ offset = 0; if ((Pjbl->jbl_NumJPs) == 0)
1451
+#endif
1452
+ {
1453
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1454
+ JUDY1CODE(return(JERRI );)
1455
+ JUDYLCODE(return(PPJERR);)
1456
+ }
1457
+
1458
+ JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state);
1459
+ Pjp = (Pjbl->jbl_jp) + offset;
1460
+ goto SM3Findlimit;
1461
+
1462
+
1463
+// ----------------------------------------------------------------------------
1464
+// BITMAP BRANCH:
1465
+//
1466
+// Look for the highest/lowest (right/left-most) non-null subexpanse, then use
1467
+// the highest/lowest JP in that subexpanse, but first copy Dcd bytes, if there
1468
+// are any (only if state < cJU_ROOTSTATE - 1), to *PIndex.
1469
+
1470
+ case cJU_JPBRANCH_B2: SM3PREPB_DCD(2, SM3BranchB);
1471
+#ifndef JU_64BIT
1472
+ case cJU_JPBRANCH_B3: SM3PREPB( 3, SM3BranchB);
1473
+#else
1474
+ case cJU_JPBRANCH_B3: SM3PREPB_DCD(3, SM3BranchB);
1475
+ case cJU_JPBRANCH_B4: SM3PREPB_DCD(4, SM3BranchB);
1476
+ case cJU_JPBRANCH_B5: SM3PREPB_DCD(5, SM3BranchB);
1477
+ case cJU_JPBRANCH_B6: SM3PREPB_DCD(6, SM3BranchB);
1478
+ case cJU_JPBRANCH_B7: SM3PREPB( 7, SM3BranchB);
1479
+#endif
1480
+ case cJU_JPBRANCH_B: SM3PREPB( cJU_ROOTSTATE, SM3BranchB);
1481
+
1482
+SM3BranchB:
1483
+ Pjbb = P_JBB(Pjp->jp_Addr);
1484
+#ifdef JUDYPREV
1485
+ subexp = cJU_NUMSUBEXPB;
1486
+
1487
+ while (! (JU_JBB_BITMAP(Pjbb, --subexp))) // find non-empty subexp.
1488
+ {
1489
+ if (subexp <= 0) // wholly empty bitmap.
1490
+ {
1491
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1492
+ JUDY1CODE(return(JERRI );)
1493
+ JUDYLCODE(return(PPJERR);)
1494
+ }
1495
+ }
1496
+
1497
+ offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp));
1498
+ // expected range:
1499
+ assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB));
1500
+#else
1501
+ subexp = -1;
1502
+
1503
+ while (! (JU_JBB_BITMAP(Pjbb, ++subexp))) // find non-empty subexp.
1504
+ {
1505
+ if (subexp >= cJU_NUMSUBEXPB - 1) // didnt find one.
1506
+ {
1507
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1508
+ JUDY1CODE(return(JERRI );)
1509
+ JUDYLCODE(return(PPJERR);)
1510
+ }
1511
+ }
1512
+
1513
+ offset = 0;
1514
+#endif
1515
+
1516
+ JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp), offset);
1517
+ JU_SETDIGIT(*PIndex, digit, state);
1518
+
1519
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL)
1520
+ {
1521
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1522
+ JUDY1CODE(return(JERRI );)
1523
+ JUDYLCODE(return(PPJERR);)
1524
+ }
1525
+
1526
+ Pjp += offset;
1527
+ goto SM3Findlimit;
1528
+
1529
+
1530
+// ----------------------------------------------------------------------------
1531
+// UNCOMPRESSED BRANCH:
1532
+//
1533
+// Look for the highest/lowest (right/left-most) non-null JP, and use it, but
1534
+// first copy Dcd bytes to *PIndex if there are any (only if state <
1535
+// cJU_ROOTSTATE - 1).
1536
+
1537
+ case cJU_JPBRANCH_U2: SM3PREPB_DCD(2, SM3BranchU);
1538
+#ifndef JU_64BIT
1539
+ case cJU_JPBRANCH_U3: SM3PREPB( 3, SM3BranchU);
1540
+#else
1541
+ case cJU_JPBRANCH_U3: SM3PREPB_DCD(3, SM3BranchU);
1542
+ case cJU_JPBRANCH_U4: SM3PREPB_DCD(4, SM3BranchU);
1543
+ case cJU_JPBRANCH_U5: SM3PREPB_DCD(5, SM3BranchU);
1544
+ case cJU_JPBRANCH_U6: SM3PREPB_DCD(6, SM3BranchU);
1545
+ case cJU_JPBRANCH_U7: SM3PREPB( 7, SM3BranchU);
1546
+#endif
1547
+ case cJU_JPBRANCH_U: SM3PREPB( cJU_ROOTSTATE, SM3BranchU);
1548
+
1549
+SM3BranchU:
1550
+ Pjbu = P_JBU(Pjp->jp_Addr);
1551
+#ifdef JUDYPREV
1552
+ digit = cJU_BRANCHUNUMJPS;
1553
+
1554
+ while (digit >= 1)
1555
+ {
1556
+ Pjp = (Pjbu->jbu_jp) + (--digit);
1557
+#else
1558
+
1559
+ for (digit = 0; digit < cJU_BRANCHUNUMJPS; ++digit)
1560
+ {
1561
+ Pjp = (Pjbu->jbu_jp) + digit;
1562
+#endif
1563
+ if (JPNULL(JU_JPTYPE(Pjp))) continue;
1564
+
1565
+ JU_SETDIGIT(*PIndex, digit, state);
1566
+ goto SM3Findlimit;
1567
+ }
1568
+
1569
+// No non-null JPs in BranchU:
1570
+
1571
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1572
+ JUDY1CODE(return(JERRI );)
1573
+ JUDYLCODE(return(PPJERR);)
1574
+
1575
+
1576
+// ----------------------------------------------------------------------------
1577
+// LINEAR LEAF:
1578
+//
1579
+// Simply use the highest/lowest (right/left-most) Index in the LeafL, but the
1580
+// details vary depending on leaf Index Size. First copy Dcd bytes, if there
1581
+// are any (only if state < cJU_ROOTSTATE - 1), to *PIndex.
1582
+
1583
+#define SM3LEAFLDCD(cState) \
1584
+ JU_SETDCD(*PIndex, Pjp, cState); \
1585
+ SM3LEAFLNODCD
1586
+
1587
+#ifdef JUDY1
1588
+#define SM3LEAFL_SETPOP1 // not needed in any cases.
1589
+#else
1590
+#define SM3LEAFL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1
1591
+#endif
1592
+
1593
+#ifdef JUDYPREV
1594
+#define SM3LEAFLNODCD \
1595
+ Pjll = P_JLL(Pjp->jp_Addr); \
1596
+ SM3LEAFL_SETPOP1; \
1597
+ offset = JU_JPLEAF_POP0(Pjp); assert(offset >= 0)
1598
+#else
1599
+#define SM3LEAFLNODCD \
1600
+ Pjll = P_JLL(Pjp->jp_Addr); \
1601
+ SM3LEAFL_SETPOP1; \
1602
+ offset = 0; assert(JU_JPLEAF_POP0(Pjp) >= 0);
1603
+#endif
1604
+
1605
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
1606
+ case cJU_JPLEAF1:
1607
+
1608
+ SM3LEAFLDCD(1);
1609
+ JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
1610
+ JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
1611
+#endif
1612
+
1613
+ case cJU_JPLEAF2:
1614
+
1615
+ SM3LEAFLDCD(2);
1616
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
1617
+ | ((uint16_t *) Pjll)[offset];
1618
+ JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
1619
+
1620
+#ifndef JU_64BIT
1621
+ case cJU_JPLEAF3:
1622
+ {
1623
+ Word_t lsb;
1624
+ SM3LEAFLNODCD;
1625
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
1626
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
1627
+ JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
1628
+ }
1629
+
1630
+#else
1631
+ case cJU_JPLEAF3:
1632
+ {
1633
+ Word_t lsb;
1634
+ SM3LEAFLDCD(3);
1635
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
1636
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
1637
+ JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
1638
+ }
1639
+
1640
+ case cJU_JPLEAF4:
1641
+
1642
+ SM3LEAFLDCD(4);
1643
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
1644
+ | ((uint32_t *) Pjll)[offset];
1645
+ JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
1646
+
1647
+ case cJU_JPLEAF5:
1648
+ {
1649
+ Word_t lsb;
1650
+ SM3LEAFLDCD(5);
1651
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
1652
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
1653
+ JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
1654
+ }
1655
+
1656
+ case cJU_JPLEAF6:
1657
+ {
1658
+ Word_t lsb;
1659
+ SM3LEAFLDCD(6);
1660
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
1661
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
1662
+ JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
1663
+ }
1664
+
1665
+ case cJU_JPLEAF7:
1666
+ {
1667
+ Word_t lsb;
1668
+ SM3LEAFLNODCD;
1669
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
1670
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
1671
+ JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
1672
+ }
1673
+#endif
1674
+
1675
+
1676
+// ----------------------------------------------------------------------------
1677
+// BITMAP LEAF:
1678
+//
1679
+// Look for the highest/lowest (right/left-most) non-null subexpanse, then use
1680
+// the highest/lowest Index in that subexpanse, but first copy Dcd bytes
1681
+// (always present since state 1 < cJU_ROOTSTATE) to *PIndex.
1682
+
1683
+ case cJU_JPLEAF_B1:
1684
+ {
1685
+ Pjlb_t Pjlb;
1686
+
1687
+ JU_SETDCD(*PIndex, Pjp, 1);
1688
+
1689
+ Pjlb = P_JLB(Pjp->jp_Addr);
1690
+#ifdef JUDYPREV
1691
+ subexp = cJU_NUMSUBEXPL;
1692
+
1693
+ while (! JU_JLB_BITMAP(Pjlb, --subexp)) // find non-empty subexp.
1694
+ {
1695
+ if (subexp <= 0) // wholly empty bitmap.
1696
+ {
1697
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1698
+ JUDY1CODE(return(JERRI );)
1699
+ JUDYLCODE(return(PPJERR);)
1700
+ }
1701
+ }
1702
+
1703
+// TBD: Might it be faster to just use a variant of BITMAPDIGIT*() that yields
1704
+// the digit for the right-most Index with a bit set?
1705
+
1706
+ offset = SEARCHBITMAPMAXL(JU_JLB_BITMAP(Pjlb, subexp));
1707
+ // expected range:
1708
+ assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPL));
1709
+#else
1710
+ subexp = -1;
1711
+
1712
+ while (! JU_JLB_BITMAP(Pjlb, ++subexp)) // find non-empty subexp.
1713
+ {
1714
+ if (subexp >= cJU_NUMSUBEXPL - 1) // didnt find one.
1715
+ {
1716
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1717
+ JUDY1CODE(return(JERRI );)
1718
+ JUDYLCODE(return(PPJERR);)
1719
+ }
1720
+ }
1721
+
1722
+ offset = 0;
1723
+#endif
1724
+
1725
+ JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
1726
+ JU_SETDIGIT1(*PIndex, digit);
1727
+ JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
1728
+// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset)));
1729
+
1730
+ } // case cJU_JPLEAF_B1
1731
+
1732
+#ifdef JUDY1
1733
+// ----------------------------------------------------------------------------
1734
+// FULL POPULATION:
1735
+//
1736
+// Copy Dcd bytes to *PIndex (always present since state 1 < cJU_ROOTSTATE),
1737
+// then set the highest/lowest possible digit as the LSB in *PIndex.
1738
+
1739
+ case cJ1_JPFULLPOPU1:
1740
+
1741
+ JU_SETDCD( *PIndex, Pjp, 1);
1742
+#ifdef JUDYPREV
1743
+ JU_SETDIGIT1(*PIndex, cJU_BITSPERBITMAP - 1);
1744
+#else
1745
+ JU_SETDIGIT1(*PIndex, 0);
1746
+#endif
1747
+ JU_RET_FOUND_FULLPOPU1;
1748
+#endif // JUDY1
1749
+
1750
+
1751
+// ----------------------------------------------------------------------------
1752
+// IMMEDIATE:
1753
+//
1754
+// Simply use the highest/lowest (right/left-most) Index in the Imm, but the
1755
+// details vary depending on leaf Index Size and pop1. Note: There are no Dcd
1756
+// bytes in an Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the
1757
+// least bytes of the immediate Index.
1758
+
1759
+ case cJU_JPIMMED_1_01: SET_01(1); goto SM3Imm_01;
1760
+ case cJU_JPIMMED_2_01: SET_01(2); goto SM3Imm_01;
1761
+ case cJU_JPIMMED_3_01: SET_01(3); goto SM3Imm_01;
1762
+#ifdef JU_64BIT
1763
+ case cJU_JPIMMED_4_01: SET_01(4); goto SM3Imm_01;
1764
+ case cJU_JPIMMED_5_01: SET_01(5); goto SM3Imm_01;
1765
+ case cJU_JPIMMED_6_01: SET_01(6); goto SM3Imm_01;
1766
+ case cJU_JPIMMED_7_01: SET_01(7); goto SM3Imm_01;
1767
+#endif
1768
+SM3Imm_01: JU_RET_FOUND_IMM_01(Pjp);
1769
+
1770
+#ifdef JUDYPREV
1771
+#define SM3IMM_OFFSET(cPop1) (cPop1) - 1 // highest.
1772
+#else
1773
+#define SM3IMM_OFFSET(cPop1) 0 // lowest.
1774
+#endif
1775
+
1776
+#define SM3IMM(cPop1,Next) \
1777
+ offset = SM3IMM_OFFSET(cPop1); \
1778
+ goto Next
1779
+
1780
+ case cJU_JPIMMED_1_02: SM3IMM( 2, SM3Imm1);
1781
+ case cJU_JPIMMED_1_03: SM3IMM( 3, SM3Imm1);
1782
+#if (defined(JUDY1) || defined(JU_64BIT))
1783
+ case cJU_JPIMMED_1_04: SM3IMM( 4, SM3Imm1);
1784
+ case cJU_JPIMMED_1_05: SM3IMM( 5, SM3Imm1);
1785
+ case cJU_JPIMMED_1_06: SM3IMM( 6, SM3Imm1);
1786
+ case cJU_JPIMMED_1_07: SM3IMM( 7, SM3Imm1);
1787
+#endif
1788
+#if (defined(JUDY1) && defined(JU_64BIT))
1789
+ case cJ1_JPIMMED_1_08: SM3IMM( 8, SM3Imm1);
1790
+ case cJ1_JPIMMED_1_09: SM3IMM( 9, SM3Imm1);
1791
+ case cJ1_JPIMMED_1_10: SM3IMM(10, SM3Imm1);
1792
+ case cJ1_JPIMMED_1_11: SM3IMM(11, SM3Imm1);
1793
+ case cJ1_JPIMMED_1_12: SM3IMM(12, SM3Imm1);
1794
+ case cJ1_JPIMMED_1_13: SM3IMM(13, SM3Imm1);
1795
+ case cJ1_JPIMMED_1_14: SM3IMM(14, SM3Imm1);
1796
+ case cJ1_JPIMMED_1_15: SM3IMM(15, SM3Imm1);
1797
+#endif
1798
+
1799
+SM3Imm1: JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
1800
+ JU_RET_FOUND_IMM(Pjp, offset);
1801
+
1802
+#if (defined(JUDY1) || defined(JU_64BIT))
1803
+ case cJU_JPIMMED_2_02: SM3IMM(2, SM3Imm2);
1804
+ case cJU_JPIMMED_2_03: SM3IMM(3, SM3Imm2);
1805
+#endif
1806
+#if (defined(JUDY1) && defined(JU_64BIT))
1807
+ case cJ1_JPIMMED_2_04: SM3IMM(4, SM3Imm2);
1808
+ case cJ1_JPIMMED_2_05: SM3IMM(5, SM3Imm2);
1809
+ case cJ1_JPIMMED_2_06: SM3IMM(6, SM3Imm2);
1810
+ case cJ1_JPIMMED_2_07: SM3IMM(7, SM3Imm2);
1811
+#endif
1812
+
1813
+#if (defined(JUDY1) || defined(JU_64BIT))
1814
+SM3Imm2: *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
1815
+ | ((uint16_t *) PJI)[offset];
1816
+ JU_RET_FOUND_IMM(Pjp, offset);
1817
+#endif
1818
+
1819
+#if (defined(JUDY1) || defined(JU_64BIT))
1820
+ case cJU_JPIMMED_3_02: SM3IMM(2, SM3Imm3);
1821
+#endif
1822
+#if (defined(JUDY1) && defined(JU_64BIT))
1823
+ case cJ1_JPIMMED_3_03: SM3IMM(3, SM3Imm3);
1824
+ case cJ1_JPIMMED_3_04: SM3IMM(4, SM3Imm3);
1825
+ case cJ1_JPIMMED_3_05: SM3IMM(5, SM3Imm3);
1826
+#endif
1827
+
1828
+#if (defined(JUDY1) || defined(JU_64BIT))
1829
+SM3Imm3:
1830
+ {
1831
+ Word_t lsb;
1832
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
1833
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
1834
+ JU_RET_FOUND_IMM(Pjp, offset);
1835
+ }
1836
+#endif
1837
+
1838
+#if (defined(JUDY1) && defined(JU_64BIT))
1839
+ case cJ1_JPIMMED_4_02: SM3IMM(2, SM3Imm4);
1840
+ case cJ1_JPIMMED_4_03: SM3IMM(3, SM3Imm4);
1841
+
1842
+SM3Imm4: *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
1843
+ | ((uint32_t *) PJI)[offset];
1844
+ JU_RET_FOUND_IMM(Pjp, offset);
1845
+
1846
+ case cJ1_JPIMMED_5_02: SM3IMM(2, SM3Imm5);
1847
+ case cJ1_JPIMMED_5_03: SM3IMM(3, SM3Imm5);
1848
+
1849
+SM3Imm5:
1850
+ {
1851
+ Word_t lsb;
1852
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
1853
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
1854
+ JU_RET_FOUND_IMM(Pjp, offset);
1855
+ }
1856
+
1857
+ case cJ1_JPIMMED_6_02: SM3IMM(2, SM3Imm6);
1858
+
1859
+SM3Imm6:
1860
+ {
1861
+ Word_t lsb;
1862
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
1863
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
1864
+ JU_RET_FOUND_IMM(Pjp, offset);
1865
+ }
1866
+
1867
+ case cJ1_JPIMMED_7_02: SM3IMM(2, SM3Imm7);
1868
+
1869
+SM3Imm7:
1870
+ {
1871
+ Word_t lsb;
1872
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
1873
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
1874
+ JU_RET_FOUND_IMM(Pjp, offset);
1875
+ }
1876
+#endif // (JUDY1 && JU_64BIT)
1877
+
1878
+
1879
+// ----------------------------------------------------------------------------
1880
+// OTHER CASES:
1881
+
1882
+ default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1883
+ JUDY1CODE(return(JERRI );)
1884
+ JUDYLCODE(return(PPJERR);)
1885
+
1886
+ } // SM3Findlimit switch.
1887
+
1888
+ /*NOTREACHED*/
1889
+
1890
+} // Judy1Prev() / Judy1Next() / JudyLPrev() / JudyLNext()
libnetdata/libjudy/src/JudyL/JudyLNextEmpty.c
new
+1390
@@ -0,0 +1,1390 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.32 $ $Source: /judy/src/JudyCommon/JudyPrevNextEmpty.c $
19
+//
20
+// Judy*PrevEmpty() and Judy*NextEmpty() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// Compile with -DJUDYNEXT for the Judy*NextEmpty() function; otherwise
24
+// defaults to Judy*PrevEmpty().
25
+//
26
+// Compile with -DTRACEJPSE to trace JP traversals.
27
+//
28
+// This file is separate from JudyPrevNext.c because it differs too greatly for
29
+// ifdefs. This might be a bit surprising, but there are two reasons:
30
+//
31
+// - First, down in the details, searching for an empty index (SearchEmpty) is
32
+// remarkably asymmetric with searching for a valid index (SearchValid),
33
+// mainly with respect to: No return of a value area for JudyL; partially-
34
+// full versus totally-full JPs; and handling of narrow pointers.
35
+//
36
+// - Second, we chose to implement SearchEmpty without a backtrack stack or
37
+// backtrack engine, partly as an experiment, and partly because we think
38
+// restarting from the top of the tree is less likely for SearchEmpty than
39
+// for SearchValid, because empty indexes are more likely than valid indexes.
40
+//
41
+// A word about naming: A prior version of this feature (see 4.13) was named
42
+// Judy*Free(), but there were concerns about that being read as a verb rather
43
+// than an adjective. After prolonged debate and based on user input, we
44
+// changed "Free" to "Empty".
45
+
46
+#if (! (defined(JUDY1) || defined(JUDYL)))
47
+#error: One of -DJUDY1 or -DJUDYL must be specified.
48
+#endif
49
+
50
+#ifndef JUDYNEXT
51
+#ifndef JUDYPREV
52
+#define JUDYPREV 1 // neither set => use default.
53
+#endif
54
+#endif
55
+
56
+#ifdef JUDY1
57
+#include "Judy1.h"
58
+#else
59
+#include "JudyL.h"
60
+#endif
61
+
62
+#include "JudyPrivate1L.h"
63
+
64
+#ifdef TRACEJPSE
65
+#include "JudyPrintJP.c"
66
+#endif
67
+
68
+
69
+// ****************************************************************************
70
+// J U D Y 1 P R E V E M P T Y
71
+// J U D Y 1 N E X T E M P T Y
72
+// J U D Y L P R E V E M P T Y
73
+// J U D Y L N E X T E M P T Y
74
+//
75
+// See the manual entry for the API.
76
+//
77
+// OVERVIEW OF Judy*PrevEmpty() / Judy*NextEmpty():
78
+//
79
+// See also for comparison the equivalent comments in JudyPrevNext.c.
80
+//
81
+// Take the callers *PIndex and subtract/add 1, but watch out for
82
+// underflow/overflow, which means "no previous/next empty index found." Use a
83
+// reentrant switch statement (state machine, see SMGetRestart and
84
+// SMGetContinue) to decode Index, starting with the JRP (PArray), through a
85
+// JPM and branches, if any, down to an immediate or a leaf. Look for Index in
86
+// that immediate or leaf, and if not found (invalid index), return success
87
+// (Index is empty).
88
+//
89
+// This search can result in a dead end where taking a different path is
90
+// required. There are four kinds of dead ends:
91
+//
92
+// BRANCH PRIMARY dead end: Encountering a fully-populated JP for the
93
+// appropriate digit in Index. Search sideways in the branch for the
94
+// previous/next absent/null/non-full JP, and if one is found, set Index to the
95
+// highest/lowest index possible in that JPs expanse. Then if the JP is an
96
+// absent or null JP, return success; otherwise for a non-full JP, traverse
97
+// through the partially populated JP.
98
+//
99
+// BRANCH SECONDARY dead end: Reaching the end of a branch during a sideways
100
+// search after a branch primary dead end. Set Index to the lowest/highest
101
+// index possible in the whole branchs expanse (one higher/lower than the
102
+// previous/next branchs expanse), then restart at the top of the tree, which
103
+// includes pre-decrementing/incrementing Index (again) and watching for
104
+// underflow/overflow (again).
105
+//
106
+// LEAF PRIMARY dead end: Finding a valid (non-empty) index in an immediate or
107
+// leaf matching Index. Search sideways in the immediate/leaf for the
108
+// previous/next empty index; if found, set *PIndex to match and return success.
109
+//
110
+// LEAF SECONDARY dead end: Reaching the end of an immediate or leaf during a
111
+// sideways search after a leaf primary dead end. Just as for a branch
112
+// secondary dead end, restart at the top of the tree with Index set to the
113
+// lowest/highest index possible in the whole immediate/leafs expanse.
114
+// TBD: If leaf secondary dead end occurs, could shortcut and treat it as a
115
+// branch primary dead end; but this would require remembering the parent
116
+// branchs type and offset (a "one-deep stack"), and also wrestling with
117
+// narrow pointers, at least for leaves (but not for immediates).
118
+//
119
+// Note some ASYMMETRIES between SearchValid and SearchEmpty:
120
+//
121
+// - The SearchValid code, upon descending through a narrow pointer, if Index
122
+// is outside the expanse of the subsidiary node (effectively a secondary
123
+// dead end), must decide whether to backtrack or findlimit. But the
124
+// SearchEmpty code simply returns success (Index is empty).
125
+//
126
+// - Similarly, the SearchValid code, upon finding no previous/next index in
127
+// the expanse of a narrow pointer (again, a secondary dead end), can simply
128
+// start to backtrack at the parent JP. But the SearchEmpty code would have
129
+// to first determine whether or not the parent JPs narrow expanse contains
130
+// a previous/next empty index outside the subexpanse. Rather than keeping a
131
+// parent state stack and backtracking this way, upon a secondary dead end,
132
+// the SearchEmpty code simply restarts at the top of the tree, whether or
133
+// not a narrow pointer is involved. Again, see the equivalent comments in
134
+// JudyPrevNext.c for comparison.
135
+//
136
+// This function is written iteratively for speed, rather than recursively.
137
+//
138
+// TBD: Wed like to enhance this function to make successive searches faster.
139
+// This would require saving some previous state, including the previous Index
140
+// returned, and in which leaf it was found. If the next call is for the same
141
+// Index and the array has not been modified, start at the same leaf. This
142
+// should be much easier to implement since this is iterative rather than
143
+// recursive code.
144
+
145
+#ifdef JUDY1
146
+#ifdef JUDYPREV
147
+FUNCTION int Judy1PrevEmpty
148
+#else
149
+FUNCTION int Judy1NextEmpty
150
+#endif
151
+#else
152
+#ifdef JUDYPREV
153
+FUNCTION int JudyLPrevEmpty
154
+#else
155
+FUNCTION int JudyLNextEmpty
156
+#endif
157
+#endif
158
+ (
159
+ Pcvoid_t PArray, // Judy array to search.
160
+ Word_t * PIndex, // starting point and result.
161
+ PJError_t PJError // optional, for returning error info.
162
+ )
163
+{
164
+ Word_t Index; // fast copy, in a register.
165
+ Pjp_t Pjp; // current JP.
166
+ Pjbl_t Pjbl; // Pjp->jp_Addr masked and cast to types:
167
+ Pjbb_t Pjbb;
168
+ Pjbu_t Pjbu;
169
+ Pjlb_t Pjlb;
170
+ PWord_t Pword; // alternate name for use by GET* macros.
171
+
172
+ Word_t digit; // next digit to decode from Index.
173
+ Word_t digits; // current state in SM = digits left to decode.
174
+ Word_t pop0; // in a leaf.
175
+ Word_t pop0mask; // precalculated to avoid variable shifts.
176
+ long offset; // within a branch or leaf (can be large).
177
+ int subexp; // subexpanse in a bitmap branch.
178
+ BITMAPB_t bitposmaskB; // bit in bitmap for bitmap branch.
179
+ BITMAPL_t bitposmaskL; // bit in bitmap for bitmap leaf.
180
+ Word_t possfullJP1; // JP types for possibly full subexpanses:
181
+ Word_t possfullJP2;
182
+ Word_t possfullJP3;
183
+
184
+
185
+// ----------------------------------------------------------------------------
186
+// M A C R O S
187
+//
188
+// These are intended to make the code a bit more readable and less redundant.
189
+
190
+
191
+// CHECK FOR NULL JP:
192
+//
193
+// TBD: In principle this can be reduced (here and in other *.c files) to just
194
+// the latter clause since no Type should ever be below cJU_JPNULL1, but in
195
+// fact some root pointer types can be lower, so for safety do both checks.
196
+
197
+#define JPNULL(Type) (((Type) >= cJU_JPNULL1) && ((Type) <= cJU_JPNULLMAX))
198
+
199
+
200
+// CHECK FOR A FULL JP:
201
+//
202
+// Given a JP, indicate if it is fully populated. Use digits, pop0mask, and
203
+// possfullJP1..3 in the context.
204
+//
205
+// This is a difficult problem because it requires checking the Pop0 bits for
206
+// all-ones, but the number of bytes depends on the JP type, which is not
207
+// directly related to the parent branchs type or level -- the JPs child
208
+// could be under a narrow pointer (hence not full). The simple answer
209
+// requires switching on or otherwise calculating the JP type, which could be
210
+// slow. Instead, in SMPREPB* precalculate pop0mask and also record in
211
+// possfullJP1..3 the child JP (branch) types that could possibly be full (one
212
+// level down), and use them here. For level-2 branches (with digits == 2),
213
+// the test for a full child depends on Judy1/JudyL.
214
+//
215
+// Note: This cannot be applied to the JP in a JPM because it doesnt have
216
+// enough pop0 digits.
217
+//
218
+// TBD: JPFULL_BRANCH diligently checks for BranchL or BranchB, where neither
219
+// of those can ever be full as it turns out. Could just check for a BranchU
220
+// at the right level. Also, pop0mask might be overkill, its not used much,
221
+// so perhaps just call cJU_POP0MASK(digits - 1) here?
222
+//
223
+// First, JPFULL_BRANCH checks for a full expanse for a JP whose child can be a
224
+// branch, that is, a JP in a branch at level 3 or higher:
225
+
226
+#define JPFULL_BRANCH(Pjp) \
227
+ ((((JU_JPDCDPOP0(Pjp) ^ cJU_ALLONES) & pop0mask) == 0) \
228
+ && ((JU_JPTYPE(Pjp) == possfullJP1) \
229
+ || (JU_JPTYPE(Pjp) == possfullJP2) \
230
+ || (JU_JPTYPE(Pjp) == possfullJP3)))
231
+
232
+#ifdef JUDY1
233
+#define JPFULL(Pjp) \
234
+ ((digits == 2) ? \
235
+ (JU_JPTYPE(Pjp) == cJ1_JPFULLPOPU1) : JPFULL_BRANCH(Pjp))
236
+#else
237
+#define JPFULL(Pjp) \
238
+ ((digits == 2) ? \
239
+ (JU_JPTYPE(Pjp) == cJU_JPLEAF_B1) \
240
+ && (((JU_JPDCDPOP0(Pjp) & cJU_POP0MASK(1)) == cJU_POP0MASK(1))) : \
241
+ JPFULL_BRANCH(Pjp))
242
+#endif
243
+
244
+
245
+// RETURN SUCCESS:
246
+//
247
+// This hides the need to set *PIndex back to the local value of Index -- use a
248
+// local value for faster operation. Note that the callers *PIndex is ALWAYS
249
+// modified upon success, at least decremented/incremented.
250
+
251
+#define RET_SUCCESS { *PIndex = Index; return(1); }
252
+
253
+
254
+// RETURN A CORRUPTION:
255
+
256
+#define RET_CORRUPT { JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); return(JERRI); }
257
+
258
+
259
+// SEARCH A BITMAP BRANCH:
260
+//
261
+// This is a weak analog of j__udySearchLeaf*() for bitmap branches. Return
262
+// the actual or next-left position, base 0, of Digit in a BITMAPB_t bitmap
263
+// (subexpanse of a full bitmap), also given a Bitposmask for Digit. The
264
+// position is the offset within the set bits.
265
+//
266
+// Unlike j__udySearchLeaf*(), the offset is not returned bit-complemented if
267
+// Digits bit is unset, because the caller can check the bitmap themselves to
268
+// determine that. Also, if Digits bit is unset, the returned offset is to
269
+// the next-left JP or index (including -1), not to the "ideal" position for
270
+// the index = next-right JP or index.
271
+//
272
+// Shortcut and skip calling j__udyCountBitsB() if the bitmap is full, in which
273
+// case (Digit % cJU_BITSPERSUBEXPB) itself is the base-0 offset.
274
+
275
+#define SEARCHBITMAPB(Bitmap,Digit,Bitposmask) \
276
+ (((Bitmap) == cJU_FULLBITMAPB) ? (Digit % cJU_BITSPERSUBEXPB) : \
277
+ j__udyCountBitsB((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1)
278
+
279
+#ifdef JUDYPREV
280
+// Equivalent to search for the highest offset in Bitmap, that is, one less
281
+// than the number of bits set:
282
+
283
+#define SEARCHBITMAPMAXB(Bitmap) \
284
+ (((Bitmap) == cJU_FULLBITMAPB) ? cJU_BITSPERSUBEXPB - 1 : \
285
+ j__udyCountBitsB(Bitmap) - 1)
286
+#endif
287
+
288
+
289
+// CHECK DECODE BYTES:
290
+//
291
+// Check Decode bytes in a JP against the equivalent portion of Index. If they
292
+// dont match, Index is outside the subexpanse of a narrow pointer, hence is
293
+// empty.
294
+
295
+#define CHECKDCD(cDigits) \
296
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, cDigits)) RET_SUCCESS
297
+
298
+
299
+// REVISE REMAINDER OF INDEX:
300
+//
301
+// Put one digit in place in Index and clear/set the lower digits, if any, so
302
+// the resulting Index is at the start/end of an expanse, or just clear/set the
303
+// least digits.
304
+//
305
+// Actually, to make simple use of JU_LEASTBYTESMASK, first clear/set all least
306
+// digits of Index including the digit to be overridden, then set the value of
307
+// that one digit. If Digits == 1 the first operation is redundant, but either
308
+// very fast or even removed by the optimizer.
309
+
310
+#define CLEARLEASTDIGITS(Digits) Index &= ~JU_LEASTBYTESMASK(Digits)
311
+#define SETLEASTDIGITS( Digits) Index |= JU_LEASTBYTESMASK(Digits)
312
+
313
+#define CLEARLEASTDIGITS_D(Digit,Digits) \
314
+ { \
315
+ CLEARLEASTDIGITS(Digits); \
316
+ JU_SETDIGIT(Index, Digit, Digits); \
317
+ }
318
+
319
+#define SETLEASTDIGITS_D(Digit,Digits) \
320
+ { \
321
+ SETLEASTDIGITS(Digits); \
322
+ JU_SETDIGIT(Index, Digit, Digits); \
323
+ }
324
+
325
+
326
+// SET REMAINDER OF INDEX AND THEN RETURN OR CONTINUE:
327
+
328
+#define SET_AND_RETURN(OpLeastDigits,Digit,Digits) \
329
+ { \
330
+ OpLeastDigits(Digit, Digits); \
331
+ RET_SUCCESS; \
332
+ }
333
+
334
+#define SET_AND_CONTINUE(OpLeastDigits,Digit,Digits) \
335
+ { \
336
+ OpLeastDigits(Digit, Digits); \
337
+ goto SMGetContinue; \
338
+ }
339
+
340
+
341
+// PREPARE TO HANDLE A LEAFW OR JP BRANCH IN THE STATE MACHINE:
342
+//
343
+// Extract a state-dependent digit from Index in a "constant" way, then jump to
344
+// common code for multiple cases.
345
+//
346
+// TBD: Should this macro do more, such as preparing variable-shift masks for
347
+// use in CLEARLEASTDIGITS and SETLEASTDIGITS?
348
+
349
+#define SMPREPB(cDigits,Next,PossFullJP1,PossFullJP2,PossFullJP3) \
350
+ digits = (cDigits); \
351
+ digit = JU_DIGITATSTATE(Index, cDigits); \
352
+ pop0mask = cJU_POP0MASK((cDigits) - 1); /* for branchs JPs */ \
353
+ possfullJP1 = (PossFullJP1); \
354
+ possfullJP2 = (PossFullJP2); \
355
+ possfullJP3 = (PossFullJP3); \
356
+ goto Next
357
+
358
+// Variations for specific-level branches and for shorthands:
359
+//
360
+// Note: SMPREPB2 need not initialize possfullJP* because JPFULL does not use
361
+// them for digits == 2, but gcc -Wall isnt quite smart enough to see this, so
362
+// waste a bit of time and space to get rid of the warning:
363
+
364
+#define SMPREPB2(Next) \
365
+ digits = 2; \
366
+ digit = JU_DIGITATSTATE(Index, 2); \
367
+ pop0mask = cJU_POP0MASK(1); /* for branchs JPs */ \
368
+ possfullJP1 = possfullJP2 = possfullJP3 = 0; \
369
+ goto Next
370
+
371
+#define SMPREPB3(Next) SMPREPB(3, Next, cJU_JPBRANCH_L2, \
372
+ cJU_JPBRANCH_B2, \
373
+ cJU_JPBRANCH_U2)
374
+#ifndef JU_64BIT
375
+#define SMPREPBL(Next) SMPREPB(cJU_ROOTSTATE, Next, cJU_JPBRANCH_L3, \
376
+ cJU_JPBRANCH_B3, \
377
+ cJU_JPBRANCH_U3)
378
+#else
379
+#define SMPREPB4(Next) SMPREPB(4, Next, cJU_JPBRANCH_L3, \
380
+ cJU_JPBRANCH_B3, \
381
+ cJU_JPBRANCH_U3)
382
+#define SMPREPB5(Next) SMPREPB(5, Next, cJU_JPBRANCH_L4, \
383
+ cJU_JPBRANCH_B4, \
384
+ cJU_JPBRANCH_U4)
385
+#define SMPREPB6(Next) SMPREPB(6, Next, cJU_JPBRANCH_L5, \
386
+ cJU_JPBRANCH_B5, \
387
+ cJU_JPBRANCH_U5)
388
+#define SMPREPB7(Next) SMPREPB(7, Next, cJU_JPBRANCH_L6, \
389
+ cJU_JPBRANCH_B6, \
390
+ cJU_JPBRANCH_U6)
391
+#define SMPREPBL(Next) SMPREPB(cJU_ROOTSTATE, Next, cJU_JPBRANCH_L7, \
392
+ cJU_JPBRANCH_B7, \
393
+ cJU_JPBRANCH_U7)
394
+#endif
395
+
396
+
397
+// RESTART AFTER SECONDARY DEAD END:
398
+//
399
+// Set Index to the first/last index in the branch or leaf subexpanse and start
400
+// over at the top of the tree.
401
+
402
+#ifdef JUDYPREV
403
+#define SMRESTART(Digits) { CLEARLEASTDIGITS(Digits); goto SMGetRestart; }
404
+#else
405
+#define SMRESTART(Digits) { SETLEASTDIGITS( Digits); goto SMGetRestart; }
406
+#endif
407
+
408
+
409
+// CHECK EDGE OF LEAFS EXPANSE:
410
+//
411
+// Given the LSBs of the lowest/highest valid index in a leaf (or equivalently
412
+// in an immediate JP), the level (index size) of the leaf, and the full index
413
+// to return (as Index in the context) already set to the full index matching
414
+// the lowest/highest one, determine if there is an empty index in the leafs
415
+// expanse below/above the lowest/highest index, which is true if the
416
+// lowest/highest index is not at the "edge" of the leafs expanse based on its
417
+// LSBs. If so, return Index decremented/incremented; otherwise restart at the
418
+// top of the tree.
419
+//
420
+// Note: In many cases Index is already at the right spot and calling
421
+// SMRESTART instead of just going directly to SMGetRestart is a bit of
422
+// overkill.
423
+//
424
+// Note: Variable shift occurs if Digits is not a constant.
425
+
426
+#ifdef JUDYPREV
427
+#define LEAF_EDGE(MinIndex,Digits) \
428
+ { \
429
+ if (MinIndex) { --Index; RET_SUCCESS; } \
430
+ SMRESTART(Digits); \
431
+ }
432
+#else
433
+#define LEAF_EDGE(MaxIndex,Digits) \
434
+ { \
435
+ if ((MaxIndex) != JU_LEASTBYTES(cJU_ALLONES, Digits)) \
436
+ { ++Index; RET_SUCCESS; } \
437
+ SMRESTART(Digits); \
438
+ }
439
+#endif
440
+
441
+// Same as above except Index is not already set to match the lowest/highest
442
+// index, so do that before decrementing/incrementing it:
443
+
444
+#ifdef JUDYPREV
445
+#define LEAF_EDGE_SET(MinIndex,Digits) \
446
+ { \
447
+ if (MinIndex) \
448
+ { JU_SETDIGITS(Index, MinIndex, Digits); --Index; RET_SUCCESS; } \
449
+ SMRESTART(Digits); \
450
+ }
451
+#else
452
+#define LEAF_EDGE_SET(MaxIndex,Digits) \
453
+ { \
454
+ if ((MaxIndex) != JU_LEASTBYTES(cJU_ALLONES, Digits)) \
455
+ { JU_SETDIGITS(Index, MaxIndex, Digits); ++Index; RET_SUCCESS; } \
456
+ SMRESTART(Digits); \
457
+ }
458
+#endif
459
+
460
+
461
+// FIND A HOLE (EMPTY INDEX) IN AN IMMEDIATE OR LEAF:
462
+//
463
+// Given an index location in a leaf (or equivalently an immediate JP) known to
464
+// contain a usable hole (an empty index less/greater than Index), and the LSBs
465
+// of a minimum/maximum index to locate, find the previous/next empty index and
466
+// return it.
467
+//
468
+// Note: "Even" index sizes (1,2,4[,8] bytes) have corresponding native C
469
+// types; "odd" index sizes dont, but they are not represented here because
470
+// they are handled completely differently; see elsewhere.
471
+
472
+#ifdef JUDYPREV
473
+
474
+#define LEAF_HOLE_EVEN(cDigits,Pjll,IndexLSB) \
475
+ { \
476
+ while (*(Pjll) > (IndexLSB)) --(Pjll); /* too high */ \
477
+ if (*(Pjll) < (IndexLSB)) RET_SUCCESS /* Index is empty */ \
478
+ while (*(--(Pjll)) == --(IndexLSB)) /* null, find a hole */;\
479
+ JU_SETDIGITS(Index, IndexLSB, cDigits); \
480
+ RET_SUCCESS; \
481
+ }
482
+#else
483
+#define LEAF_HOLE_EVEN(cDigits,Pjll,IndexLSB) \
484
+ { \
485
+ while (*(Pjll) < (IndexLSB)) ++(Pjll); /* too low */ \
486
+ if (*(Pjll) > (IndexLSB)) RET_SUCCESS /* Index is empty */ \
487
+ while (*(++(Pjll)) == ++(IndexLSB)) /* null, find a hole */;\
488
+ JU_SETDIGITS(Index, IndexLSB, cDigits); \
489
+ RET_SUCCESS; \
490
+ }
491
+#endif
492
+
493
+
494
+// SEARCH FOR AN EMPTY INDEX IN AN IMMEDIATE OR LEAF:
495
+//
496
+// Given a pointer to the first index in a leaf (or equivalently an immediate
497
+// JP), the population of the leaf, and a first empty Index to find (inclusive,
498
+// as Index in the context), where Index is known to fall within the expanse of
499
+// the leaf to search, efficiently find the previous/next empty index in the
500
+// leaf, if any. For simplicity the following overview is stated in terms of
501
+// Judy*NextEmpty() only, but the same concepts apply symmetrically for
502
+// Judy*PrevEmpty(). Also, in each case the comparisons are for the LSBs of
503
+// Index and leaf indexes, according to the leafs level.
504
+//
505
+// 1. If Index is GREATER than the last (highest) index in the leaf
506
+// (maxindex), return success, Index is empty. (Remember, Index is known
507
+// to be in the leafs expanse.)
508
+//
509
+// 2. If Index is EQUAL to maxindex: If maxindex is not at the edge of the
510
+// leafs expanse, increment Index and return success, there is an empty
511
+// Index one higher than any in the leaf; otherwise restart with Index
512
+// reset to the upper edge of the leafs expanse. Note: This might cause
513
+// an extra cache line fill, but this is OK for repeatedly-called search
514
+// code, and it saves CPU time.
515
+//
516
+// 3. If Index is LESS than maxindex, check for "dense to end of leaf":
517
+// Subtract Index from maxindex, and back up that many slots in the leaf.
518
+// If the resulting offset is not before the start of the leaf then compare
519
+// the index at this offset (baseindex) with Index:
520
+//
521
+// 3a. If GREATER, the leaf must be corrupt, since indexes are sorted and
522
+// there are no duplicates.
523
+//
524
+// 3b. If EQUAL, the leaf is "dense" from Index to maxindex, meaning there is
525
+// no reason to search it. "Slide right" to the high end of the leaf
526
+// (modify Index to maxindex) and continue with step 2 above.
527
+//
528
+// 3c. If LESS, continue with step 4.
529
+//
530
+// 4. If the offset based on maxindex minus Index falls BEFORE the start of
531
+// the leaf, or if, per 3c above, baseindex is LESS than Index, the leaf is
532
+// guaranteed "not dense to the end" and a usable empty Index must exist.
533
+// This supports a more efficient search loop. Start at the FIRST index in
534
+// the leaf, or one BEYOND baseindex, respectively, and search the leaf as
535
+// follows, comparing each current index (currindex) with Index:
536
+//
537
+// 4a. If LESS, keep going to next index. Note: This is certain to terminate
538
+// because maxindex is known to be greater than Index, hence the loop can
539
+// be small and fast.
540
+//
541
+// 4b. If EQUAL, loop and increment Index until finding currindex greater than
542
+// Index, and return success with the modified Index.
543
+//
544
+// 4c. If GREATER, return success, Index (unmodified) is empty.
545
+//
546
+// Note: These are macros rather than functions for speed.
547
+
548
+#ifdef JUDYPREV
549
+
550
+#define JSLE_EVEN(Addr,Pop0,cDigits,LeafType) \
551
+ { \
552
+ LeafType * PjllLSB = (LeafType *) (Addr); \
553
+ LeafType IndexLSB = Index; /* auto-masking */ \
554
+ \
555
+ /* Index before or at start of leaf: */ \
556
+ \
557
+ if (*PjllLSB >= IndexLSB) /* no need to search */ \
558
+ { \
559
+ if (*PjllLSB > IndexLSB) RET_SUCCESS; /* Index empty */ \
560
+ LEAF_EDGE(*PjllLSB, cDigits); \
561
+ } \
562
+ \
563
+ /* Index in or after leaf: */ \
564
+ \
565
+ offset = IndexLSB - *PjllLSB; /* tentative offset */ \
566
+ if (offset <= (Pop0)) /* can check density */ \
567
+ { \
568
+ PjllLSB += offset; /* move to slot */ \
569
+ \
570
+ if (*PjllLSB <= IndexLSB) /* dense or corrupt */ \
571
+ { \
572
+ if (*PjllLSB == IndexLSB) /* dense, check edge */ \
573
+ LEAF_EDGE_SET(PjllLSB[-offset], cDigits); \
574
+ RET_CORRUPT; \
575
+ } \
576
+ --PjllLSB; /* not dense, start at previous */ \
577
+ } \
578
+ else PjllLSB = ((LeafType *) (Addr)) + (Pop0); /* start at max */ \
579
+ \
580
+ LEAF_HOLE_EVEN(cDigits, PjllLSB, IndexLSB); \
581
+ }
582
+
583
+// JSLE_ODD is completely different from JSLE_EVEN because its important to
584
+// minimize copying odd indexes to compare them (see 4.14). Furthermore, a
585
+// very complex version (4.17, but abandoned before fully debugged) that
586
+// avoided calling j__udySearchLeaf*() ran twice as fast as 4.14, but still
587
+// half as fast as SearchValid. Doug suggested that to minimize complexity and
588
+// share common code we should use j__udySearchLeaf*() for the initial search
589
+// to establish if Index is empty, which should be common. If Index is valid
590
+// in a leaf or immediate indexes, odds are good that an empty Index is nearby,
591
+// so for simplicity just use a *COPY* function to linearly search the
592
+// remainder.
593
+//
594
+// TBD: Pathological case? Average performance should be good, but worst-case
595
+// might suffer. When Search says the initial Index is valid, so a linear
596
+// copy-and-compare is begun, if the caller builds fairly large leaves with
597
+// dense clusters AND frequently does a SearchEmpty at one end of such a
598
+// cluster, performance wont be very good. Might a dense-check help? This
599
+// means checking offset against the index at offset, and then against the
600
+// first/last index in the leaf. We doubt the pathological case will appear
601
+// much in real applications because they will probably alternate SearchValid
602
+// and SearchEmpty calls.
603
+
604
+#define JSLE_ODD(cDigits,Pjll,Pop0,Search,Copy) \
605
+ { \
606
+ Word_t IndexLSB; /* least bytes only */ \
607
+ Word_t IndexFound; /* in leaf */ \
608
+ \
609
+ if ((offset = Search(Pjll, (Pop0) + 1, Index)) < 0) \
610
+ RET_SUCCESS; /* Index is empty */ \
611
+ \
612
+ IndexLSB = JU_LEASTBYTES(Index, cDigits); \
613
+ offset *= (cDigits); \
614
+ \
615
+ while ((offset -= (cDigits)) >= 0) \
616
+ { /* skip until empty or start */ \
617
+ Copy(IndexFound, ((uint8_t *) (Pjll)) + offset); \
618
+ if (IndexFound != (--IndexLSB)) /* found an empty */ \
619
+ { JU_SETDIGITS(Index, IndexLSB, cDigits); RET_SUCCESS; }\
620
+ } \
621
+ LEAF_EDGE_SET(IndexLSB, cDigits); \
622
+ }
623
+
624
+#else // JUDYNEXT
625
+
626
+#define JSLE_EVEN(Addr,Pop0,cDigits,LeafType) \
627
+ { \
628
+ LeafType * PjllLSB = ((LeafType *) (Addr)) + (Pop0); \
629
+ LeafType IndexLSB = Index; /* auto-masking */ \
630
+ \
631
+ /* Index at or after end of leaf: */ \
632
+ \
633
+ if (*PjllLSB <= IndexLSB) /* no need to search */ \
634
+ { \
635
+ if (*PjllLSB < IndexLSB) RET_SUCCESS; /* Index empty */\
636
+ LEAF_EDGE(*PjllLSB, cDigits); \
637
+ } \
638
+ \
639
+ /* Index before or in leaf: */ \
640
+ \
641
+ offset = *PjllLSB - IndexLSB; /* tentative offset */ \
642
+ if (offset <= (Pop0)) /* can check density */ \
643
+ { \
644
+ PjllLSB -= offset; /* move to slot */ \
645
+ \
646
+ if (*PjllLSB >= IndexLSB) /* dense or corrupt */ \
647
+ { \
648
+ if (*PjllLSB == IndexLSB) /* dense, check edge */ \
649
+ LEAF_EDGE_SET(PjllLSB[offset], cDigits); \
650
+ RET_CORRUPT; \
651
+ } \
652
+ ++PjllLSB; /* not dense, start at next */ \
653
+ } \
654
+ else PjllLSB = (LeafType *) (Addr); /* start at minimum */ \
655
+ \
656
+ LEAF_HOLE_EVEN(cDigits, PjllLSB, IndexLSB); \
657
+ }
658
+
659
+#define JSLE_ODD(cDigits,Pjll,Pop0,Search,Copy) \
660
+ { \
661
+ Word_t IndexLSB; /* least bytes only */ \
662
+ Word_t IndexFound; /* in leaf */ \
663
+ int offsetmax; /* in bytes */ \
664
+ \
665
+ if ((offset = Search(Pjll, (Pop0) + 1, Index)) < 0) \
666
+ RET_SUCCESS; /* Index is empty */ \
667
+ \
668
+ IndexLSB = JU_LEASTBYTES(Index, cDigits); \
669
+ offset *= (cDigits); \
670
+ offsetmax = (Pop0) * (cDigits); /* single multiply */ \
671
+ \
672
+ while ((offset += (cDigits)) <= offsetmax) \
673
+ { /* skip until empty or end */ \
674
+ Copy(IndexFound, ((uint8_t *) (Pjll)) + offset); \
675
+ if (IndexFound != (++IndexLSB)) /* found an empty */ \
676
+ { JU_SETDIGITS(Index, IndexLSB, cDigits); RET_SUCCESS; } \
677
+ } \
678
+ LEAF_EDGE_SET(IndexLSB, cDigits); \
679
+ }
680
+
681
+#endif // JUDYNEXT
682
+
683
+// Note: Immediate indexes never fill a single index group, so for odd index
684
+// sizes, save time by calling JSLE_ODD_IMM instead of JSLE_ODD.
685
+
686
+#define j__udySearchLeafEmpty1(Addr,Pop0) \
687
+ JSLE_EVEN(Addr, Pop0, 1, uint8_t)
688
+
689
+#define j__udySearchLeafEmpty2(Addr,Pop0) \
690
+ JSLE_EVEN(Addr, Pop0, 2, uint16_t)
691
+
692
+#define j__udySearchLeafEmpty3(Addr,Pop0) \
693
+ JSLE_ODD(3, Addr, Pop0, j__udySearchLeaf3, JU_COPY3_PINDEX_TO_LONG)
694
+
695
+#ifndef JU_64BIT
696
+
697
+#define j__udySearchLeafEmptyL(Addr,Pop0) \
698
+ JSLE_EVEN(Addr, Pop0, 4, Word_t)
699
+
700
+#else
701
+
702
+#define j__udySearchLeafEmpty4(Addr,Pop0) \
703
+ JSLE_EVEN(Addr, Pop0, 4, uint32_t)
704
+
705
+#define j__udySearchLeafEmpty5(Addr,Pop0) \
706
+ JSLE_ODD(5, Addr, Pop0, j__udySearchLeaf5, JU_COPY5_PINDEX_TO_LONG)
707
+
708
+#define j__udySearchLeafEmpty6(Addr,Pop0) \
709
+ JSLE_ODD(6, Addr, Pop0, j__udySearchLeaf6, JU_COPY6_PINDEX_TO_LONG)
710
+
711
+#define j__udySearchLeafEmpty7(Addr,Pop0) \
712
+ JSLE_ODD(7, Addr, Pop0, j__udySearchLeaf7, JU_COPY7_PINDEX_TO_LONG)
713
+
714
+#define j__udySearchLeafEmptyL(Addr,Pop0) \
715
+ JSLE_EVEN(Addr, Pop0, 8, Word_t)
716
+
717
+#endif // JU_64BIT
718
+
719
+
720
+// ----------------------------------------------------------------------------
721
+// START OF CODE:
722
+//
723
+// CHECK FOR SHORTCUTS:
724
+//
725
+// Error out if PIndex is null.
726
+
727
+ if (PIndex == (PWord_t) NULL)
728
+ {
729
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
730
+ return(JERRI);
731
+ }
732
+
733
+ Index = *PIndex; // fast local copy.
734
+
735
+// Set and pre-decrement/increment Index, watching for underflow/overflow:
736
+//
737
+// An out-of-bounds Index means failure: No previous/next empty index.
738
+
739
+SMGetRestart: // return here with revised Index.
740
+
741
+#ifdef JUDYPREV
742
+ if (Index-- == 0) return(0);
743
+#else
744
+ if (++Index == 0) return(0);
745
+#endif
746
+
747
+// An empty array with an in-bounds (not underflowed/overflowed) Index means
748
+// success:
749
+//
750
+// Note: This check is redundant after restarting at SMGetRestart, but should
751
+// take insignificant time.
752
+
753
+ if (PArray == (Pvoid_t) NULL) RET_SUCCESS;
754
+
755
+// ----------------------------------------------------------------------------
756
+// ROOT-LEVEL LEAF that starts with a Pop0 word; just look within the leaf:
757
+//
758
+// If Index is not in the leaf, return success; otherwise return the first
759
+// empty Index, if any, below/above where it would belong.
760
+
761
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
762
+ {
763
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
764
+ pop0 = Pjlw[0];
765
+
766
+#ifdef JUDY1
767
+ if (pop0 == 0) // special case.
768
+ {
769
+#ifdef JUDYPREV
770
+ if ((Index != Pjlw[1]) || (Index-- != 0)) RET_SUCCESS;
771
+#else
772
+ if ((Index != Pjlw[1]) || (++Index != 0)) RET_SUCCESS;
773
+#endif
774
+ return(0); // no previous/next empty index.
775
+ }
776
+#endif // JUDY1
777
+
778
+ j__udySearchLeafEmptyL(Pjlw + 1, pop0);
779
+
780
+// No return -- thanks ALAN
781
+
782
+ }
783
+ else
784
+
785
+// ----------------------------------------------------------------------------
786
+// HANDLE JRP Branch:
787
+//
788
+// For JRP branches, traverse the JPM; handle LEAFW
789
+// directly; but look for the most common cases first.
790
+
791
+ {
792
+ Pjpm_t Pjpm = P_JPM(PArray);
793
+ Pjp = &(Pjpm->jpm_JP);
794
+
795
+// goto SMGetContinue;
796
+ }
797
+
798
+
799
+// ============================================================================
800
+// STATE MACHINE -- GET INDEX:
801
+//
802
+// Search for Index (already decremented/incremented so as to be an inclusive
803
+// search). If not found (empty index), return success. Otherwise do a
804
+// previous/next search, and if successful modify Index to the empty index
805
+// found. See function header comments.
806
+//
807
+// ENTRY: Pjp points to next JP to interpret, whose Decode bytes have not yet
808
+// been checked.
809
+//
810
+// Note: Check Decode bytes at the start of each loop, not after looking up a
811
+// new JP, so its easy to do constant shifts/masks.
812
+//
813
+// EXIT: Return, or branch to SMGetRestart with modified Index, or branch to
814
+// SMGetContinue with a modified Pjp, as described elsewhere.
815
+//
816
+// WARNING: For run-time efficiency the following cases replicate code with
817
+// varying constants, rather than using common code with variable values!
818
+
819
+SMGetContinue: // return here for next branch/leaf.
820
+
821
+#ifdef TRACEJPSE
822
+ JudyPrintJP(Pjp, "sf", __LINE__);
823
+#endif
824
+
825
+ switch (JU_JPTYPE(Pjp))
826
+ {
827
+
828
+
829
+// ----------------------------------------------------------------------------
830
+// LINEAR BRANCH:
831
+//
832
+// Check Decode bytes, if any, in the current JP, then search for a JP for the
833
+// next digit in Index.
834
+
835
+ case cJU_JPBRANCH_L2: CHECKDCD(2); SMPREPB2(SMBranchL);
836
+ case cJU_JPBRANCH_L3: CHECKDCD(3); SMPREPB3(SMBranchL);
837
+#ifdef JU_64BIT
838
+ case cJU_JPBRANCH_L4: CHECKDCD(4); SMPREPB4(SMBranchL);
839
+ case cJU_JPBRANCH_L5: CHECKDCD(5); SMPREPB5(SMBranchL);
840
+ case cJU_JPBRANCH_L6: CHECKDCD(6); SMPREPB6(SMBranchL);
841
+ case cJU_JPBRANCH_L7: CHECKDCD(7); SMPREPB7(SMBranchL);
842
+#endif
843
+ case cJU_JPBRANCH_L: SMPREPBL(SMBranchL);
844
+
845
+// Common code (state-independent) for all cases of linear branches:
846
+
847
+SMBranchL:
848
+ Pjbl = P_JBL(Pjp->jp_Addr);
849
+
850
+// First, check if Indexs expanse (digit) is below/above the first/last
851
+// populated expanse in the BranchL, in which case Index is empty; otherwise
852
+// find the offset of the lowest/highest populated expanse at or above/below
853
+// digit, if any:
854
+//
855
+// Note: The for-loop is guaranteed to exit eventually because the first/last
856
+// expanse is known to be a terminator.
857
+//
858
+// Note: Cannot use j__udySearchLeaf*Empty1() here because it only applies to
859
+// leaves and does not know about partial versus full JPs, unlike the use of
860
+// j__udySearchLeaf1() for BranchLs in SearchValid code. Also, since linear
861
+// leaf expanse lists are small, dont waste time calling j__udySearchLeaf1(),
862
+// just scan the expanse list.
863
+
864
+#ifdef JUDYPREV
865
+ if ((Pjbl->jbl_Expanse[0]) > digit) RET_SUCCESS;
866
+
867
+ for (offset = (Pjbl->jbl_NumJPs) - 1; /* null */; --offset)
868
+#else
869
+ if ((Pjbl->jbl_Expanse[(Pjbl->jbl_NumJPs) - 1]) < digit)
870
+ RET_SUCCESS;
871
+
872
+ for (offset = 0; /* null */; ++offset)
873
+#endif
874
+ {
875
+
876
+// Too low/high, keep going; or too high/low, meaning the loop passed a hole
877
+// and the initial Index is empty:
878
+
879
+#ifdef JUDYPREV
880
+ if ((Pjbl->jbl_Expanse[offset]) > digit) continue;
881
+ if ((Pjbl->jbl_Expanse[offset]) < digit) RET_SUCCESS;
882
+#else
883
+ if ((Pjbl->jbl_Expanse[offset]) < digit) continue;
884
+ if ((Pjbl->jbl_Expanse[offset]) > digit) RET_SUCCESS;
885
+#endif
886
+
887
+// Found expanse matching digit; if its not full, traverse through it:
888
+
889
+ if (! JPFULL((Pjbl->jbl_jp) + offset))
890
+ {
891
+ Pjp = (Pjbl->jbl_jp) + offset;
892
+ goto SMGetContinue;
893
+ }
894
+
895
+// Common code: While searching for a lower/higher hole or a non-full JP, upon
896
+// finding a lower/higher hole, adjust Index using the revised digit and
897
+// return; or upon finding a consecutive lower/higher expanse, if the expanses
898
+// JP is non-full, modify Index and traverse through the JP:
899
+
900
+#define BRANCHL_CHECK(OpIncDec,OpLeastDigits,Digit,Digits) \
901
+ { \
902
+ if ((Pjbl->jbl_Expanse[offset]) != OpIncDec digit) \
903
+ SET_AND_RETURN(OpLeastDigits, Digit, Digits); \
904
+ \
905
+ if (! JPFULL((Pjbl->jbl_jp) + offset)) \
906
+ { \
907
+ Pjp = (Pjbl->jbl_jp) + offset; \
908
+ SET_AND_CONTINUE(OpLeastDigits, Digit, Digits); \
909
+ } \
910
+ }
911
+
912
+// BranchL primary dead end: Expanse matching Index/digit is full (rare except
913
+// for dense/sequential indexes):
914
+//
915
+// Search for a lower/higher hole, a non-full JP, or the end of the expanse
916
+// list, while decrementing/incrementing digit.
917
+
918
+#ifdef JUDYPREV
919
+ while (--offset >= 0)
920
+ BRANCHL_CHECK(--, SETLEASTDIGITS_D, digit, digits)
921
+#else
922
+ while (++offset < Pjbl->jbl_NumJPs)
923
+ BRANCHL_CHECK(++, CLEARLEASTDIGITS_D, digit, digits)
924
+#endif
925
+
926
+// Passed end of BranchL expanse list after finding a matching but full
927
+// expanse:
928
+//
929
+// Digit now matches the lowest/highest expanse, which is a full expanse; if
930
+// digit is at the end of BranchLs expanse (no hole before/after), break out
931
+// of the loop; otherwise modify Index to the next lower/higher digit and
932
+// return success:
933
+
934
+#ifdef JUDYPREV
935
+ if (digit == 0) break;
936
+ --digit; SET_AND_RETURN(SETLEASTDIGITS_D, digit, digits);
937
+#else
938
+ if (digit == JU_LEASTBYTES(cJU_ALLONES, 1)) break;
939
+ ++digit; SET_AND_RETURN(CLEARLEASTDIGITS_D, digit, digits);
940
+#endif
941
+ } // for-loop
942
+
943
+// BranchL secondary dead end, no non-full previous/next JP:
944
+
945
+ SMRESTART(digits);
946
+
947
+
948
+// ----------------------------------------------------------------------------
949
+// BITMAP BRANCH:
950
+//
951
+// Check Decode bytes, if any, in the current JP, then search for a JP for the
952
+// next digit in Index.
953
+
954
+ case cJU_JPBRANCH_B2: CHECKDCD(2); SMPREPB2(SMBranchB);
955
+ case cJU_JPBRANCH_B3: CHECKDCD(3); SMPREPB3(SMBranchB);
956
+#ifdef JU_64BIT
957
+ case cJU_JPBRANCH_B4: CHECKDCD(4); SMPREPB4(SMBranchB);
958
+ case cJU_JPBRANCH_B5: CHECKDCD(5); SMPREPB5(SMBranchB);
959
+ case cJU_JPBRANCH_B6: CHECKDCD(6); SMPREPB6(SMBranchB);
960
+ case cJU_JPBRANCH_B7: CHECKDCD(7); SMPREPB7(SMBranchB);
961
+#endif
962
+ case cJU_JPBRANCH_B: SMPREPBL(SMBranchB);
963
+
964
+// Common code (state-independent) for all cases of bitmap branches:
965
+
966
+SMBranchB:
967
+ Pjbb = P_JBB(Pjp->jp_Addr);
968
+
969
+// Locate the digits JP in the subexpanse list, if present:
970
+
971
+ subexp = digit / cJU_BITSPERSUBEXPB;
972
+ assert(subexp < cJU_NUMSUBEXPB); // falls in expected range.
973
+ bitposmaskB = JU_BITPOSMASKB(digit);
974
+
975
+// Absent JP = no JP matches current digit in Index:
976
+
977
+// if (! JU_BITMAPTESTB(Pjbb, digit)) // slower.
978
+ if (! (JU_JBB_BITMAP(Pjbb, subexp) & bitposmaskB)) // faster.
979
+ RET_SUCCESS;
980
+
981
+// Non-full JP matches current digit in Index:
982
+//
983
+// Iterate to the subsidiary non-full JP.
984
+
985
+ offset = SEARCHBITMAPB(JU_JBB_BITMAP(Pjbb, subexp), digit,
986
+ bitposmaskB);
987
+ // not negative since at least one bit is set:
988
+ assert(offset >= 0);
989
+ assert(offset < (int) cJU_BITSPERSUBEXPB);
990
+
991
+// Watch for null JP subarray pointer with non-null bitmap (a corruption):
992
+
993
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp)))
994
+ == (Pjp_t) NULL) RET_CORRUPT;
995
+
996
+ Pjp += offset;
997
+ if (! JPFULL(Pjp)) goto SMGetContinue;
998
+
999
+// BranchB primary dead end:
1000
+//
1001
+// Upon hitting a full JP in a BranchB for the next digit in Index, search
1002
+// sideways for a previous/next absent JP (unset bit) or non-full JP (set bit
1003
+// with non-full JP); first in the current bitmap subexpanse, then in
1004
+// lower/higher subexpanses. Upon entry, Pjp points to a known-unusable JP,
1005
+// ready to decrement/increment.
1006
+//
1007
+// Note: The preceding code is separate from this loop because Index does not
1008
+// need revising (see SET_AND_*()) if the initial index is an empty index.
1009
+//
1010
+// TBD: For speed, shift bitposmaskB instead of using JU_BITMAPTESTB or
1011
+// JU_BITPOSMASKB, but this shift has knowledge of bit order that really should
1012
+// be encapsulated in a header file.
1013
+
1014
+#define BRANCHB_CHECKBIT(OpLeastDigits) \
1015
+ if (! (JU_JBB_BITMAP(Pjbb, subexp) & bitposmaskB)) /* absent JP */ \
1016
+ SET_AND_RETURN(OpLeastDigits, digit, digits)
1017
+
1018
+#define BRANCHB_CHECKJPFULL(OpLeastDigits) \
1019
+ if (! JPFULL(Pjp)) \
1020
+ SET_AND_CONTINUE(OpLeastDigits, digit, digits)
1021
+
1022
+#define BRANCHB_STARTSUBEXP(OpLeastDigits) \
1023
+ if (! JU_JBB_BITMAP(Pjbb, subexp)) /* empty subexpanse, shortcut */ \
1024
+ SET_AND_RETURN(OpLeastDigits, digit, digits) \
1025
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL) RET_CORRUPT
1026
+
1027
+#ifdef JUDYPREV
1028
+
1029
+ --digit; // skip initial digit.
1030
+ bitposmaskB >>= 1; // see TBD above.
1031
+
1032
+BranchBNextSubexp: // return here to check next bitmap subexpanse.
1033
+
1034
+ while (bitposmaskB) // more bits to check in subexp.
1035
+ {
1036
+ BRANCHB_CHECKBIT(SETLEASTDIGITS_D);
1037
+ --Pjp; // previous in subarray.
1038
+ BRANCHB_CHECKJPFULL(SETLEASTDIGITS_D);
1039
+ assert(digit >= 0);
1040
+ --digit;
1041
+ bitposmaskB >>= 1;
1042
+ }
1043
+
1044
+ if (subexp-- > 0) // more subexpanses.
1045
+ {
1046
+ BRANCHB_STARTSUBEXP(SETLEASTDIGITS_D);
1047
+ Pjp += SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp)) + 1;
1048
+ bitposmaskB = (1U << (cJU_BITSPERSUBEXPB - 1));
1049
+ goto BranchBNextSubexp;
1050
+ }
1051
+
1052
+#else // JUDYNEXT
1053
+
1054
+ ++digit; // skip initial digit.
1055
+ bitposmaskB <<= 1; // note: BITMAPB_t.
1056
+
1057
+BranchBNextSubexp: // return here to check next bitmap subexpanse.
1058
+
1059
+ while (bitposmaskB) // more bits to check in subexp.
1060
+ {
1061
+ BRANCHB_CHECKBIT(CLEARLEASTDIGITS_D);
1062
+ ++Pjp; // previous in subarray.
1063
+ BRANCHB_CHECKJPFULL(CLEARLEASTDIGITS_D);
1064
+ assert(digit < cJU_SUBEXPPERSTATE);
1065
+ ++digit;
1066
+ bitposmaskB <<= 1; // note: BITMAPB_t.
1067
+ }
1068
+
1069
+ if (++subexp < cJU_NUMSUBEXPB) // more subexpanses.
1070
+ {
1071
+ BRANCHB_STARTSUBEXP(CLEARLEASTDIGITS_D);
1072
+ --Pjp; // pre-decrement.
1073
+ bitposmaskB = 1;
1074
+ goto BranchBNextSubexp;
1075
+ }
1076
+
1077
+#endif // JUDYNEXT
1078
+
1079
+// BranchB secondary dead end, no non-full previous/next JP:
1080
+
1081
+ SMRESTART(digits);
1082
+
1083
+
1084
+// ----------------------------------------------------------------------------
1085
+// UNCOMPRESSED BRANCH:
1086
+//
1087
+// Check Decode bytes, if any, in the current JP, then search for a JP for the
1088
+// next digit in Index.
1089
+
1090
+ case cJU_JPBRANCH_U2: CHECKDCD(2); SMPREPB2(SMBranchU);
1091
+ case cJU_JPBRANCH_U3: CHECKDCD(3); SMPREPB3(SMBranchU);
1092
+#ifdef JU_64BIT
1093
+ case cJU_JPBRANCH_U4: CHECKDCD(4); SMPREPB4(SMBranchU);
1094
+ case cJU_JPBRANCH_U5: CHECKDCD(5); SMPREPB5(SMBranchU);
1095
+ case cJU_JPBRANCH_U6: CHECKDCD(6); SMPREPB6(SMBranchU);
1096
+ case cJU_JPBRANCH_U7: CHECKDCD(7); SMPREPB7(SMBranchU);
1097
+#endif
1098
+ case cJU_JPBRANCH_U: SMPREPBL(SMBranchU);
1099
+
1100
+// Common code (state-independent) for all cases of uncompressed branches:
1101
+
1102
+SMBranchU:
1103
+ Pjbu = P_JBU(Pjp->jp_Addr);
1104
+ Pjp = (Pjbu->jbu_jp) + digit;
1105
+
1106
+// Absent JP = null JP for current digit in Index:
1107
+
1108
+ if (JPNULL(JU_JPTYPE(Pjp))) RET_SUCCESS;
1109
+
1110
+// Non-full JP matches current digit in Index:
1111
+//
1112
+// Iterate to the subsidiary JP.
1113
+
1114
+ if (! JPFULL(Pjp)) goto SMGetContinue;
1115
+
1116
+// BranchU primary dead end:
1117
+//
1118
+// Upon hitting a full JP in a BranchU for the next digit in Index, search
1119
+// sideways for a previous/next null or non-full JP. BRANCHU_CHECKJP() is
1120
+// shorthand for common code.
1121
+//
1122
+// Note: The preceding code is separate from this loop because Index does not
1123
+// need revising (see SET_AND_*()) if the initial index is an empty index.
1124
+
1125
+#define BRANCHU_CHECKJP(OpIncDec,OpLeastDigits) \
1126
+ { \
1127
+ OpIncDec Pjp; \
1128
+ \
1129
+ if (JPNULL(JU_JPTYPE(Pjp))) \
1130
+ SET_AND_RETURN(OpLeastDigits, digit, digits) \
1131
+ \
1132
+ if (! JPFULL(Pjp)) \
1133
+ SET_AND_CONTINUE(OpLeastDigits, digit, digits) \
1134
+ }
1135
+
1136
+#ifdef JUDYPREV
1137
+ while (digit-- > 0)
1138
+ BRANCHU_CHECKJP(--, SETLEASTDIGITS_D);
1139
+#else
1140
+ while (++digit < cJU_BRANCHUNUMJPS)
1141
+ BRANCHU_CHECKJP(++, CLEARLEASTDIGITS_D);
1142
+#endif
1143
+
1144
+// BranchU secondary dead end, no non-full previous/next JP:
1145
+
1146
+ SMRESTART(digits);
1147
+
1148
+
1149
+// ----------------------------------------------------------------------------
1150
+// LINEAR LEAF:
1151
+//
1152
+// Check Decode bytes, if any, in the current JP, then search the leaf for the
1153
+// previous/next empty index starting at Index. Primary leaf dead end is
1154
+// hidden within j__udySearchLeaf*Empty*(). In case of secondary leaf dead
1155
+// end, restart at the top of the tree.
1156
+//
1157
+// Note: Pword is the name known to GET*; think of it as Pjlw.
1158
+
1159
+#define SMLEAFL(cDigits,Func) \
1160
+ Pword = (PWord_t) P_JLW(Pjp->jp_Addr); \
1161
+ pop0 = JU_JPLEAF_POP0(Pjp); \
1162
+ Func(Pword, pop0)
1163
+
1164
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
1165
+ case cJU_JPLEAF1: CHECKDCD(1); SMLEAFL(1, j__udySearchLeafEmpty1);
1166
+#endif
1167
+ case cJU_JPLEAF2: CHECKDCD(2); SMLEAFL(2, j__udySearchLeafEmpty2);
1168
+ case cJU_JPLEAF3: CHECKDCD(3); SMLEAFL(3, j__udySearchLeafEmpty3);
1169
+
1170
+#ifdef JU_64BIT
1171
+ case cJU_JPLEAF4: CHECKDCD(4); SMLEAFL(4, j__udySearchLeafEmpty4);
1172
+ case cJU_JPLEAF5: CHECKDCD(5); SMLEAFL(5, j__udySearchLeafEmpty5);
1173
+ case cJU_JPLEAF6: CHECKDCD(6); SMLEAFL(6, j__udySearchLeafEmpty6);
1174
+ case cJU_JPLEAF7: CHECKDCD(7); SMLEAFL(7, j__udySearchLeafEmpty7);
1175
+#endif
1176
+
1177
+
1178
+// ----------------------------------------------------------------------------
1179
+// BITMAP LEAF:
1180
+//
1181
+// Check Decode bytes, if any, in the current JP, then search the leaf for the
1182
+// previous/next empty index starting at Index.
1183
+
1184
+ case cJU_JPLEAF_B1:
1185
+
1186
+ CHECKDCD(1);
1187
+
1188
+ Pjlb = P_JLB(Pjp->jp_Addr);
1189
+ digit = JU_DIGITATSTATE(Index, 1);
1190
+ subexp = digit / cJU_BITSPERSUBEXPL;
1191
+ bitposmaskL = JU_BITPOSMASKL(digit);
1192
+ assert(subexp < cJU_NUMSUBEXPL); // falls in expected range.
1193
+
1194
+// Absent index = no index matches current digit in Index:
1195
+
1196
+// if (! JU_BITMAPTESTL(Pjlb, digit)) // slower.
1197
+ if (! (JU_JLB_BITMAP(Pjlb, subexp) & bitposmaskL)) // faster.
1198
+ RET_SUCCESS;
1199
+
1200
+// LeafB1 primary dead end:
1201
+//
1202
+// Upon hitting a valid (non-empty) index in a LeafB1 for the last digit in
1203
+// Index, search sideways for a previous/next absent index, first in the
1204
+// current bitmap subexpanse, then in lower/higher subexpanses.
1205
+// LEAFB1_CHECKBIT() is shorthand for common code to handle one bit in one
1206
+// bitmap subexpanse.
1207
+//
1208
+// Note: The preceding code is separate from this loop because Index does not
1209
+// need revising (see SET_AND_*()) if the initial index is an empty index.
1210
+//
1211
+// TBD: For speed, shift bitposmaskL instead of using JU_BITMAPTESTL or
1212
+// JU_BITPOSMASKL, but this shift has knowledge of bit order that really should
1213
+// be encapsulated in a header file.
1214
+
1215
+#define LEAFB1_CHECKBIT(OpLeastDigits) \
1216
+ if (! (JU_JLB_BITMAP(Pjlb, subexp) & bitposmaskL)) \
1217
+ SET_AND_RETURN(OpLeastDigits, digit, 1)
1218
+
1219
+#define LEAFB1_STARTSUBEXP(OpLeastDigits) \
1220
+ if (! JU_JLB_BITMAP(Pjlb, subexp)) /* empty subexp */ \
1221
+ SET_AND_RETURN(OpLeastDigits, digit, 1)
1222
+
1223
+#ifdef JUDYPREV
1224
+
1225
+ --digit; // skip initial digit.
1226
+ bitposmaskL >>= 1; // see TBD above.
1227
+
1228
+LeafB1NextSubexp: // return here to check next bitmap subexpanse.
1229
+
1230
+ while (bitposmaskL) // more bits to check in subexp.
1231
+ {
1232
+ LEAFB1_CHECKBIT(SETLEASTDIGITS_D);
1233
+ assert(digit >= 0);
1234
+ --digit;
1235
+ bitposmaskL >>= 1;
1236
+ }
1237
+
1238
+ if (subexp-- > 0) // more subexpanses.
1239
+ {
1240
+ LEAFB1_STARTSUBEXP(SETLEASTDIGITS_D);
1241
+ bitposmaskL = (1UL << (cJU_BITSPERSUBEXPL - 1));
1242
+ goto LeafB1NextSubexp;
1243
+ }
1244
+
1245
+#else // JUDYNEXT
1246
+
1247
+ ++digit; // skip initial digit.
1248
+ bitposmaskL <<= 1; // note: BITMAPL_t.
1249
+
1250
+LeafB1NextSubexp: // return here to check next bitmap subexpanse.
1251
+
1252
+ while (bitposmaskL) // more bits to check in subexp.
1253
+ {
1254
+ LEAFB1_CHECKBIT(CLEARLEASTDIGITS_D);
1255
+ assert(digit < cJU_SUBEXPPERSTATE);
1256
+ ++digit;
1257
+ bitposmaskL <<= 1; // note: BITMAPL_t.
1258
+ }
1259
+
1260
+ if (++subexp < cJU_NUMSUBEXPL) // more subexpanses.
1261
+ {
1262
+ LEAFB1_STARTSUBEXP(CLEARLEASTDIGITS_D);
1263
+ bitposmaskL = 1;
1264
+ goto LeafB1NextSubexp;
1265
+ }
1266
+
1267
+#endif // JUDYNEXT
1268
+
1269
+// LeafB1 secondary dead end, no empty index:
1270
+
1271
+ SMRESTART(1);
1272
+
1273
+
1274
+#ifdef JUDY1
1275
+// ----------------------------------------------------------------------------
1276
+// FULL POPULATION:
1277
+//
1278
+// If the Decode bytes do not match, Index is empty (without modification);
1279
+// otherwise restart.
1280
+
1281
+ case cJ1_JPFULLPOPU1:
1282
+
1283
+ CHECKDCD(1);
1284
+ SMRESTART(1);
1285
+#endif
1286
+
1287
+
1288
+// ----------------------------------------------------------------------------
1289
+// IMMEDIATE:
1290
+//
1291
+// Pop1 = 1 Immediate JPs:
1292
+//
1293
+// If Index is not in the immediate JP, return success; otherwise check if
1294
+// there is an empty index below/above the immediate JPs index, and if so,
1295
+// return success with modified Index, else restart.
1296
+//
1297
+// Note: Doug says its fast enough to calculate the index size (digits) in
1298
+// the following; no need to set it separately for each case.
1299
+
1300
+ case cJU_JPIMMED_1_01:
1301
+ case cJU_JPIMMED_2_01:
1302
+ case cJU_JPIMMED_3_01:
1303
+#ifdef JU_64BIT
1304
+ case cJU_JPIMMED_4_01:
1305
+ case cJU_JPIMMED_5_01:
1306
+ case cJU_JPIMMED_6_01:
1307
+ case cJU_JPIMMED_7_01:
1308
+#endif
1309
+ if (JU_JPDCDPOP0(Pjp) != JU_TRIMTODCDSIZE(Index)) RET_SUCCESS;
1310
+ digits = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_01 + 1;
1311
+ LEAF_EDGE(JU_LEASTBYTES(JU_JPDCDPOP0(Pjp), digits), digits);
1312
+
1313
+// Immediate JPs with Pop1 > 1:
1314
+
1315
+#define IMM_MULTI(Func,BaseJPType) \
1316
+ JUDY1CODE(Pword = (PWord_t) (Pjp->jp_1Index);) \
1317
+ JUDYLCODE(Pword = (PWord_t) (Pjp->jp_LIndex);) \
1318
+ Func(Pword, JU_JPTYPE(Pjp) - (BaseJPType) + 1)
1319
+
1320
+ case cJU_JPIMMED_1_02:
1321
+ case cJU_JPIMMED_1_03:
1322
+#if (defined(JUDY1) || defined(JU_64BIT))
1323
+ case cJU_JPIMMED_1_04:
1324
+ case cJU_JPIMMED_1_05:
1325
+ case cJU_JPIMMED_1_06:
1326
+ case cJU_JPIMMED_1_07:
1327
+#endif
1328
+#if (defined(JUDY1) && defined(JU_64BIT))
1329
+ case cJ1_JPIMMED_1_08:
1330
+ case cJ1_JPIMMED_1_09:
1331
+ case cJ1_JPIMMED_1_10:
1332
+ case cJ1_JPIMMED_1_11:
1333
+ case cJ1_JPIMMED_1_12:
1334
+ case cJ1_JPIMMED_1_13:
1335
+ case cJ1_JPIMMED_1_14:
1336
+ case cJ1_JPIMMED_1_15:
1337
+#endif
1338
+ IMM_MULTI(j__udySearchLeafEmpty1, cJU_JPIMMED_1_02);
1339
+
1340
+#if (defined(JUDY1) || defined(JU_64BIT))
1341
+ case cJU_JPIMMED_2_02:
1342
+ case cJU_JPIMMED_2_03:
1343
+#endif
1344
+#if (defined(JUDY1) && defined(JU_64BIT))
1345
+ case cJ1_JPIMMED_2_04:
1346
+ case cJ1_JPIMMED_2_05:
1347
+ case cJ1_JPIMMED_2_06:
1348
+ case cJ1_JPIMMED_2_07:
1349
+#endif
1350
+#if (defined(JUDY1) || defined(JU_64BIT))
1351
+ IMM_MULTI(j__udySearchLeafEmpty2, cJU_JPIMMED_2_02);
1352
+#endif
1353
+
1354
+#if (defined(JUDY1) || defined(JU_64BIT))
1355
+ case cJU_JPIMMED_3_02:
1356
+#endif
1357
+#if (defined(JUDY1) && defined(JU_64BIT))
1358
+ case cJ1_JPIMMED_3_03:
1359
+ case cJ1_JPIMMED_3_04:
1360
+ case cJ1_JPIMMED_3_05:
1361
+#endif
1362
+#if (defined(JUDY1) || defined(JU_64BIT))
1363
+ IMM_MULTI(j__udySearchLeafEmpty3, cJU_JPIMMED_3_02);
1364
+#endif
1365
+
1366
+#if (defined(JUDY1) && defined(JU_64BIT))
1367
+ case cJ1_JPIMMED_4_02:
1368
+ case cJ1_JPIMMED_4_03:
1369
+ IMM_MULTI(j__udySearchLeafEmpty4, cJ1_JPIMMED_4_02);
1370
+
1371
+ case cJ1_JPIMMED_5_02:
1372
+ case cJ1_JPIMMED_5_03:
1373
+ IMM_MULTI(j__udySearchLeafEmpty5, cJ1_JPIMMED_5_02);
1374
+
1375
+ case cJ1_JPIMMED_6_02:
1376
+ IMM_MULTI(j__udySearchLeafEmpty6, cJ1_JPIMMED_6_02);
1377
+
1378
+ case cJ1_JPIMMED_7_02:
1379
+ IMM_MULTI(j__udySearchLeafEmpty7, cJ1_JPIMMED_7_02);
1380
+#endif
1381
+
1382
+
1383
+// ----------------------------------------------------------------------------
1384
+// INVALID JP TYPE:
1385
+
1386
+ default: RET_CORRUPT;
1387
+
1388
+ } // SMGet switch.
1389
+
1390
+} // Judy1PrevEmpty() / Judy1NextEmpty() / JudyLPrevEmpty() / JudyLNextEmpty()
libnetdata/libjudy/src/JudyL/JudyLPrev.c
new
+1890
@@ -0,0 +1,1890 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.54 $ $Source: /judy/src/JudyCommon/JudyPrevNext.c $
19
+//
20
+// Judy*Prev() and Judy*Next() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// Compile with -DJUDYNEXT for the Judy*Next() function; otherwise defaults to
24
+// Judy*Prev().
25
+
26
+#if (! (defined(JUDY1) || defined(JUDYL)))
27
+#error: One of -DJUDY1 or -DJUDYL must be specified.
28
+#endif
29
+
30
+#ifndef JUDYNEXT
31
+#ifndef JUDYPREV
32
+#define JUDYPREV 1 // neither set => use default.
33
+#endif
34
+#endif
35
+
36
+#ifdef JUDY1
37
+#include "Judy1.h"
38
+#else
39
+#include "JudyL.h"
40
+#endif
41
+
42
+#include "JudyPrivate1L.h"
43
+
44
+
45
+// ****************************************************************************
46
+// J U D Y 1 P R E V
47
+// J U D Y 1 N E X T
48
+// J U D Y L P R E V
49
+// J U D Y L N E X T
50
+//
51
+// See the manual entry for the API.
52
+//
53
+// OVERVIEW OF Judy*Prev():
54
+//
55
+// Use a reentrant switch statement (state machine, SM1 = "get") to decode the
56
+// callers *PIndex-1, starting with the (PArray), through branches, if
57
+// any, down to an immediate or a leaf. Look for *PIndex-1 in that leaf, and
58
+// if found, return it.
59
+//
60
+// A dead end is either a branch that does not contain a JP for the appropriate
61
+// digit in *PIndex-1, or a leaf that does not contain the undecoded digits of
62
+// *PIndex-1. Upon reaching a dead end, backtrack through the leaf/branches
63
+// that were just traversed, using a list (history) of parent JPs that is built
64
+// while going forward in SM1Get. Start with the current leaf or branch. In a
65
+// backtracked leaf, look for an Index less than *PIndex-1. In each
66
+// backtracked branch, look "sideways" for the next JP, if any, lower than the
67
+// one for the digit (from *PIndex-1) that was previously decoded. While
68
+// backtracking, if a leaf has no previous Index or a branch has no lower JP,
69
+// go to its parent branch in turn. Upon reaching the JRP, return failure, "no
70
+// previous Index". The backtrack process is sufficiently different from
71
+// SM1Get to merit its own separate reentrant switch statement (SM2 =
72
+// "backtrack").
73
+//
74
+// While backtracking, upon finding a lower JP in a branch, there is certain to
75
+// be a "prev" Index under that JP (unless the Judy array is corrupt).
76
+// Traverse forward again, this time taking the last (highest, right-most) JP
77
+// in each branch, and the last (highest) Index upon reaching an immediate or a
78
+// leaf. This traversal is sufficiently different from SM1Get and SM2Backtrack
79
+// to merit its own separate reentrant switch statement (SM3 = "findlimit").
80
+//
81
+// "Decode" bytes in JPs complicate this process a little. In SM1Get, when a
82
+// JP is a narrow pointer, that is, when states are skipped (so the skipped
83
+// digits are stored in jp_DcdPopO), compare the relevant digits to the same
84
+// digits in *PIndex-1. If they are EQUAL, proceed in SM1Get as before. If
85
+// jp_DcdPopOs digits are GREATER, treat the JP as a dead end and proceed in
86
+// SM2Backtrack. If jp_DcdPopOs digits are LESS, treat the JP as if it had
87
+// just been found during a backtrack and proceed directly in SM3Findlimit.
88
+//
89
+// Note that Decode bytes can be ignored in SM3Findlimit; they dont matter.
90
+// Also note that in practice the Decode bytes are routinely compared with
91
+// *PIndex-1 because thats simpler and no slower than first testing for
92
+// narrowness.
93
+//
94
+// Decode bytes also make it unnecessary to construct the Index to return (the
95
+// revised *PIndex) during the search. This step is deferred until finding an
96
+// Index during backtrack or findlimit, before returning it. The first digit
97
+// of *PIndex is derived (saved) based on which JP is used in a JRP branch.
98
+// The remaining digits are obtained from the jp_DcdPopO field in the JP (if
99
+// any) above the immediate or leaf containing the found (prev) Index, plus the
100
+// remaining digit(s) in the immediate or leaf itself. In the case of a LEAFW,
101
+// the Index to return is found directly in the leaf.
102
+//
103
+// Note: Theoretically, as described above, upon reaching a dead end, SM1Get
104
+// passes control to SM2Backtrack to look sideways, even in a leaf. Actually
105
+// its a little more efficient for the SM1Get leaf cases to shortcut this and
106
+// take care of the sideways searches themselves. Hence the history list only
107
+// contains branch JPs, and SM2Backtrack only handles branches. In fact, even
108
+// the branch handling cases in SM1Get do some shortcutting (sideways
109
+// searching) to avoid pushing history and calling SM2Backtrack unnecessarily.
110
+//
111
+// Upon reaching an Index to return after backtracking, *PIndex must be
112
+// modified to the found Index. In principle this could be done by building
113
+// the Index from a saved rootdigit (in the top branch) plus the Dcd bytes from
114
+// the parent JP plus the appropriate Index bytes from the leaf. However,
115
+// Immediates are difficult because their parent JPs lack one (last) digit. So
116
+// instead just build the *PIndex to return "top down" while backtracking and
117
+// findlimiting.
118
+//
119
+// This function is written iteratively for speed, rather than recursively.
120
+//
121
+// CAVEATS:
122
+//
123
+// Why use a backtrack list (history stack), since it has finite size? The
124
+// size is small for Judy on both 32-bit and 64-bit systems, and a list (really
125
+// just an array) is fast to maintain and use. Other alternatives include
126
+// doing a lookahead (lookaside) in each branch while traversing forward
127
+// (decoding), and restarting from the top upon a dead end.
128
+//
129
+// A lookahead means noting the last branch traversed which contained a
130
+// non-null JP lower than the one specified by a digit in *PIndex-1, and
131
+// returning to that point for SM3Findlimit. This seems like a good idea, and
132
+// should be pretty cheap for linear and bitmap branches, but it could result
133
+// in up to 31 unnecessary additional cache line fills (in extreme cases) for
134
+// every uncompressed branch traversed. We have considered means of attaching
135
+// to or hiding within an uncompressed branch (in null JPs) a "cache line map"
136
+// or other structure, such as an offset to the next non-null JP, that would
137
+// speed this up, but it seems unnecessary merely to avoid having a
138
+// finite-length list (array). (If JudySL is ever made "native", the finite
139
+// list length will be an issue.)
140
+//
141
+// Restarting at the top of the Judy array after a dead end requires a careful
142
+// modification of *PIndex-1 to decrement the digit for the parent branch and
143
+// set the remaining lower digits to all 1s. This must be repeated each time a
144
+// parent branch contains another dead end, so even though it should all happen
145
+// in cache, the CPU time can be excessive. (For JudySL or an equivalent
146
+// "infinitely deep" Judy array, consider a hybrid of a large, finite,
147
+// "circular" list and a restart-at-top when the list is backtracked to
148
+// exhaustion.)
149
+//
150
+// Why search for *PIndex-1 instead of *PIndex during SM1Get? In rare
151
+// instances this prevents an unnecessary decode down the wrong path followed
152
+// by a backtrack; its pretty cheap to set up initially; and it means the
153
+// SM1Get machine can simply return if/when it finds that Index.
154
+//
155
+// TBD: Wed like to enhance this function to make successive searches faster.
156
+// This would require saving some previous state, including the previous Index
157
+// returned, and in which leaf it was found. If the next call is for the same
158
+// Index and the array has not been modified, start at the same leaf. This
159
+// should be much easier to implement since this is iterative rather than
160
+// recursive code.
161
+//
162
+// VARIATIONS FOR Judy*Next():
163
+//
164
+// The Judy*Next() code is nearly a perfect mirror of the Judy*Prev() code.
165
+// See the Judy*Prev() overview comments, and mentally switch the following:
166
+//
167
+// - "*PIndex-1" => "*PIndex+1"
168
+// - "less than" => "greater than"
169
+// - "lower" => "higher"
170
+// - "lowest" => "highest"
171
+// - "next-left" => "next-right"
172
+// - "right-most" => "left-most"
173
+//
174
+// Note: SM3Findlimit could be called SM3Findmax/SM3Findmin, but a common name
175
+// for both Prev and Next means many fewer ifdefs in this code.
176
+//
177
+// TBD: Currently this code traverses a JP whether its expanse is partially or
178
+// completely full (populated). For Judy1 (only), since there is no value area
179
+// needed, consider shortcutting to a "success" return upon encountering a full
180
+// JP in SM1Get (or even SM3Findlimit?) A full JP looks like this:
181
+//
182
+// (((JU_JPDCDPOP0(Pjp) ^ cJU_ALLONES) & cJU_POP0MASK(cLevel)) == 0)
183
+
184
+#ifdef JUDY1
185
+#ifdef JUDYPREV
186
+FUNCTION int Judy1Prev
187
+#else
188
+FUNCTION int Judy1Next
189
+#endif
190
+#else
191
+#ifdef JUDYPREV
192
+FUNCTION PPvoid_t JudyLPrev
193
+#else
194
+FUNCTION PPvoid_t JudyLNext
195
+#endif
196
+#endif
197
+ (
198
+ Pcvoid_t PArray, // Judy array to search.
199
+ Word_t * PIndex, // starting point and result.
200
+ PJError_t PJError // optional, for returning error info.
201
+ )
202
+{
203
+ Pjp_t Pjp, Pjp2; // current JPs.
204
+ Pjbl_t Pjbl; // Pjp->jp_Addr masked and cast to types:
205
+ Pjbb_t Pjbb;
206
+ Pjbu_t Pjbu;
207
+
208
+// Note: The following initialization is not strictly required but it makes
209
+// gcc -Wall happy because there is an "impossible" path from Immed handling to
210
+// SM1LeafLImm code that looks like Pjll might be used before set:
211
+
212
+ Pjll_t Pjll = (Pjll_t) NULL;
213
+ Word_t state; // current state in SM.
214
+ Word_t digit; // next digit to decode from Index.
215
+
216
+// Note: The following initialization is not strictly required but it makes
217
+// gcc -Wall happy because there is an "impossible" path from Immed handling to
218
+// SM1LeafLImm code (for JudyL & JudyPrev only) that looks like pop1 might be
219
+// used before set:
220
+
221
+#if (defined(JUDYL) && defined(JUDYPREV))
222
+ Word_t pop1 = 0; // in a leaf.
223
+#else
224
+ Word_t pop1; // in a leaf.
225
+#endif
226
+ int offset; // linear branch/leaf, from j__udySearchLeaf*().
227
+ int subexp; // subexpanse in a bitmap branch.
228
+ Word_t bitposmask; // bit in bitmap for Index.
229
+
230
+// History for SM2Backtrack:
231
+//
232
+// For a given histnum, APjphist[histnum] is a parent JP that points to a
233
+// branch, and Aoffhist[histnum] is the offset of the NEXT JP in the branch to
234
+// which the parent JP points. The meaning of Aoffhist[histnum] depends on the
235
+// type of branch to which the parent JP points:
236
+//
237
+// Linear: Offset of the next JP in the JP list.
238
+//
239
+// Bitmap: Which subexpanse, plus the offset of the next JP in the
240
+// subexpanses JP list (to avoid bit-counting again), plus for Judy*Next(),
241
+// hidden one byte to the left, which digit, because Judy*Next() also needs
242
+// this.
243
+//
244
+// Uncompressed: Digit, which is actually the offset of the JP in the branch.
245
+//
246
+// Note: Only branch JPs are stored in APjphist[] because, as explained
247
+// earlier, SM1Get shortcuts sideways searches in leaves (and even in branches
248
+// in some cases), so SM2Backtrack only handles branches.
249
+
250
+#define HISTNUMMAX cJU_ROOTSTATE // maximum branches traversable.
251
+ Pjp_t APjphist[HISTNUMMAX]; // list of branch JPs traversed.
252
+ int Aoffhist[HISTNUMMAX]; // list of next JP offsets; see above.
253
+ int histnum = 0; // number of JPs now in list.
254
+
255
+
256
+// ----------------------------------------------------------------------------
257
+// M A C R O S
258
+//
259
+// These are intended to make the code a bit more readable and less redundant.
260
+
261
+
262
+// "PUSH" AND "POP" Pjp AND offset ON HISTORY STACKS:
263
+//
264
+// Note: Ensure a corrupt Judy array does not overflow *hist[]. Meanwhile,
265
+// underflowing *hist[] simply means theres no more room to backtrack =>
266
+// "no previous/next Index".
267
+
268
+#define HISTPUSH(Pjp,Offset) \
269
+ APjphist[histnum] = (Pjp); \
270
+ Aoffhist[histnum] = (Offset); \
271
+ \
272
+ if (++histnum >= HISTNUMMAX) \
273
+ { \
274
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT) \
275
+ JUDY1CODE(return(JERRI );) \
276
+ JUDYLCODE(return(PPJERR);) \
277
+ }
278
+
279
+#define HISTPOP(Pjp,Offset) \
280
+ if ((histnum--) < 1) JU_RET_NOTFOUND; \
281
+ (Pjp) = APjphist[histnum]; \
282
+ (Offset) = Aoffhist[histnum]
283
+
284
+// How to pack/unpack Aoffhist[] values for bitmap branches:
285
+
286
+#ifdef JUDYPREV
287
+
288
+#define HISTPUSHBOFF(Subexp,Offset,Digit) \
289
+ (((Subexp) * cJU_BITSPERSUBEXPB) | (Offset))
290
+
291
+#define HISTPOPBOFF(Subexp,Offset,Digit) \
292
+ (Subexp) = (Offset) / cJU_BITSPERSUBEXPB; \
293
+ (Offset) %= cJU_BITSPERSUBEXPB
294
+#else
295
+
296
+#define HISTPUSHBOFF(Subexp,Offset,Digit) \
297
+ (((Digit) << cJU_BITSPERBYTE) \
298
+ | ((Subexp) * cJU_BITSPERSUBEXPB) | (Offset))
299
+
300
+#define HISTPOPBOFF(Subexp,Offset,Digit) \
301
+ (Digit) = (Offset) >> cJU_BITSPERBYTE; \
302
+ (Subexp) = ((Offset) & JU_LEASTBYTESMASK(1)) / cJU_BITSPERSUBEXPB; \
303
+ (Offset) %= cJU_BITSPERSUBEXPB
304
+#endif
305
+
306
+
307
+// CHECK FOR NULL JP:
308
+
309
+#define JPNULL(Type) (((Type) >= cJU_JPNULL1) && ((Type) <= cJU_JPNULLMAX))
310
+
311
+
312
+// SEARCH A BITMAP:
313
+//
314
+// This is a weak analog of j__udySearchLeaf*() for bitmaps. Return the actual
315
+// or next-left position, base 0, of Digit in the single uint32_t bitmap, also
316
+// given a Bitposmask for Digit.
317
+//
318
+// Unlike j__udySearchLeaf*(), the offset is not returned bit-complemented if
319
+// Digits bit is unset, because the caller can check the bitmap themselves to
320
+// determine that. Also, if Digits bit is unset, the returned offset is to
321
+// the next-left JP (including -1), not to the "ideal" position for the Index =
322
+// next-right JP.
323
+//
324
+// Shortcut and skip calling j__udyCountBits*() if the bitmap is full, in which
325
+// case (Digit % cJU_BITSPERSUBEXP*) itself is the base-0 offset.
326
+//
327
+// TBD for Judy*Next(): Should this return next-right instead of next-left?
328
+// That is, +1 from current value? Maybe not, if Digits bit IS set, +1 would
329
+// be wrong.
330
+
331
+#define SEARCHBITMAPB(Bitmap,Digit,Bitposmask) \
332
+ (((Bitmap) == cJU_FULLBITMAPB) ? (Digit % cJU_BITSPERSUBEXPB) : \
333
+ j__udyCountBitsB((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1)
334
+
335
+#define SEARCHBITMAPL(Bitmap,Digit,Bitposmask) \
336
+ (((Bitmap) == cJU_FULLBITMAPL) ? (Digit % cJU_BITSPERSUBEXPL) : \
337
+ j__udyCountBitsL((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1)
338
+
339
+#ifdef JUDYPREV
340
+// Equivalent to search for the highest offset in Bitmap:
341
+
342
+#define SEARCHBITMAPMAXB(Bitmap) \
343
+ (((Bitmap) == cJU_FULLBITMAPB) ? cJU_BITSPERSUBEXPB - 1 : \
344
+ j__udyCountBitsB(Bitmap) - 1)
345
+
346
+#define SEARCHBITMAPMAXL(Bitmap) \
347
+ (((Bitmap) == cJU_FULLBITMAPL) ? cJU_BITSPERSUBEXPL - 1 : \
348
+ j__udyCountBitsL(Bitmap) - 1)
349
+#endif
350
+
351
+
352
+// CHECK DECODE BYTES:
353
+//
354
+// Check Decode bytes in a JP against the equivalent portion of *PIndex. If
355
+// *PIndex is lower (for Judy*Prev()) or higher (for Judy*Next()), this JP is a
356
+// dead end (the same as if it had been absent in a linear or bitmap branch or
357
+// null in an uncompressed branch), enter SM2Backtrack; otherwise enter
358
+// SM3Findlimit to find the highest/lowest Index under this JP, as if the code
359
+// had already backtracked to this JP.
360
+
361
+#ifdef JUDYPREV
362
+#define CDcmp__ <
363
+#else
364
+#define CDcmp__ >
365
+#endif
366
+
367
+#define CHECKDCD(cState) \
368
+ if (JU_DCDNOTMATCHINDEX(*PIndex, Pjp, cState)) \
369
+ { \
370
+ if ((*PIndex & cJU_DCDMASK(cState)) \
371
+ CDcmp__(JU_JPDCDPOP0(Pjp) & cJU_DCDMASK(cState))) \
372
+ { \
373
+ goto SM2Backtrack; \
374
+ } \
375
+ goto SM3Findlimit; \
376
+ }
377
+
378
+
379
+// PREPARE TO HANDLE A LEAFW OR JRP BRANCH IN SM1:
380
+//
381
+// Extract a state-dependent digit from Index in a "constant" way, then jump to
382
+// common code for multiple cases.
383
+
384
+#define SM1PREPB(cState,Next) \
385
+ state = (cState); \
386
+ digit = JU_DIGITATSTATE(*PIndex, cState); \
387
+ goto Next
388
+
389
+
390
+// PREPARE TO HANDLE A LEAFW OR JRP BRANCH IN SM3:
391
+//
392
+// Optionally save Dcd bytes into *PIndex, then save state and jump to common
393
+// code for multiple cases.
394
+
395
+#define SM3PREPB_DCD(cState,Next) \
396
+ JU_SETDCD(*PIndex, Pjp, cState); \
397
+ SM3PREPB(cState,Next)
398
+
399
+#define SM3PREPB(cState,Next) state = (cState); goto Next
400
+
401
+
402
+// ----------------------------------------------------------------------------
403
+// CHECK FOR SHORTCUTS:
404
+//
405
+// Error out if PIndex is null. Execute JU_RET_NOTFOUND if the Judy array is
406
+// empty or *PIndex is already the minimum/maximum Index possible.
407
+//
408
+// Note: As documented, in case of failure *PIndex may be modified.
409
+
410
+ if (PIndex == (PWord_t) NULL)
411
+ {
412
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
413
+ JUDY1CODE(return(JERRI );)
414
+ JUDYLCODE(return(PPJERR);)
415
+ }
416
+
417
+#ifdef JUDYPREV
418
+ if ((PArray == (Pvoid_t) NULL) || ((*PIndex)-- == 0))
419
+#else
420
+ if ((PArray == (Pvoid_t) NULL) || ((*PIndex)++ == cJU_ALLONES))
421
+#endif
422
+ JU_RET_NOTFOUND;
423
+
424
+
425
+// HANDLE JRP:
426
+//
427
+// Before even entering SM1Get, check the JRP type. For JRP branches, traverse
428
+// the JPM; handle LEAFW leaves directly; but look for the most common cases
429
+// first.
430
+
431
+// ROOT-STATE LEAF that starts with a Pop0 word; just look within the leaf:
432
+//
433
+// If *PIndex is in the leaf, return it; otherwise return the Index, if any,
434
+// below where it would belong.
435
+
436
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
437
+ {
438
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
439
+ pop1 = Pjlw[0] + 1;
440
+
441
+ if ((offset = j__udySearchLeafW(Pjlw + 1, pop1, *PIndex))
442
+ >= 0) // Index is present.
443
+ {
444
+ assert(offset < pop1); // in expected range.
445
+ JU_RET_FOUND_LEAFW(Pjlw, pop1, offset); // *PIndex is set.
446
+ }
447
+
448
+#ifdef JUDYPREV
449
+ if ((offset = ~offset) == 0) // no next-left Index.
450
+#else
451
+ if ((offset = ~offset) >= pop1) // no next-right Index.
452
+#endif
453
+ JU_RET_NOTFOUND;
454
+
455
+ assert(offset <= pop1); // valid result.
456
+
457
+#ifdef JUDYPREV
458
+ *PIndex = Pjlw[offset--]; // next-left Index, base 1.
459
+#else
460
+ *PIndex = Pjlw[offset + 1]; // next-right Index, base 1.
461
+#endif
462
+ JU_RET_FOUND_LEAFW(Pjlw, pop1, offset); // base 0.
463
+
464
+ }
465
+ else // JRP BRANCH
466
+ {
467
+ Pjpm_t Pjpm = P_JPM(PArray);
468
+ Pjp = &(Pjpm->jpm_JP);
469
+
470
+// goto SM1Get;
471
+ }
472
+
473
+// ============================================================================
474
+// STATE MACHINE 1 -- GET INDEX:
475
+//
476
+// Search for *PIndex (already decremented/incremented so as to be inclusive).
477
+// If found, return it. Otherwise in theory hand off to SM2Backtrack or
478
+// SM3Findlimit, but in practice "shortcut" by first sideways searching the
479
+// current branch or leaf upon hitting a dead end. During sideways search,
480
+// modify *PIndex to a new path taken.
481
+//
482
+// ENTRY: Pjp points to next JP to interpret, whose Decode bytes have not yet
483
+// been checked. This JP is not yet listed in history.
484
+//
485
+// Note: Check Decode bytes at the start of each loop, not after looking up a
486
+// new JP, so its easy to do constant shifts/masks, although this requires
487
+// cautious handling of Pjp, offset, and *hist[] for correct entry to
488
+// SM2Backtrack.
489
+//
490
+// EXIT: Return, or branch to SM2Backtrack or SM3Findlimit with correct
491
+// interface, as described elsewhere.
492
+//
493
+// WARNING: For run-time efficiency the following cases replicate code with
494
+// varying constants, rather than using common code with variable values!
495
+
496
+SM1Get: // return here for next branch/leaf.
497
+
498
+ switch (JU_JPTYPE(Pjp))
499
+ {
500
+
501
+
502
+// ----------------------------------------------------------------------------
503
+// LINEAR BRANCH:
504
+//
505
+// Check Decode bytes, if any, in the current JP, then search for a JP for the
506
+// next digit in *PIndex.
507
+
508
+ case cJU_JPBRANCH_L2: CHECKDCD(2); SM1PREPB(2, SM1BranchL);
509
+ case cJU_JPBRANCH_L3: CHECKDCD(3); SM1PREPB(3, SM1BranchL);
510
+#ifdef JU_64BIT
511
+ case cJU_JPBRANCH_L4: CHECKDCD(4); SM1PREPB(4, SM1BranchL);
512
+ case cJU_JPBRANCH_L5: CHECKDCD(5); SM1PREPB(5, SM1BranchL);
513
+ case cJU_JPBRANCH_L6: CHECKDCD(6); SM1PREPB(6, SM1BranchL);
514
+ case cJU_JPBRANCH_L7: CHECKDCD(7); SM1PREPB(7, SM1BranchL);
515
+#endif
516
+ case cJU_JPBRANCH_L: SM1PREPB(cJU_ROOTSTATE, SM1BranchL);
517
+
518
+// Common code (state-independent) for all cases of linear branches:
519
+
520
+SM1BranchL:
521
+ Pjbl = P_JBL(Pjp->jp_Addr);
522
+
523
+// Found JP matching current digit in *PIndex; record parent JP and the next
524
+// JPs offset, and iterate to the next JP:
525
+
526
+ if ((offset = j__udySearchLeaf1((Pjll_t) (Pjbl->jbl_Expanse),
527
+ Pjbl->jbl_NumJPs, digit)) >= 0)
528
+ {
529
+ HISTPUSH(Pjp, offset);
530
+ Pjp = (Pjbl->jbl_jp) + offset;
531
+ goto SM1Get;
532
+ }
533
+
534
+// Dead end, no JP in BranchL for next digit in *PIndex:
535
+//
536
+// Get the ideal location of digits JP, and if theres no next-left/right JP
537
+// in the BranchL, shortcut and start backtracking one level up; ignore the
538
+// current Pjp because it points to a BranchL with no next-left/right JP.
539
+
540
+#ifdef JUDYPREV
541
+ if ((offset = (~offset) - 1) < 0) // no next-left JP in BranchL.
542
+#else
543
+ if ((offset = (~offset)) >= Pjbl->jbl_NumJPs) // no next-right.
544
+#endif
545
+ goto SM2Backtrack;
546
+
547
+// Theres a next-left/right JP in the current BranchL; save its digit in
548
+// *PIndex and shortcut to SM3Findlimit:
549
+
550
+ JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state);
551
+ Pjp = (Pjbl->jbl_jp) + offset;
552
+ goto SM3Findlimit;
553
+
554
+
555
+// ----------------------------------------------------------------------------
556
+// BITMAP BRANCH:
557
+//
558
+// Check Decode bytes, if any, in the current JP, then look for a JP for the
559
+// next digit in *PIndex.
560
+
561
+ case cJU_JPBRANCH_B2: CHECKDCD(2); SM1PREPB(2, SM1BranchB);
562
+ case cJU_JPBRANCH_B3: CHECKDCD(3); SM1PREPB(3, SM1BranchB);
563
+#ifdef JU_64BIT
564
+ case cJU_JPBRANCH_B4: CHECKDCD(4); SM1PREPB(4, SM1BranchB);
565
+ case cJU_JPBRANCH_B5: CHECKDCD(5); SM1PREPB(5, SM1BranchB);
566
+ case cJU_JPBRANCH_B6: CHECKDCD(6); SM1PREPB(6, SM1BranchB);
567
+ case cJU_JPBRANCH_B7: CHECKDCD(7); SM1PREPB(7, SM1BranchB);
568
+#endif
569
+ case cJU_JPBRANCH_B: SM1PREPB(cJU_ROOTSTATE, SM1BranchB);
570
+
571
+// Common code (state-independent) for all cases of bitmap branches:
572
+
573
+SM1BranchB:
574
+ Pjbb = P_JBB(Pjp->jp_Addr);
575
+
576
+// Locate the digits JP in the subexpanse list, if present, otherwise the
577
+// offset of the next-left JP, if any:
578
+
579
+ subexp = digit / cJU_BITSPERSUBEXPB;
580
+ assert(subexp < cJU_NUMSUBEXPB); // falls in expected range.
581
+ bitposmask = JU_BITPOSMASKB(digit);
582
+ offset = SEARCHBITMAPB(JU_JBB_BITMAP(Pjbb, subexp), digit,
583
+ bitposmask);
584
+ // right range:
585
+ assert((offset >= -1) && (offset < (int) cJU_BITSPERSUBEXPB));
586
+
587
+// Found JP matching current digit in *PIndex:
588
+//
589
+// Record the parent JP and the next JPs offset; and iterate to the next JP.
590
+
591
+// if (JU_BITMAPTESTB(Pjbb, digit)) // slower.
592
+ if (JU_JBB_BITMAP(Pjbb, subexp) & bitposmask) // faster.
593
+ {
594
+ // not negative since at least one bit is set:
595
+ assert(offset >= 0);
596
+
597
+ HISTPUSH(Pjp, HISTPUSHBOFF(subexp, offset, digit));
598
+
599
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL)
600
+ {
601
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
602
+ JUDY1CODE(return(JERRI );)
603
+ JUDYLCODE(return(PPJERR);)
604
+ }
605
+
606
+ Pjp += offset;
607
+ goto SM1Get; // iterate to next JP.
608
+ }
609
+
610
+// Dead end, no JP in BranchB for next digit in *PIndex:
611
+//
612
+// If theres a next-left/right JP in the current BranchB, shortcut to
613
+// SM3Findlimit. Note: offset is already set to the correct value for the
614
+// next-left/right JP.
615
+
616
+#ifdef JUDYPREV
617
+ if (offset >= 0) // next-left JP is in this subexpanse.
618
+ goto SM1BranchBFindlimit;
619
+
620
+ while (--subexp >= 0) // search next-left subexpanses.
621
+#else
622
+ if (JU_JBB_BITMAP(Pjbb, subexp) & JU_MASKHIGHEREXC(bitposmask))
623
+ {
624
+ ++offset; // next-left => next-right.
625
+ goto SM1BranchBFindlimit;
626
+ }
627
+
628
+ while (++subexp < cJU_NUMSUBEXPB) // search next-right subexps.
629
+#endif
630
+ {
631
+ if (! JU_JBB_PJP(Pjbb, subexp)) continue; // empty subexpanse.
632
+
633
+#ifdef JUDYPREV
634
+ offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp));
635
+ // expected range:
636
+ assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB));
637
+#else
638
+ offset = 0;
639
+#endif
640
+
641
+// Save the next-left/right JPs digit in *PIndex:
642
+
643
+SM1BranchBFindlimit:
644
+ JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp),
645
+ offset);
646
+ JU_SETDIGIT(*PIndex, digit, state);
647
+
648
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL)
649
+ {
650
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
651
+ JUDY1CODE(return(JERRI );)
652
+ JUDYLCODE(return(PPJERR);)
653
+ }
654
+
655
+ Pjp += offset;
656
+ goto SM3Findlimit;
657
+ }
658
+
659
+// Theres no next-left/right JP in the BranchB:
660
+//
661
+// Shortcut and start backtracking one level up; ignore the current Pjp because
662
+// it points to a BranchB with no next-left/right JP.
663
+
664
+ goto SM2Backtrack;
665
+
666
+
667
+// ----------------------------------------------------------------------------
668
+// UNCOMPRESSED BRANCH:
669
+//
670
+// Check Decode bytes, if any, in the current JP, then look for a JP for the
671
+// next digit in *PIndex.
672
+
673
+ case cJU_JPBRANCH_U2: CHECKDCD(2); SM1PREPB(2, SM1BranchU);
674
+ case cJU_JPBRANCH_U3: CHECKDCD(3); SM1PREPB(3, SM1BranchU);
675
+#ifdef JU_64BIT
676
+ case cJU_JPBRANCH_U4: CHECKDCD(4); SM1PREPB(4, SM1BranchU);
677
+ case cJU_JPBRANCH_U5: CHECKDCD(5); SM1PREPB(5, SM1BranchU);
678
+ case cJU_JPBRANCH_U6: CHECKDCD(6); SM1PREPB(6, SM1BranchU);
679
+ case cJU_JPBRANCH_U7: CHECKDCD(7); SM1PREPB(7, SM1BranchU);
680
+#endif
681
+ case cJU_JPBRANCH_U: SM1PREPB(cJU_ROOTSTATE, SM1BranchU);
682
+
683
+// Common code (state-independent) for all cases of uncompressed branches:
684
+
685
+SM1BranchU:
686
+ Pjbu = P_JBU(Pjp->jp_Addr);
687
+ Pjp2 = (Pjbu->jbu_jp) + digit;
688
+
689
+// Found JP matching current digit in *PIndex:
690
+//
691
+// Record the parent JP and the next JPs digit, and iterate to the next JP.
692
+//
693
+// TBD: Instead of this, just goto SM1Get, and add cJU_JPNULL* cases to the
694
+// SM1Get state machine? Then backtrack? However, it means you cant detect
695
+// an inappropriate cJU_JPNULL*, when it occurs in other than a BranchU, and
696
+// return JU_RET_CORRUPT.
697
+
698
+ if (! JPNULL(JU_JPTYPE(Pjp2))) // digit has a JP.
699
+ {
700
+ HISTPUSH(Pjp, digit);
701
+ Pjp = Pjp2;
702
+ goto SM1Get;
703
+ }
704
+
705
+// Dead end, no JP in BranchU for next digit in *PIndex:
706
+//
707
+// Search for a next-left/right JP in the current BranchU, and if one is found,
708
+// save its digit in *PIndex and shortcut to SM3Findlimit:
709
+
710
+#ifdef JUDYPREV
711
+ while (digit >= 1)
712
+ {
713
+ Pjp = (Pjbu->jbu_jp) + (--digit);
714
+#else
715
+ while (digit < cJU_BRANCHUNUMJPS - 1)
716
+ {
717
+ Pjp = (Pjbu->jbu_jp) + (++digit);
718
+#endif
719
+ if (JPNULL(JU_JPTYPE(Pjp))) continue;
720
+
721
+ JU_SETDIGIT(*PIndex, digit, state);
722
+ goto SM3Findlimit;
723
+ }
724
+
725
+// Theres no next-left/right JP in the BranchU:
726
+//
727
+// Shortcut and start backtracking one level up; ignore the current Pjp because
728
+// it points to a BranchU with no next-left/right JP.
729
+
730
+ goto SM2Backtrack;
731
+
732
+
733
+// ----------------------------------------------------------------------------
734
+// LINEAR LEAF:
735
+//
736
+// Check Decode bytes, if any, in the current JP, then search the leaf for
737
+// *PIndex.
738
+
739
+#define SM1LEAFL(Func) \
740
+ Pjll = P_JLL(Pjp->jp_Addr); \
741
+ pop1 = JU_JPLEAF_POP0(Pjp) + 1; \
742
+ offset = Func(Pjll, pop1, *PIndex); \
743
+ goto SM1LeafLImm
744
+
745
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
746
+ case cJU_JPLEAF1: CHECKDCD(1); SM1LEAFL(j__udySearchLeaf1);
747
+#endif
748
+ case cJU_JPLEAF2: CHECKDCD(2); SM1LEAFL(j__udySearchLeaf2);
749
+ case cJU_JPLEAF3: CHECKDCD(3); SM1LEAFL(j__udySearchLeaf3);
750
+
751
+#ifdef JU_64BIT
752
+ case cJU_JPLEAF4: CHECKDCD(4); SM1LEAFL(j__udySearchLeaf4);
753
+ case cJU_JPLEAF5: CHECKDCD(5); SM1LEAFL(j__udySearchLeaf5);
754
+ case cJU_JPLEAF6: CHECKDCD(6); SM1LEAFL(j__udySearchLeaf6);
755
+ case cJU_JPLEAF7: CHECKDCD(7); SM1LEAFL(j__udySearchLeaf7);
756
+#endif
757
+
758
+// Common code (state-independent) for all cases of linear leaves and
759
+// immediates:
760
+
761
+SM1LeafLImm:
762
+ if (offset >= 0) // *PIndex is in LeafL / Immed.
763
+#ifdef JUDY1
764
+ JU_RET_FOUND;
765
+#else
766
+ { // JudyL is trickier...
767
+ switch (JU_JPTYPE(Pjp))
768
+ {
769
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
770
+ case cJU_JPLEAF1: JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
771
+#endif
772
+ case cJU_JPLEAF2: JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
773
+ case cJU_JPLEAF3: JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
774
+#ifdef JU_64BIT
775
+ case cJU_JPLEAF4: JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
776
+ case cJU_JPLEAF5: JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
777
+ case cJU_JPLEAF6: JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
778
+ case cJU_JPLEAF7: JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
779
+#endif
780
+
781
+ case cJU_JPIMMED_1_01:
782
+ case cJU_JPIMMED_2_01:
783
+ case cJU_JPIMMED_3_01:
784
+#ifdef JU_64BIT
785
+ case cJU_JPIMMED_4_01:
786
+ case cJU_JPIMMED_5_01:
787
+ case cJU_JPIMMED_6_01:
788
+ case cJU_JPIMMED_7_01:
789
+#endif
790
+ JU_RET_FOUND_IMM_01(Pjp);
791
+
792
+ case cJU_JPIMMED_1_02:
793
+ case cJU_JPIMMED_1_03:
794
+#ifdef JU_64BIT
795
+ case cJU_JPIMMED_1_04:
796
+ case cJU_JPIMMED_1_05:
797
+ case cJU_JPIMMED_1_06:
798
+ case cJU_JPIMMED_1_07:
799
+ case cJU_JPIMMED_2_02:
800
+ case cJU_JPIMMED_2_03:
801
+ case cJU_JPIMMED_3_02:
802
+#endif
803
+ JU_RET_FOUND_IMM(Pjp, offset);
804
+ }
805
+
806
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // impossible?
807
+ JUDY1CODE(return(JERRI );)
808
+ JUDYLCODE(return(PPJERR);)
809
+
810
+ } // found *PIndex
811
+
812
+#endif // JUDYL
813
+
814
+// Dead end, no Index in LeafL / Immed for remaining digit(s) in *PIndex:
815
+//
816
+// Get the ideal location of Index, and if theres no next-left/right Index in
817
+// the LeafL / Immed, shortcut and start backtracking one level up; ignore the
818
+// current Pjp because it points to a LeafL / Immed with no next-left/right
819
+// Index.
820
+
821
+#ifdef JUDYPREV
822
+ if ((offset = (~offset) - 1) < 0) // no next-left Index.
823
+#else
824
+ if ((offset = (~offset)) >= pop1) // no next-right Index.
825
+#endif
826
+ goto SM2Backtrack;
827
+
828
+// Theres a next-left/right Index in the current LeafL / Immed; shortcut by
829
+// copying its digit(s) to *PIndex and returning it.
830
+//
831
+// Unfortunately this is pretty hairy, especially avoiding endian issues.
832
+//
833
+// The cJU_JPLEAF* cases are very similar to same-index-size cJU_JPIMMED* cases
834
+// for *_02 and above, but must return differently, at least for JudyL, so
835
+// spell them out separately here at the cost of a little redundant code for
836
+// Judy1.
837
+
838
+ switch (JU_JPTYPE(Pjp))
839
+ {
840
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
841
+ case cJU_JPLEAF1:
842
+
843
+ JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
844
+ JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
845
+#endif
846
+
847
+ case cJU_JPLEAF2:
848
+
849
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
850
+ | ((uint16_t *) Pjll)[offset];
851
+ JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
852
+
853
+ case cJU_JPLEAF3:
854
+ {
855
+ Word_t lsb;
856
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
857
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
858
+ JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
859
+ }
860
+
861
+#ifdef JU_64BIT
862
+ case cJU_JPLEAF4:
863
+
864
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
865
+ | ((uint32_t *) Pjll)[offset];
866
+ JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
867
+
868
+ case cJU_JPLEAF5:
869
+ {
870
+ Word_t lsb;
871
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
872
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
873
+ JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
874
+ }
875
+
876
+ case cJU_JPLEAF6:
877
+ {
878
+ Word_t lsb;
879
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
880
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
881
+ JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
882
+ }
883
+
884
+ case cJU_JPLEAF7:
885
+ {
886
+ Word_t lsb;
887
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
888
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
889
+ JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
890
+ }
891
+
892
+#endif // JU_64BIT
893
+
894
+#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState)
895
+
896
+ case cJU_JPIMMED_1_01: SET_01(1); goto SM1Imm_01;
897
+ case cJU_JPIMMED_2_01: SET_01(2); goto SM1Imm_01;
898
+ case cJU_JPIMMED_3_01: SET_01(3); goto SM1Imm_01;
899
+#ifdef JU_64BIT
900
+ case cJU_JPIMMED_4_01: SET_01(4); goto SM1Imm_01;
901
+ case cJU_JPIMMED_5_01: SET_01(5); goto SM1Imm_01;
902
+ case cJU_JPIMMED_6_01: SET_01(6); goto SM1Imm_01;
903
+ case cJU_JPIMMED_7_01: SET_01(7); goto SM1Imm_01;
904
+#endif
905
+SM1Imm_01: JU_RET_FOUND_IMM_01(Pjp);
906
+
907
+// Shorthand for where to find start of Index bytes array:
908
+
909
+#ifdef JUDY1
910
+#define PJI (Pjp->jp_1Index)
911
+#else
912
+#define PJI (Pjp->jp_LIndex)
913
+#endif
914
+
915
+ case cJU_JPIMMED_1_02:
916
+ case cJU_JPIMMED_1_03:
917
+#if (defined(JUDY1) || defined(JU_64BIT))
918
+ case cJU_JPIMMED_1_04:
919
+ case cJU_JPIMMED_1_05:
920
+ case cJU_JPIMMED_1_06:
921
+ case cJU_JPIMMED_1_07:
922
+#endif
923
+#if (defined(JUDY1) && defined(JU_64BIT))
924
+ case cJ1_JPIMMED_1_08:
925
+ case cJ1_JPIMMED_1_09:
926
+ case cJ1_JPIMMED_1_10:
927
+ case cJ1_JPIMMED_1_11:
928
+ case cJ1_JPIMMED_1_12:
929
+ case cJ1_JPIMMED_1_13:
930
+ case cJ1_JPIMMED_1_14:
931
+ case cJ1_JPIMMED_1_15:
932
+#endif
933
+ JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
934
+ JU_RET_FOUND_IMM(Pjp, offset);
935
+
936
+#if (defined(JUDY1) || defined(JU_64BIT))
937
+ case cJU_JPIMMED_2_02:
938
+ case cJU_JPIMMED_2_03:
939
+#endif
940
+#if (defined(JUDY1) && defined(JU_64BIT))
941
+ case cJ1_JPIMMED_2_04:
942
+ case cJ1_JPIMMED_2_05:
943
+ case cJ1_JPIMMED_2_06:
944
+ case cJ1_JPIMMED_2_07:
945
+#endif
946
+#if (defined(JUDY1) || defined(JU_64BIT))
947
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
948
+ | ((uint16_t *) PJI)[offset];
949
+ JU_RET_FOUND_IMM(Pjp, offset);
950
+#endif
951
+
952
+#if (defined(JUDY1) || defined(JU_64BIT))
953
+ case cJU_JPIMMED_3_02:
954
+#endif
955
+#if (defined(JUDY1) && defined(JU_64BIT))
956
+ case cJ1_JPIMMED_3_03:
957
+ case cJ1_JPIMMED_3_04:
958
+ case cJ1_JPIMMED_3_05:
959
+#endif
960
+#if (defined(JUDY1) || defined(JU_64BIT))
961
+ {
962
+ Word_t lsb;
963
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
964
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
965
+ JU_RET_FOUND_IMM(Pjp, offset);
966
+ }
967
+#endif
968
+
969
+#if (defined(JUDY1) && defined(JU_64BIT))
970
+ case cJ1_JPIMMED_4_02:
971
+ case cJ1_JPIMMED_4_03:
972
+
973
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
974
+ | ((uint32_t *) PJI)[offset];
975
+ JU_RET_FOUND_IMM(Pjp, offset);
976
+
977
+ case cJ1_JPIMMED_5_02:
978
+ case cJ1_JPIMMED_5_03:
979
+ {
980
+ Word_t lsb;
981
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
982
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
983
+ JU_RET_FOUND_IMM(Pjp, offset);
984
+ }
985
+
986
+ case cJ1_JPIMMED_6_02:
987
+ {
988
+ Word_t lsb;
989
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
990
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
991
+ JU_RET_FOUND_IMM(Pjp, offset);
992
+ }
993
+
994
+ case cJ1_JPIMMED_7_02:
995
+ {
996
+ Word_t lsb;
997
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
998
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
999
+ JU_RET_FOUND_IMM(Pjp, offset);
1000
+ }
1001
+
1002
+#endif // (JUDY1 && JU_64BIT)
1003
+
1004
+ } // switch for not-found *PIndex
1005
+
1006
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // impossible?
1007
+ JUDY1CODE(return(JERRI );)
1008
+ JUDYLCODE(return(PPJERR);)
1009
+
1010
+
1011
+// ----------------------------------------------------------------------------
1012
+// BITMAP LEAF:
1013
+//
1014
+// Check Decode bytes, if any, in the current JP, then look in the leaf for
1015
+// *PIndex.
1016
+
1017
+ case cJU_JPLEAF_B1:
1018
+ {
1019
+ Pjlb_t Pjlb;
1020
+ CHECKDCD(1);
1021
+
1022
+ Pjlb = P_JLB(Pjp->jp_Addr);
1023
+ digit = JU_DIGITATSTATE(*PIndex, 1);
1024
+ subexp = JU_SUBEXPL(digit);
1025
+ bitposmask = JU_BITPOSMASKL(digit);
1026
+ assert(subexp < cJU_NUMSUBEXPL); // falls in expected range.
1027
+
1028
+// *PIndex exists in LeafB1:
1029
+
1030
+// if (JU_BITMAPTESTL(Pjlb, digit)) // slower.
1031
+ if (JU_JLB_BITMAP(Pjlb, subexp) & bitposmask) // faster.
1032
+ {
1033
+#ifdef JUDYL // needs offset at this point:
1034
+ offset = SEARCHBITMAPL(JU_JLB_BITMAP(Pjlb, subexp), digit, bitposmask);
1035
+#endif
1036
+ JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
1037
+// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset)));
1038
+ }
1039
+
1040
+// Dead end, no Index in LeafB1 for remaining digit in *PIndex:
1041
+//
1042
+// If theres a next-left/right Index in the current LeafB1, which for
1043
+// Judy*Next() is true if any bits are set for higher Indexes, shortcut by
1044
+// returning it. Note: For Judy*Prev(), offset is set here to the correct
1045
+// value for the next-left JP.
1046
+
1047
+ offset = SEARCHBITMAPL(JU_JLB_BITMAP(Pjlb, subexp), digit,
1048
+ bitposmask);
1049
+ // right range:
1050
+ assert((offset >= -1) && (offset < (int) cJU_BITSPERSUBEXPL));
1051
+
1052
+#ifdef JUDYPREV
1053
+ if (offset >= 0) // next-left JP is in this subexpanse.
1054
+ goto SM1LeafB1Findlimit;
1055
+
1056
+ while (--subexp >= 0) // search next-left subexpanses.
1057
+#else
1058
+ if (JU_JLB_BITMAP(Pjlb, subexp) & JU_MASKHIGHEREXC(bitposmask))
1059
+ {
1060
+ ++offset; // next-left => next-right.
1061
+ goto SM1LeafB1Findlimit;
1062
+ }
1063
+
1064
+ while (++subexp < cJU_NUMSUBEXPL) // search next-right subexps.
1065
+#endif
1066
+ {
1067
+ if (! JU_JLB_BITMAP(Pjlb, subexp)) continue; // empty subexp.
1068
+
1069
+#ifdef JUDYPREV
1070
+ offset = SEARCHBITMAPMAXL(JU_JLB_BITMAP(Pjlb, subexp));
1071
+ // expected range:
1072
+ assert((offset >= 0) && (offset < (int) cJU_BITSPERSUBEXPL));
1073
+#else
1074
+ offset = 0;
1075
+#endif
1076
+
1077
+// Save the next-left/right Indexess digit in *PIndex:
1078
+
1079
+SM1LeafB1Findlimit:
1080
+ JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
1081
+ JU_SETDIGIT1(*PIndex, digit);
1082
+ JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
1083
+// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset)));
1084
+ }
1085
+
1086
+// Theres no next-left/right Index in the LeafB1:
1087
+//
1088
+// Shortcut and start backtracking one level up; ignore the current Pjp because
1089
+// it points to a LeafB1 with no next-left/right Index.
1090
+
1091
+ goto SM2Backtrack;
1092
+
1093
+ } // case cJU_JPLEAF_B1
1094
+
1095
+#ifdef JUDY1
1096
+// ----------------------------------------------------------------------------
1097
+// FULL POPULATION:
1098
+//
1099
+// If the Decode bytes match, *PIndex is found (without modification).
1100
+
1101
+ case cJ1_JPFULLPOPU1:
1102
+
1103
+ CHECKDCD(1);
1104
+ JU_RET_FOUND_FULLPOPU1;
1105
+#endif
1106
+
1107
+
1108
+// ----------------------------------------------------------------------------
1109
+// IMMEDIATE:
1110
+
1111
+#ifdef JUDYPREV
1112
+#define SM1IMM_SETPOP1(cPop1)
1113
+#else
1114
+#define SM1IMM_SETPOP1(cPop1) pop1 = (cPop1)
1115
+#endif
1116
+
1117
+#define SM1IMM(Func,cPop1) \
1118
+ SM1IMM_SETPOP1(cPop1); \
1119
+ offset = Func((Pjll_t) (PJI), cPop1, *PIndex); \
1120
+ goto SM1LeafLImm
1121
+
1122
+// Special case for Pop1 = 1 Immediate JPs:
1123
+//
1124
+// If *PIndex is in the immediate, offset is 0, otherwise the binary NOT of the
1125
+// offset where it belongs, 0 or 1, same as from the search functions.
1126
+
1127
+#ifdef JUDYPREV
1128
+#define SM1IMM_01_SETPOP1
1129
+#else
1130
+#define SM1IMM_01_SETPOP1 pop1 = 1
1131
+#endif
1132
+
1133
+#define SM1IMM_01 \
1134
+ SM1IMM_01_SETPOP1; \
1135
+ offset = ((JU_JPDCDPOP0(Pjp) < JU_TRIMTODCDSIZE(*PIndex)) ? ~1 : \
1136
+ (JU_JPDCDPOP0(Pjp) == JU_TRIMTODCDSIZE(*PIndex)) ? 0 : \
1137
+ ~0); \
1138
+ goto SM1LeafLImm
1139
+
1140
+ case cJU_JPIMMED_1_01:
1141
+ case cJU_JPIMMED_2_01:
1142
+ case cJU_JPIMMED_3_01:
1143
+#ifdef JU_64BIT
1144
+ case cJU_JPIMMED_4_01:
1145
+ case cJU_JPIMMED_5_01:
1146
+ case cJU_JPIMMED_6_01:
1147
+ case cJU_JPIMMED_7_01:
1148
+#endif
1149
+ SM1IMM_01;
1150
+
1151
+// TBD: Doug says it would be OK to have fewer calls and calculate arg 2, here
1152
+// and in Judy*Count() also.
1153
+
1154
+ case cJU_JPIMMED_1_02: SM1IMM(j__udySearchLeaf1, 2);
1155
+ case cJU_JPIMMED_1_03: SM1IMM(j__udySearchLeaf1, 3);
1156
+#if (defined(JUDY1) || defined(JU_64BIT))
1157
+ case cJU_JPIMMED_1_04: SM1IMM(j__udySearchLeaf1, 4);
1158
+ case cJU_JPIMMED_1_05: SM1IMM(j__udySearchLeaf1, 5);
1159
+ case cJU_JPIMMED_1_06: SM1IMM(j__udySearchLeaf1, 6);
1160
+ case cJU_JPIMMED_1_07: SM1IMM(j__udySearchLeaf1, 7);
1161
+#endif
1162
+#if (defined(JUDY1) && defined(JU_64BIT))
1163
+ case cJ1_JPIMMED_1_08: SM1IMM(j__udySearchLeaf1, 8);
1164
+ case cJ1_JPIMMED_1_09: SM1IMM(j__udySearchLeaf1, 9);
1165
+ case cJ1_JPIMMED_1_10: SM1IMM(j__udySearchLeaf1, 10);
1166
+ case cJ1_JPIMMED_1_11: SM1IMM(j__udySearchLeaf1, 11);
1167
+ case cJ1_JPIMMED_1_12: SM1IMM(j__udySearchLeaf1, 12);
1168
+ case cJ1_JPIMMED_1_13: SM1IMM(j__udySearchLeaf1, 13);
1169
+ case cJ1_JPIMMED_1_14: SM1IMM(j__udySearchLeaf1, 14);
1170
+ case cJ1_JPIMMED_1_15: SM1IMM(j__udySearchLeaf1, 15);
1171
+#endif
1172
+
1173
+#if (defined(JUDY1) || defined(JU_64BIT))
1174
+ case cJU_JPIMMED_2_02: SM1IMM(j__udySearchLeaf2, 2);
1175
+ case cJU_JPIMMED_2_03: SM1IMM(j__udySearchLeaf2, 3);
1176
+#endif
1177
+#if (defined(JUDY1) && defined(JU_64BIT))
1178
+ case cJ1_JPIMMED_2_04: SM1IMM(j__udySearchLeaf2, 4);
1179
+ case cJ1_JPIMMED_2_05: SM1IMM(j__udySearchLeaf2, 5);
1180
+ case cJ1_JPIMMED_2_06: SM1IMM(j__udySearchLeaf2, 6);
1181
+ case cJ1_JPIMMED_2_07: SM1IMM(j__udySearchLeaf2, 7);
1182
+#endif
1183
+
1184
+#if (defined(JUDY1) || defined(JU_64BIT))
1185
+ case cJU_JPIMMED_3_02: SM1IMM(j__udySearchLeaf3, 2);
1186
+#endif
1187
+#if (defined(JUDY1) && defined(JU_64BIT))
1188
+ case cJ1_JPIMMED_3_03: SM1IMM(j__udySearchLeaf3, 3);
1189
+ case cJ1_JPIMMED_3_04: SM1IMM(j__udySearchLeaf3, 4);
1190
+ case cJ1_JPIMMED_3_05: SM1IMM(j__udySearchLeaf3, 5);
1191
+
1192
+ case cJ1_JPIMMED_4_02: SM1IMM(j__udySearchLeaf4, 2);
1193
+ case cJ1_JPIMMED_4_03: SM1IMM(j__udySearchLeaf4, 3);
1194
+
1195
+ case cJ1_JPIMMED_5_02: SM1IMM(j__udySearchLeaf5, 2);
1196
+ case cJ1_JPIMMED_5_03: SM1IMM(j__udySearchLeaf5, 3);
1197
+
1198
+ case cJ1_JPIMMED_6_02: SM1IMM(j__udySearchLeaf6, 2);
1199
+
1200
+ case cJ1_JPIMMED_7_02: SM1IMM(j__udySearchLeaf7, 2);
1201
+#endif
1202
+
1203
+
1204
+// ----------------------------------------------------------------------------
1205
+// INVALID JP TYPE:
1206
+
1207
+ default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1208
+ JUDY1CODE(return(JERRI );)
1209
+ JUDYLCODE(return(PPJERR);)
1210
+
1211
+ } // SM1Get switch.
1212
+
1213
+ /*NOTREACHED*/
1214
+
1215
+
1216
+// ============================================================================
1217
+// STATE MACHINE 2 -- BACKTRACK BRANCH TO PREVIOUS JP:
1218
+//
1219
+// Look for the next-left/right JP in a branch, backing up the history list as
1220
+// necessary. Upon finding a next-left/right JP, modify the corresponding
1221
+// digit in *PIndex before passing control to SM3Findlimit.
1222
+//
1223
+// Note: As described earlier, only branch JPs are expected here; other types
1224
+// fall into the default case.
1225
+//
1226
+// Note: If a found JP contains needed Dcd bytes, thats OK, theyre copied to
1227
+// *PIndex in SM3Findlimit.
1228
+//
1229
+// TBD: This code has a lot in common with similar code in the shortcut cases
1230
+// in SM1Get. Can combine this code somehow?
1231
+//
1232
+// ENTRY: List, possibly empty, of JPs and offsets in APjphist[] and
1233
+// Aoffhist[]; see earlier comments.
1234
+//
1235
+// EXIT: Execute JU_RET_NOTFOUND if no previous/next JP; otherwise jump to
1236
+// SM3Findlimit to resume a new but different downward search.
1237
+
1238
+SM2Backtrack: // come or return here for first/next sideways search.
1239
+
1240
+ HISTPOP(Pjp, offset);
1241
+
1242
+ switch (JU_JPTYPE(Pjp))
1243
+ {
1244
+
1245
+
1246
+// ----------------------------------------------------------------------------
1247
+// LINEAR BRANCH:
1248
+
1249
+ case cJU_JPBRANCH_L2: state = 2; goto SM2BranchL;
1250
+ case cJU_JPBRANCH_L3: state = 3; goto SM2BranchL;
1251
+#ifdef JU_64BIT
1252
+ case cJU_JPBRANCH_L4: state = 4; goto SM2BranchL;
1253
+ case cJU_JPBRANCH_L5: state = 5; goto SM2BranchL;
1254
+ case cJU_JPBRANCH_L6: state = 6; goto SM2BranchL;
1255
+ case cJU_JPBRANCH_L7: state = 7; goto SM2BranchL;
1256
+#endif
1257
+ case cJU_JPBRANCH_L: state = cJU_ROOTSTATE; goto SM2BranchL;
1258
+
1259
+SM2BranchL:
1260
+#ifdef JUDYPREV
1261
+ if (--offset < 0) goto SM2Backtrack; // no next-left JP in BranchL.
1262
+#endif
1263
+ Pjbl = P_JBL(Pjp->jp_Addr);
1264
+#ifdef JUDYNEXT
1265
+ if (++offset >= (Pjbl->jbl_NumJPs)) goto SM2Backtrack;
1266
+ // no next-right JP in BranchL.
1267
+#endif
1268
+
1269
+// Theres a next-left/right JP in the current BranchL; save its digit in
1270
+// *PIndex and continue with SM3Findlimit:
1271
+
1272
+ JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state);
1273
+ Pjp = (Pjbl->jbl_jp) + offset;
1274
+ goto SM3Findlimit;
1275
+
1276
+
1277
+// ----------------------------------------------------------------------------
1278
+// BITMAP BRANCH:
1279
+
1280
+ case cJU_JPBRANCH_B2: state = 2; goto SM2BranchB;
1281
+ case cJU_JPBRANCH_B3: state = 3; goto SM2BranchB;
1282
+#ifdef JU_64BIT
1283
+ case cJU_JPBRANCH_B4: state = 4; goto SM2BranchB;
1284
+ case cJU_JPBRANCH_B5: state = 5; goto SM2BranchB;
1285
+ case cJU_JPBRANCH_B6: state = 6; goto SM2BranchB;
1286
+ case cJU_JPBRANCH_B7: state = 7; goto SM2BranchB;
1287
+#endif
1288
+ case cJU_JPBRANCH_B: state = cJU_ROOTSTATE; goto SM2BranchB;
1289
+
1290
+SM2BranchB:
1291
+ Pjbb = P_JBB(Pjp->jp_Addr);
1292
+ HISTPOPBOFF(subexp, offset, digit); // unpack values.
1293
+
1294
+// If theres a next-left/right JP in the current BranchB, which for
1295
+// Judy*Next() is true if any bits are set for higher Indexes, continue to
1296
+// SM3Findlimit:
1297
+//
1298
+// Note: offset is set to the JP previously traversed; go one to the
1299
+// left/right.
1300
+
1301
+#ifdef JUDYPREV
1302
+ if (offset > 0) // next-left JP is in this subexpanse.
1303
+ {
1304
+ --offset;
1305
+ goto SM2BranchBFindlimit;
1306
+ }
1307
+
1308
+ while (--subexp >= 0) // search next-left subexpanses.
1309
+#else
1310
+ if (JU_JBB_BITMAP(Pjbb, subexp)
1311
+ & JU_MASKHIGHEREXC(JU_BITPOSMASKB(digit)))
1312
+ {
1313
+ ++offset; // next-left => next-right.
1314
+ goto SM2BranchBFindlimit;
1315
+ }
1316
+
1317
+ while (++subexp < cJU_NUMSUBEXPB) // search next-right subexps.
1318
+#endif
1319
+ {
1320
+ if (! JU_JBB_PJP(Pjbb, subexp)) continue; // empty subexpanse.
1321
+
1322
+#ifdef JUDYPREV
1323
+ offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp));
1324
+ // expected range:
1325
+ assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB));
1326
+#else
1327
+ offset = 0;
1328
+#endif
1329
+
1330
+// Save the next-left/right JPs digit in *PIndex:
1331
+
1332
+SM2BranchBFindlimit:
1333
+ JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp),
1334
+ offset);
1335
+ JU_SETDIGIT(*PIndex, digit, state);
1336
+
1337
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL)
1338
+ {
1339
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1340
+ JUDY1CODE(return(JERRI );)
1341
+ JUDYLCODE(return(PPJERR);)
1342
+ }
1343
+
1344
+ Pjp += offset;
1345
+ goto SM3Findlimit;
1346
+ }
1347
+
1348
+// Theres no next-left/right JP in the BranchB:
1349
+
1350
+ goto SM2Backtrack;
1351
+
1352
+
1353
+// ----------------------------------------------------------------------------
1354
+// UNCOMPRESSED BRANCH:
1355
+
1356
+ case cJU_JPBRANCH_U2: state = 2; goto SM2BranchU;
1357
+ case cJU_JPBRANCH_U3: state = 3; goto SM2BranchU;
1358
+#ifdef JU_64BIT
1359
+ case cJU_JPBRANCH_U4: state = 4; goto SM2BranchU;
1360
+ case cJU_JPBRANCH_U5: state = 5; goto SM2BranchU;
1361
+ case cJU_JPBRANCH_U6: state = 6; goto SM2BranchU;
1362
+ case cJU_JPBRANCH_U7: state = 7; goto SM2BranchU;
1363
+#endif
1364
+ case cJU_JPBRANCH_U: state = cJU_ROOTSTATE; goto SM2BranchU;
1365
+
1366
+SM2BranchU:
1367
+
1368
+// Search for a next-left/right JP in the current BranchU, and if one is found,
1369
+// save its digit in *PIndex and continue to SM3Findlimit:
1370
+
1371
+ Pjbu = P_JBU(Pjp->jp_Addr);
1372
+ digit = offset;
1373
+
1374
+#ifdef JUDYPREV
1375
+ while (digit >= 1)
1376
+ {
1377
+ Pjp = (Pjbu->jbu_jp) + (--digit);
1378
+#else
1379
+ while (digit < cJU_BRANCHUNUMJPS - 1)
1380
+ {
1381
+ Pjp = (Pjbu->jbu_jp) + (++digit);
1382
+#endif
1383
+ if (JPNULL(JU_JPTYPE(Pjp))) continue;
1384
+
1385
+ JU_SETDIGIT(*PIndex, digit, state);
1386
+ goto SM3Findlimit;
1387
+ }
1388
+
1389
+// Theres no next-left/right JP in the BranchU:
1390
+
1391
+ goto SM2Backtrack;
1392
+
1393
+
1394
+// ----------------------------------------------------------------------------
1395
+// INVALID JP TYPE:
1396
+
1397
+ default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1398
+ JUDY1CODE(return(JERRI );)
1399
+ JUDYLCODE(return(PPJERR);)
1400
+
1401
+ } // SM2Backtrack switch.
1402
+
1403
+ /*NOTREACHED*/
1404
+
1405
+
1406
+// ============================================================================
1407
+// STATE MACHINE 3 -- FIND LIMIT JP/INDEX:
1408
+//
1409
+// Look for the highest/lowest (right/left-most) JP in each branch and the
1410
+// highest/lowest Index in a leaf or immediate, and return it. While
1411
+// traversing, modify appropriate digit(s) in *PIndex to reflect the path
1412
+// taken, including Dcd bytes in each JP (which could hold critical missing
1413
+// digits for skipped branches).
1414
+//
1415
+// ENTRY: Pjp set to a JP under which to find max/min JPs (if a branch JP) or
1416
+// a max/min Index and return (if a leaf or immediate JP).
1417
+//
1418
+// EXIT: Execute JU_RET_FOUND* upon reaching a leaf or immediate. Should be
1419
+// impossible to fail, unless the Judy array is corrupt.
1420
+
1421
+SM3Findlimit: // come or return here for first/next branch/leaf.
1422
+
1423
+ switch (JU_JPTYPE(Pjp))
1424
+ {
1425
+// ----------------------------------------------------------------------------
1426
+// LINEAR BRANCH:
1427
+//
1428
+// Simply use the highest/lowest (right/left-most) JP in the BranchL, but first
1429
+// copy the Dcd bytes to *PIndex if there are any (only if state <
1430
+// cJU_ROOTSTATE - 1).
1431
+
1432
+ case cJU_JPBRANCH_L2: SM3PREPB_DCD(2, SM3BranchL);
1433
+#ifndef JU_64BIT
1434
+ case cJU_JPBRANCH_L3: SM3PREPB( 3, SM3BranchL);
1435
+#else
1436
+ case cJU_JPBRANCH_L3: SM3PREPB_DCD(3, SM3BranchL);
1437
+ case cJU_JPBRANCH_L4: SM3PREPB_DCD(4, SM3BranchL);
1438
+ case cJU_JPBRANCH_L5: SM3PREPB_DCD(5, SM3BranchL);
1439
+ case cJU_JPBRANCH_L6: SM3PREPB_DCD(6, SM3BranchL);
1440
+ case cJU_JPBRANCH_L7: SM3PREPB( 7, SM3BranchL);
1441
+#endif
1442
+ case cJU_JPBRANCH_L: SM3PREPB( cJU_ROOTSTATE, SM3BranchL);
1443
+
1444
+SM3BranchL:
1445
+ Pjbl = P_JBL(Pjp->jp_Addr);
1446
+
1447
+#ifdef JUDYPREV
1448
+ if ((offset = (Pjbl->jbl_NumJPs) - 1) < 0)
1449
+#else
1450
+ offset = 0; if ((Pjbl->jbl_NumJPs) == 0)
1451
+#endif
1452
+ {
1453
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1454
+ JUDY1CODE(return(JERRI );)
1455
+ JUDYLCODE(return(PPJERR);)
1456
+ }
1457
+
1458
+ JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[offset], state);
1459
+ Pjp = (Pjbl->jbl_jp) + offset;
1460
+ goto SM3Findlimit;
1461
+
1462
+
1463
+// ----------------------------------------------------------------------------
1464
+// BITMAP BRANCH:
1465
+//
1466
+// Look for the highest/lowest (right/left-most) non-null subexpanse, then use
1467
+// the highest/lowest JP in that subexpanse, but first copy Dcd bytes, if there
1468
+// are any (only if state < cJU_ROOTSTATE - 1), to *PIndex.
1469
+
1470
+ case cJU_JPBRANCH_B2: SM3PREPB_DCD(2, SM3BranchB);
1471
+#ifndef JU_64BIT
1472
+ case cJU_JPBRANCH_B3: SM3PREPB( 3, SM3BranchB);
1473
+#else
1474
+ case cJU_JPBRANCH_B3: SM3PREPB_DCD(3, SM3BranchB);
1475
+ case cJU_JPBRANCH_B4: SM3PREPB_DCD(4, SM3BranchB);
1476
+ case cJU_JPBRANCH_B5: SM3PREPB_DCD(5, SM3BranchB);
1477
+ case cJU_JPBRANCH_B6: SM3PREPB_DCD(6, SM3BranchB);
1478
+ case cJU_JPBRANCH_B7: SM3PREPB( 7, SM3BranchB);
1479
+#endif
1480
+ case cJU_JPBRANCH_B: SM3PREPB( cJU_ROOTSTATE, SM3BranchB);
1481
+
1482
+SM3BranchB:
1483
+ Pjbb = P_JBB(Pjp->jp_Addr);
1484
+#ifdef JUDYPREV
1485
+ subexp = cJU_NUMSUBEXPB;
1486
+
1487
+ while (! (JU_JBB_BITMAP(Pjbb, --subexp))) // find non-empty subexp.
1488
+ {
1489
+ if (subexp <= 0) // wholly empty bitmap.
1490
+ {
1491
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1492
+ JUDY1CODE(return(JERRI );)
1493
+ JUDYLCODE(return(PPJERR);)
1494
+ }
1495
+ }
1496
+
1497
+ offset = SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp));
1498
+ // expected range:
1499
+ assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPB));
1500
+#else
1501
+ subexp = -1;
1502
+
1503
+ while (! (JU_JBB_BITMAP(Pjbb, ++subexp))) // find non-empty subexp.
1504
+ {
1505
+ if (subexp >= cJU_NUMSUBEXPB - 1) // didnt find one.
1506
+ {
1507
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1508
+ JUDY1CODE(return(JERRI );)
1509
+ JUDYLCODE(return(PPJERR);)
1510
+ }
1511
+ }
1512
+
1513
+ offset = 0;
1514
+#endif
1515
+
1516
+ JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb, subexp), offset);
1517
+ JU_SETDIGIT(*PIndex, digit, state);
1518
+
1519
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL)
1520
+ {
1521
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1522
+ JUDY1CODE(return(JERRI );)
1523
+ JUDYLCODE(return(PPJERR);)
1524
+ }
1525
+
1526
+ Pjp += offset;
1527
+ goto SM3Findlimit;
1528
+
1529
+
1530
+// ----------------------------------------------------------------------------
1531
+// UNCOMPRESSED BRANCH:
1532
+//
1533
+// Look for the highest/lowest (right/left-most) non-null JP, and use it, but
1534
+// first copy Dcd bytes to *PIndex if there are any (only if state <
1535
+// cJU_ROOTSTATE - 1).
1536
+
1537
+ case cJU_JPBRANCH_U2: SM3PREPB_DCD(2, SM3BranchU);
1538
+#ifndef JU_64BIT
1539
+ case cJU_JPBRANCH_U3: SM3PREPB( 3, SM3BranchU);
1540
+#else
1541
+ case cJU_JPBRANCH_U3: SM3PREPB_DCD(3, SM3BranchU);
1542
+ case cJU_JPBRANCH_U4: SM3PREPB_DCD(4, SM3BranchU);
1543
+ case cJU_JPBRANCH_U5: SM3PREPB_DCD(5, SM3BranchU);
1544
+ case cJU_JPBRANCH_U6: SM3PREPB_DCD(6, SM3BranchU);
1545
+ case cJU_JPBRANCH_U7: SM3PREPB( 7, SM3BranchU);
1546
+#endif
1547
+ case cJU_JPBRANCH_U: SM3PREPB( cJU_ROOTSTATE, SM3BranchU);
1548
+
1549
+SM3BranchU:
1550
+ Pjbu = P_JBU(Pjp->jp_Addr);
1551
+#ifdef JUDYPREV
1552
+ digit = cJU_BRANCHUNUMJPS;
1553
+
1554
+ while (digit >= 1)
1555
+ {
1556
+ Pjp = (Pjbu->jbu_jp) + (--digit);
1557
+#else
1558
+
1559
+ for (digit = 0; digit < cJU_BRANCHUNUMJPS; ++digit)
1560
+ {
1561
+ Pjp = (Pjbu->jbu_jp) + digit;
1562
+#endif
1563
+ if (JPNULL(JU_JPTYPE(Pjp))) continue;
1564
+
1565
+ JU_SETDIGIT(*PIndex, digit, state);
1566
+ goto SM3Findlimit;
1567
+ }
1568
+
1569
+// No non-null JPs in BranchU:
1570
+
1571
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1572
+ JUDY1CODE(return(JERRI );)
1573
+ JUDYLCODE(return(PPJERR);)
1574
+
1575
+
1576
+// ----------------------------------------------------------------------------
1577
+// LINEAR LEAF:
1578
+//
1579
+// Simply use the highest/lowest (right/left-most) Index in the LeafL, but the
1580
+// details vary depending on leaf Index Size. First copy Dcd bytes, if there
1581
+// are any (only if state < cJU_ROOTSTATE - 1), to *PIndex.
1582
+
1583
+#define SM3LEAFLDCD(cState) \
1584
+ JU_SETDCD(*PIndex, Pjp, cState); \
1585
+ SM3LEAFLNODCD
1586
+
1587
+#ifdef JUDY1
1588
+#define SM3LEAFL_SETPOP1 // not needed in any cases.
1589
+#else
1590
+#define SM3LEAFL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1
1591
+#endif
1592
+
1593
+#ifdef JUDYPREV
1594
+#define SM3LEAFLNODCD \
1595
+ Pjll = P_JLL(Pjp->jp_Addr); \
1596
+ SM3LEAFL_SETPOP1; \
1597
+ offset = JU_JPLEAF_POP0(Pjp); assert(offset >= 0)
1598
+#else
1599
+#define SM3LEAFLNODCD \
1600
+ Pjll = P_JLL(Pjp->jp_Addr); \
1601
+ SM3LEAFL_SETPOP1; \
1602
+ offset = 0; assert(JU_JPLEAF_POP0(Pjp) >= 0);
1603
+#endif
1604
+
1605
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
1606
+ case cJU_JPLEAF1:
1607
+
1608
+ SM3LEAFLDCD(1);
1609
+ JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
1610
+ JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
1611
+#endif
1612
+
1613
+ case cJU_JPLEAF2:
1614
+
1615
+ SM3LEAFLDCD(2);
1616
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
1617
+ | ((uint16_t *) Pjll)[offset];
1618
+ JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
1619
+
1620
+#ifndef JU_64BIT
1621
+ case cJU_JPLEAF3:
1622
+ {
1623
+ Word_t lsb;
1624
+ SM3LEAFLNODCD;
1625
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
1626
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
1627
+ JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
1628
+ }
1629
+
1630
+#else
1631
+ case cJU_JPLEAF3:
1632
+ {
1633
+ Word_t lsb;
1634
+ SM3LEAFLDCD(3);
1635
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
1636
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
1637
+ JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
1638
+ }
1639
+
1640
+ case cJU_JPLEAF4:
1641
+
1642
+ SM3LEAFLDCD(4);
1643
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
1644
+ | ((uint32_t *) Pjll)[offset];
1645
+ JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
1646
+
1647
+ case cJU_JPLEAF5:
1648
+ {
1649
+ Word_t lsb;
1650
+ SM3LEAFLDCD(5);
1651
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
1652
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
1653
+ JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
1654
+ }
1655
+
1656
+ case cJU_JPLEAF6:
1657
+ {
1658
+ Word_t lsb;
1659
+ SM3LEAFLDCD(6);
1660
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
1661
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
1662
+ JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
1663
+ }
1664
+
1665
+ case cJU_JPLEAF7:
1666
+ {
1667
+ Word_t lsb;
1668
+ SM3LEAFLNODCD;
1669
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
1670
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
1671
+ JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
1672
+ }
1673
+#endif
1674
+
1675
+
1676
+// ----------------------------------------------------------------------------
1677
+// BITMAP LEAF:
1678
+//
1679
+// Look for the highest/lowest (right/left-most) non-null subexpanse, then use
1680
+// the highest/lowest Index in that subexpanse, but first copy Dcd bytes
1681
+// (always present since state 1 < cJU_ROOTSTATE) to *PIndex.
1682
+
1683
+ case cJU_JPLEAF_B1:
1684
+ {
1685
+ Pjlb_t Pjlb;
1686
+
1687
+ JU_SETDCD(*PIndex, Pjp, 1);
1688
+
1689
+ Pjlb = P_JLB(Pjp->jp_Addr);
1690
+#ifdef JUDYPREV
1691
+ subexp = cJU_NUMSUBEXPL;
1692
+
1693
+ while (! JU_JLB_BITMAP(Pjlb, --subexp)) // find non-empty subexp.
1694
+ {
1695
+ if (subexp <= 0) // wholly empty bitmap.
1696
+ {
1697
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1698
+ JUDY1CODE(return(JERRI );)
1699
+ JUDYLCODE(return(PPJERR);)
1700
+ }
1701
+ }
1702
+
1703
+// TBD: Might it be faster to just use a variant of BITMAPDIGIT*() that yields
1704
+// the digit for the right-most Index with a bit set?
1705
+
1706
+ offset = SEARCHBITMAPMAXL(JU_JLB_BITMAP(Pjlb, subexp));
1707
+ // expected range:
1708
+ assert((offset >= 0) && (offset < cJU_BITSPERSUBEXPL));
1709
+#else
1710
+ subexp = -1;
1711
+
1712
+ while (! JU_JLB_BITMAP(Pjlb, ++subexp)) // find non-empty subexp.
1713
+ {
1714
+ if (subexp >= cJU_NUMSUBEXPL - 1) // didnt find one.
1715
+ {
1716
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1717
+ JUDY1CODE(return(JERRI );)
1718
+ JUDYLCODE(return(PPJERR);)
1719
+ }
1720
+ }
1721
+
1722
+ offset = 0;
1723
+#endif
1724
+
1725
+ JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
1726
+ JU_SETDIGIT1(*PIndex, digit);
1727
+ JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
1728
+// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + (offset)));
1729
+
1730
+ } // case cJU_JPLEAF_B1
1731
+
1732
+#ifdef JUDY1
1733
+// ----------------------------------------------------------------------------
1734
+// FULL POPULATION:
1735
+//
1736
+// Copy Dcd bytes to *PIndex (always present since state 1 < cJU_ROOTSTATE),
1737
+// then set the highest/lowest possible digit as the LSB in *PIndex.
1738
+
1739
+ case cJ1_JPFULLPOPU1:
1740
+
1741
+ JU_SETDCD( *PIndex, Pjp, 1);
1742
+#ifdef JUDYPREV
1743
+ JU_SETDIGIT1(*PIndex, cJU_BITSPERBITMAP - 1);
1744
+#else
1745
+ JU_SETDIGIT1(*PIndex, 0);
1746
+#endif
1747
+ JU_RET_FOUND_FULLPOPU1;
1748
+#endif // JUDY1
1749
+
1750
+
1751
+// ----------------------------------------------------------------------------
1752
+// IMMEDIATE:
1753
+//
1754
+// Simply use the highest/lowest (right/left-most) Index in the Imm, but the
1755
+// details vary depending on leaf Index Size and pop1. Note: There are no Dcd
1756
+// bytes in an Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the
1757
+// least bytes of the immediate Index.
1758
+
1759
+ case cJU_JPIMMED_1_01: SET_01(1); goto SM3Imm_01;
1760
+ case cJU_JPIMMED_2_01: SET_01(2); goto SM3Imm_01;
1761
+ case cJU_JPIMMED_3_01: SET_01(3); goto SM3Imm_01;
1762
+#ifdef JU_64BIT
1763
+ case cJU_JPIMMED_4_01: SET_01(4); goto SM3Imm_01;
1764
+ case cJU_JPIMMED_5_01: SET_01(5); goto SM3Imm_01;
1765
+ case cJU_JPIMMED_6_01: SET_01(6); goto SM3Imm_01;
1766
+ case cJU_JPIMMED_7_01: SET_01(7); goto SM3Imm_01;
1767
+#endif
1768
+SM3Imm_01: JU_RET_FOUND_IMM_01(Pjp);
1769
+
1770
+#ifdef JUDYPREV
1771
+#define SM3IMM_OFFSET(cPop1) (cPop1) - 1 // highest.
1772
+#else
1773
+#define SM3IMM_OFFSET(cPop1) 0 // lowest.
1774
+#endif
1775
+
1776
+#define SM3IMM(cPop1,Next) \
1777
+ offset = SM3IMM_OFFSET(cPop1); \
1778
+ goto Next
1779
+
1780
+ case cJU_JPIMMED_1_02: SM3IMM( 2, SM3Imm1);
1781
+ case cJU_JPIMMED_1_03: SM3IMM( 3, SM3Imm1);
1782
+#if (defined(JUDY1) || defined(JU_64BIT))
1783
+ case cJU_JPIMMED_1_04: SM3IMM( 4, SM3Imm1);
1784
+ case cJU_JPIMMED_1_05: SM3IMM( 5, SM3Imm1);
1785
+ case cJU_JPIMMED_1_06: SM3IMM( 6, SM3Imm1);
1786
+ case cJU_JPIMMED_1_07: SM3IMM( 7, SM3Imm1);
1787
+#endif
1788
+#if (defined(JUDY1) && defined(JU_64BIT))
1789
+ case cJ1_JPIMMED_1_08: SM3IMM( 8, SM3Imm1);
1790
+ case cJ1_JPIMMED_1_09: SM3IMM( 9, SM3Imm1);
1791
+ case cJ1_JPIMMED_1_10: SM3IMM(10, SM3Imm1);
1792
+ case cJ1_JPIMMED_1_11: SM3IMM(11, SM3Imm1);
1793
+ case cJ1_JPIMMED_1_12: SM3IMM(12, SM3Imm1);
1794
+ case cJ1_JPIMMED_1_13: SM3IMM(13, SM3Imm1);
1795
+ case cJ1_JPIMMED_1_14: SM3IMM(14, SM3Imm1);
1796
+ case cJ1_JPIMMED_1_15: SM3IMM(15, SM3Imm1);
1797
+#endif
1798
+
1799
+SM3Imm1: JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
1800
+ JU_RET_FOUND_IMM(Pjp, offset);
1801
+
1802
+#if (defined(JUDY1) || defined(JU_64BIT))
1803
+ case cJU_JPIMMED_2_02: SM3IMM(2, SM3Imm2);
1804
+ case cJU_JPIMMED_2_03: SM3IMM(3, SM3Imm2);
1805
+#endif
1806
+#if (defined(JUDY1) && defined(JU_64BIT))
1807
+ case cJ1_JPIMMED_2_04: SM3IMM(4, SM3Imm2);
1808
+ case cJ1_JPIMMED_2_05: SM3IMM(5, SM3Imm2);
1809
+ case cJ1_JPIMMED_2_06: SM3IMM(6, SM3Imm2);
1810
+ case cJ1_JPIMMED_2_07: SM3IMM(7, SM3Imm2);
1811
+#endif
1812
+
1813
+#if (defined(JUDY1) || defined(JU_64BIT))
1814
+SM3Imm2: *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
1815
+ | ((uint16_t *) PJI)[offset];
1816
+ JU_RET_FOUND_IMM(Pjp, offset);
1817
+#endif
1818
+
1819
+#if (defined(JUDY1) || defined(JU_64BIT))
1820
+ case cJU_JPIMMED_3_02: SM3IMM(2, SM3Imm3);
1821
+#endif
1822
+#if (defined(JUDY1) && defined(JU_64BIT))
1823
+ case cJ1_JPIMMED_3_03: SM3IMM(3, SM3Imm3);
1824
+ case cJ1_JPIMMED_3_04: SM3IMM(4, SM3Imm3);
1825
+ case cJ1_JPIMMED_3_05: SM3IMM(5, SM3Imm3);
1826
+#endif
1827
+
1828
+#if (defined(JUDY1) || defined(JU_64BIT))
1829
+SM3Imm3:
1830
+ {
1831
+ Word_t lsb;
1832
+ JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
1833
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
1834
+ JU_RET_FOUND_IMM(Pjp, offset);
1835
+ }
1836
+#endif
1837
+
1838
+#if (defined(JUDY1) && defined(JU_64BIT))
1839
+ case cJ1_JPIMMED_4_02: SM3IMM(2, SM3Imm4);
1840
+ case cJ1_JPIMMED_4_03: SM3IMM(3, SM3Imm4);
1841
+
1842
+SM3Imm4: *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
1843
+ | ((uint32_t *) PJI)[offset];
1844
+ JU_RET_FOUND_IMM(Pjp, offset);
1845
+
1846
+ case cJ1_JPIMMED_5_02: SM3IMM(2, SM3Imm5);
1847
+ case cJ1_JPIMMED_5_03: SM3IMM(3, SM3Imm5);
1848
+
1849
+SM3Imm5:
1850
+ {
1851
+ Word_t lsb;
1852
+ JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
1853
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
1854
+ JU_RET_FOUND_IMM(Pjp, offset);
1855
+ }
1856
+
1857
+ case cJ1_JPIMMED_6_02: SM3IMM(2, SM3Imm6);
1858
+
1859
+SM3Imm6:
1860
+ {
1861
+ Word_t lsb;
1862
+ JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
1863
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
1864
+ JU_RET_FOUND_IMM(Pjp, offset);
1865
+ }
1866
+
1867
+ case cJ1_JPIMMED_7_02: SM3IMM(2, SM3Imm7);
1868
+
1869
+SM3Imm7:
1870
+ {
1871
+ Word_t lsb;
1872
+ JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
1873
+ *PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
1874
+ JU_RET_FOUND_IMM(Pjp, offset);
1875
+ }
1876
+#endif // (JUDY1 && JU_64BIT)
1877
+
1878
+
1879
+// ----------------------------------------------------------------------------
1880
+// OTHER CASES:
1881
+
1882
+ default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
1883
+ JUDY1CODE(return(JERRI );)
1884
+ JUDYLCODE(return(PPJERR);)
1885
+
1886
+ } // SM3Findlimit switch.
1887
+
1888
+ /*NOTREACHED*/
1889
+
1890
+} // Judy1Prev() / Judy1Next() / JudyLPrev() / JudyLNext()
libnetdata/libjudy/src/JudyL/JudyLPrevEmpty.c
new
+1390
@@ -0,0 +1,1390 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.32 $ $Source: /judy/src/JudyCommon/JudyPrevNextEmpty.c $
19
+//
20
+// Judy*PrevEmpty() and Judy*NextEmpty() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+//
23
+// Compile with -DJUDYNEXT for the Judy*NextEmpty() function; otherwise
24
+// defaults to Judy*PrevEmpty().
25
+//
26
+// Compile with -DTRACEJPSE to trace JP traversals.
27
+//
28
+// This file is separate from JudyPrevNext.c because it differs too greatly for
29
+// ifdefs. This might be a bit surprising, but there are two reasons:
30
+//
31
+// - First, down in the details, searching for an empty index (SearchEmpty) is
32
+// remarkably asymmetric with searching for a valid index (SearchValid),
33
+// mainly with respect to: No return of a value area for JudyL; partially-
34
+// full versus totally-full JPs; and handling of narrow pointers.
35
+//
36
+// - Second, we chose to implement SearchEmpty without a backtrack stack or
37
+// backtrack engine, partly as an experiment, and partly because we think
38
+// restarting from the top of the tree is less likely for SearchEmpty than
39
+// for SearchValid, because empty indexes are more likely than valid indexes.
40
+//
41
+// A word about naming: A prior version of this feature (see 4.13) was named
42
+// Judy*Free(), but there were concerns about that being read as a verb rather
43
+// than an adjective. After prolonged debate and based on user input, we
44
+// changed "Free" to "Empty".
45
+
46
+#if (! (defined(JUDY1) || defined(JUDYL)))
47
+#error: One of -DJUDY1 or -DJUDYL must be specified.
48
+#endif
49
+
50
+#ifndef JUDYNEXT
51
+#ifndef JUDYPREV
52
+#define JUDYPREV 1 // neither set => use default.
53
+#endif
54
+#endif
55
+
56
+#ifdef JUDY1
57
+#include "Judy1.h"
58
+#else
59
+#include "JudyL.h"
60
+#endif
61
+
62
+#include "JudyPrivate1L.h"
63
+
64
+#ifdef TRACEJPSE
65
+#include "JudyPrintJP.c"
66
+#endif
67
+
68
+
69
+// ****************************************************************************
70
+// J U D Y 1 P R E V E M P T Y
71
+// J U D Y 1 N E X T E M P T Y
72
+// J U D Y L P R E V E M P T Y
73
+// J U D Y L N E X T E M P T Y
74
+//
75
+// See the manual entry for the API.
76
+//
77
+// OVERVIEW OF Judy*PrevEmpty() / Judy*NextEmpty():
78
+//
79
+// See also for comparison the equivalent comments in JudyPrevNext.c.
80
+//
81
+// Take the callers *PIndex and subtract/add 1, but watch out for
82
+// underflow/overflow, which means "no previous/next empty index found." Use a
83
+// reentrant switch statement (state machine, see SMGetRestart and
84
+// SMGetContinue) to decode Index, starting with the JRP (PArray), through a
85
+// JPM and branches, if any, down to an immediate or a leaf. Look for Index in
86
+// that immediate or leaf, and if not found (invalid index), return success
87
+// (Index is empty).
88
+//
89
+// This search can result in a dead end where taking a different path is
90
+// required. There are four kinds of dead ends:
91
+//
92
+// BRANCH PRIMARY dead end: Encountering a fully-populated JP for the
93
+// appropriate digit in Index. Search sideways in the branch for the
94
+// previous/next absent/null/non-full JP, and if one is found, set Index to the
95
+// highest/lowest index possible in that JPs expanse. Then if the JP is an
96
+// absent or null JP, return success; otherwise for a non-full JP, traverse
97
+// through the partially populated JP.
98
+//
99
+// BRANCH SECONDARY dead end: Reaching the end of a branch during a sideways
100
+// search after a branch primary dead end. Set Index to the lowest/highest
101
+// index possible in the whole branchs expanse (one higher/lower than the
102
+// previous/next branchs expanse), then restart at the top of the tree, which
103
+// includes pre-decrementing/incrementing Index (again) and watching for
104
+// underflow/overflow (again).
105
+//
106
+// LEAF PRIMARY dead end: Finding a valid (non-empty) index in an immediate or
107
+// leaf matching Index. Search sideways in the immediate/leaf for the
108
+// previous/next empty index; if found, set *PIndex to match and return success.
109
+//
110
+// LEAF SECONDARY dead end: Reaching the end of an immediate or leaf during a
111
+// sideways search after a leaf primary dead end. Just as for a branch
112
+// secondary dead end, restart at the top of the tree with Index set to the
113
+// lowest/highest index possible in the whole immediate/leafs expanse.
114
+// TBD: If leaf secondary dead end occurs, could shortcut and treat it as a
115
+// branch primary dead end; but this would require remembering the parent
116
+// branchs type and offset (a "one-deep stack"), and also wrestling with
117
+// narrow pointers, at least for leaves (but not for immediates).
118
+//
119
+// Note some ASYMMETRIES between SearchValid and SearchEmpty:
120
+//
121
+// - The SearchValid code, upon descending through a narrow pointer, if Index
122
+// is outside the expanse of the subsidiary node (effectively a secondary
123
+// dead end), must decide whether to backtrack or findlimit. But the
124
+// SearchEmpty code simply returns success (Index is empty).
125
+//
126
+// - Similarly, the SearchValid code, upon finding no previous/next index in
127
+// the expanse of a narrow pointer (again, a secondary dead end), can simply
128
+// start to backtrack at the parent JP. But the SearchEmpty code would have
129
+// to first determine whether or not the parent JPs narrow expanse contains
130
+// a previous/next empty index outside the subexpanse. Rather than keeping a
131
+// parent state stack and backtracking this way, upon a secondary dead end,
132
+// the SearchEmpty code simply restarts at the top of the tree, whether or
133
+// not a narrow pointer is involved. Again, see the equivalent comments in
134
+// JudyPrevNext.c for comparison.
135
+//
136
+// This function is written iteratively for speed, rather than recursively.
137
+//
138
+// TBD: Wed like to enhance this function to make successive searches faster.
139
+// This would require saving some previous state, including the previous Index
140
+// returned, and in which leaf it was found. If the next call is for the same
141
+// Index and the array has not been modified, start at the same leaf. This
142
+// should be much easier to implement since this is iterative rather than
143
+// recursive code.
144
+
145
+#ifdef JUDY1
146
+#ifdef JUDYPREV
147
+FUNCTION int Judy1PrevEmpty
148
+#else
149
+FUNCTION int Judy1NextEmpty
150
+#endif
151
+#else
152
+#ifdef JUDYPREV
153
+FUNCTION int JudyLPrevEmpty
154
+#else
155
+FUNCTION int JudyLNextEmpty
156
+#endif
157
+#endif
158
+ (
159
+ Pcvoid_t PArray, // Judy array to search.
160
+ Word_t * PIndex, // starting point and result.
161
+ PJError_t PJError // optional, for returning error info.
162
+ )
163
+{
164
+ Word_t Index; // fast copy, in a register.
165
+ Pjp_t Pjp; // current JP.
166
+ Pjbl_t Pjbl; // Pjp->jp_Addr masked and cast to types:
167
+ Pjbb_t Pjbb;
168
+ Pjbu_t Pjbu;
169
+ Pjlb_t Pjlb;
170
+ PWord_t Pword; // alternate name for use by GET* macros.
171
+
172
+ Word_t digit; // next digit to decode from Index.
173
+ Word_t digits; // current state in SM = digits left to decode.
174
+ Word_t pop0; // in a leaf.
175
+ Word_t pop0mask; // precalculated to avoid variable shifts.
176
+ long offset; // within a branch or leaf (can be large).
177
+ int subexp; // subexpanse in a bitmap branch.
178
+ BITMAPB_t bitposmaskB; // bit in bitmap for bitmap branch.
179
+ BITMAPL_t bitposmaskL; // bit in bitmap for bitmap leaf.
180
+ Word_t possfullJP1; // JP types for possibly full subexpanses:
181
+ Word_t possfullJP2;
182
+ Word_t possfullJP3;
183
+
184
+
185
+// ----------------------------------------------------------------------------
186
+// M A C R O S
187
+//
188
+// These are intended to make the code a bit more readable and less redundant.
189
+
190
+
191
+// CHECK FOR NULL JP:
192
+//
193
+// TBD: In principle this can be reduced (here and in other *.c files) to just
194
+// the latter clause since no Type should ever be below cJU_JPNULL1, but in
195
+// fact some root pointer types can be lower, so for safety do both checks.
196
+
197
+#define JPNULL(Type) (((Type) >= cJU_JPNULL1) && ((Type) <= cJU_JPNULLMAX))
198
+
199
+
200
+// CHECK FOR A FULL JP:
201
+//
202
+// Given a JP, indicate if it is fully populated. Use digits, pop0mask, and
203
+// possfullJP1..3 in the context.
204
+//
205
+// This is a difficult problem because it requires checking the Pop0 bits for
206
+// all-ones, but the number of bytes depends on the JP type, which is not
207
+// directly related to the parent branchs type or level -- the JPs child
208
+// could be under a narrow pointer (hence not full). The simple answer
209
+// requires switching on or otherwise calculating the JP type, which could be
210
+// slow. Instead, in SMPREPB* precalculate pop0mask and also record in
211
+// possfullJP1..3 the child JP (branch) types that could possibly be full (one
212
+// level down), and use them here. For level-2 branches (with digits == 2),
213
+// the test for a full child depends on Judy1/JudyL.
214
+//
215
+// Note: This cannot be applied to the JP in a JPM because it doesnt have
216
+// enough pop0 digits.
217
+//
218
+// TBD: JPFULL_BRANCH diligently checks for BranchL or BranchB, where neither
219
+// of those can ever be full as it turns out. Could just check for a BranchU
220
+// at the right level. Also, pop0mask might be overkill, its not used much,
221
+// so perhaps just call cJU_POP0MASK(digits - 1) here?
222
+//
223
+// First, JPFULL_BRANCH checks for a full expanse for a JP whose child can be a
224
+// branch, that is, a JP in a branch at level 3 or higher:
225
+
226
+#define JPFULL_BRANCH(Pjp) \
227
+ ((((JU_JPDCDPOP0(Pjp) ^ cJU_ALLONES) & pop0mask) == 0) \
228
+ && ((JU_JPTYPE(Pjp) == possfullJP1) \
229
+ || (JU_JPTYPE(Pjp) == possfullJP2) \
230
+ || (JU_JPTYPE(Pjp) == possfullJP3)))
231
+
232
+#ifdef JUDY1
233
+#define JPFULL(Pjp) \
234
+ ((digits == 2) ? \
235
+ (JU_JPTYPE(Pjp) == cJ1_JPFULLPOPU1) : JPFULL_BRANCH(Pjp))
236
+#else
237
+#define JPFULL(Pjp) \
238
+ ((digits == 2) ? \
239
+ (JU_JPTYPE(Pjp) == cJU_JPLEAF_B1) \
240
+ && (((JU_JPDCDPOP0(Pjp) & cJU_POP0MASK(1)) == cJU_POP0MASK(1))) : \
241
+ JPFULL_BRANCH(Pjp))
242
+#endif
243
+
244
+
245
+// RETURN SUCCESS:
246
+//
247
+// This hides the need to set *PIndex back to the local value of Index -- use a
248
+// local value for faster operation. Note that the callers *PIndex is ALWAYS
249
+// modified upon success, at least decremented/incremented.
250
+
251
+#define RET_SUCCESS { *PIndex = Index; return(1); }
252
+
253
+
254
+// RETURN A CORRUPTION:
255
+
256
+#define RET_CORRUPT { JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); return(JERRI); }
257
+
258
+
259
+// SEARCH A BITMAP BRANCH:
260
+//
261
+// This is a weak analog of j__udySearchLeaf*() for bitmap branches. Return
262
+// the actual or next-left position, base 0, of Digit in a BITMAPB_t bitmap
263
+// (subexpanse of a full bitmap), also given a Bitposmask for Digit. The
264
+// position is the offset within the set bits.
265
+//
266
+// Unlike j__udySearchLeaf*(), the offset is not returned bit-complemented if
267
+// Digits bit is unset, because the caller can check the bitmap themselves to
268
+// determine that. Also, if Digits bit is unset, the returned offset is to
269
+// the next-left JP or index (including -1), not to the "ideal" position for
270
+// the index = next-right JP or index.
271
+//
272
+// Shortcut and skip calling j__udyCountBitsB() if the bitmap is full, in which
273
+// case (Digit % cJU_BITSPERSUBEXPB) itself is the base-0 offset.
274
+
275
+#define SEARCHBITMAPB(Bitmap,Digit,Bitposmask) \
276
+ (((Bitmap) == cJU_FULLBITMAPB) ? (Digit % cJU_BITSPERSUBEXPB) : \
277
+ j__udyCountBitsB((Bitmap) & JU_MASKLOWERINC(Bitposmask)) - 1)
278
+
279
+#ifdef JUDYPREV
280
+// Equivalent to search for the highest offset in Bitmap, that is, one less
281
+// than the number of bits set:
282
+
283
+#define SEARCHBITMAPMAXB(Bitmap) \
284
+ (((Bitmap) == cJU_FULLBITMAPB) ? cJU_BITSPERSUBEXPB - 1 : \
285
+ j__udyCountBitsB(Bitmap) - 1)
286
+#endif
287
+
288
+
289
+// CHECK DECODE BYTES:
290
+//
291
+// Check Decode bytes in a JP against the equivalent portion of Index. If they
292
+// dont match, Index is outside the subexpanse of a narrow pointer, hence is
293
+// empty.
294
+
295
+#define CHECKDCD(cDigits) \
296
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, cDigits)) RET_SUCCESS
297
+
298
+
299
+// REVISE REMAINDER OF INDEX:
300
+//
301
+// Put one digit in place in Index and clear/set the lower digits, if any, so
302
+// the resulting Index is at the start/end of an expanse, or just clear/set the
303
+// least digits.
304
+//
305
+// Actually, to make simple use of JU_LEASTBYTESMASK, first clear/set all least
306
+// digits of Index including the digit to be overridden, then set the value of
307
+// that one digit. If Digits == 1 the first operation is redundant, but either
308
+// very fast or even removed by the optimizer.
309
+
310
+#define CLEARLEASTDIGITS(Digits) Index &= ~JU_LEASTBYTESMASK(Digits)
311
+#define SETLEASTDIGITS( Digits) Index |= JU_LEASTBYTESMASK(Digits)
312
+
313
+#define CLEARLEASTDIGITS_D(Digit,Digits) \
314
+ { \
315
+ CLEARLEASTDIGITS(Digits); \
316
+ JU_SETDIGIT(Index, Digit, Digits); \
317
+ }
318
+
319
+#define SETLEASTDIGITS_D(Digit,Digits) \
320
+ { \
321
+ SETLEASTDIGITS(Digits); \
322
+ JU_SETDIGIT(Index, Digit, Digits); \
323
+ }
324
+
325
+
326
+// SET REMAINDER OF INDEX AND THEN RETURN OR CONTINUE:
327
+
328
+#define SET_AND_RETURN(OpLeastDigits,Digit,Digits) \
329
+ { \
330
+ OpLeastDigits(Digit, Digits); \
331
+ RET_SUCCESS; \
332
+ }
333
+
334
+#define SET_AND_CONTINUE(OpLeastDigits,Digit,Digits) \
335
+ { \
336
+ OpLeastDigits(Digit, Digits); \
337
+ goto SMGetContinue; \
338
+ }
339
+
340
+
341
+// PREPARE TO HANDLE A LEAFW OR JP BRANCH IN THE STATE MACHINE:
342
+//
343
+// Extract a state-dependent digit from Index in a "constant" way, then jump to
344
+// common code for multiple cases.
345
+//
346
+// TBD: Should this macro do more, such as preparing variable-shift masks for
347
+// use in CLEARLEASTDIGITS and SETLEASTDIGITS?
348
+
349
+#define SMPREPB(cDigits,Next,PossFullJP1,PossFullJP2,PossFullJP3) \
350
+ digits = (cDigits); \
351
+ digit = JU_DIGITATSTATE(Index, cDigits); \
352
+ pop0mask = cJU_POP0MASK((cDigits) - 1); /* for branchs JPs */ \
353
+ possfullJP1 = (PossFullJP1); \
354
+ possfullJP2 = (PossFullJP2); \
355
+ possfullJP3 = (PossFullJP3); \
356
+ goto Next
357
+
358
+// Variations for specific-level branches and for shorthands:
359
+//
360
+// Note: SMPREPB2 need not initialize possfullJP* because JPFULL does not use
361
+// them for digits == 2, but gcc -Wall isnt quite smart enough to see this, so
362
+// waste a bit of time and space to get rid of the warning:
363
+
364
+#define SMPREPB2(Next) \
365
+ digits = 2; \
366
+ digit = JU_DIGITATSTATE(Index, 2); \
367
+ pop0mask = cJU_POP0MASK(1); /* for branchs JPs */ \
368
+ possfullJP1 = possfullJP2 = possfullJP3 = 0; \
369
+ goto Next
370
+
371
+#define SMPREPB3(Next) SMPREPB(3, Next, cJU_JPBRANCH_L2, \
372
+ cJU_JPBRANCH_B2, \
373
+ cJU_JPBRANCH_U2)
374
+#ifndef JU_64BIT
375
+#define SMPREPBL(Next) SMPREPB(cJU_ROOTSTATE, Next, cJU_JPBRANCH_L3, \
376
+ cJU_JPBRANCH_B3, \
377
+ cJU_JPBRANCH_U3)
378
+#else
379
+#define SMPREPB4(Next) SMPREPB(4, Next, cJU_JPBRANCH_L3, \
380
+ cJU_JPBRANCH_B3, \
381
+ cJU_JPBRANCH_U3)
382
+#define SMPREPB5(Next) SMPREPB(5, Next, cJU_JPBRANCH_L4, \
383
+ cJU_JPBRANCH_B4, \
384
+ cJU_JPBRANCH_U4)
385
+#define SMPREPB6(Next) SMPREPB(6, Next, cJU_JPBRANCH_L5, \
386
+ cJU_JPBRANCH_B5, \
387
+ cJU_JPBRANCH_U5)
388
+#define SMPREPB7(Next) SMPREPB(7, Next, cJU_JPBRANCH_L6, \
389
+ cJU_JPBRANCH_B6, \
390
+ cJU_JPBRANCH_U6)
391
+#define SMPREPBL(Next) SMPREPB(cJU_ROOTSTATE, Next, cJU_JPBRANCH_L7, \
392
+ cJU_JPBRANCH_B7, \
393
+ cJU_JPBRANCH_U7)
394
+#endif
395
+
396
+
397
+// RESTART AFTER SECONDARY DEAD END:
398
+//
399
+// Set Index to the first/last index in the branch or leaf subexpanse and start
400
+// over at the top of the tree.
401
+
402
+#ifdef JUDYPREV
403
+#define SMRESTART(Digits) { CLEARLEASTDIGITS(Digits); goto SMGetRestart; }
404
+#else
405
+#define SMRESTART(Digits) { SETLEASTDIGITS( Digits); goto SMGetRestart; }
406
+#endif
407
+
408
+
409
+// CHECK EDGE OF LEAFS EXPANSE:
410
+//
411
+// Given the LSBs of the lowest/highest valid index in a leaf (or equivalently
412
+// in an immediate JP), the level (index size) of the leaf, and the full index
413
+// to return (as Index in the context) already set to the full index matching
414
+// the lowest/highest one, determine if there is an empty index in the leafs
415
+// expanse below/above the lowest/highest index, which is true if the
416
+// lowest/highest index is not at the "edge" of the leafs expanse based on its
417
+// LSBs. If so, return Index decremented/incremented; otherwise restart at the
418
+// top of the tree.
419
+//
420
+// Note: In many cases Index is already at the right spot and calling
421
+// SMRESTART instead of just going directly to SMGetRestart is a bit of
422
+// overkill.
423
+//
424
+// Note: Variable shift occurs if Digits is not a constant.
425
+
426
+#ifdef JUDYPREV
427
+#define LEAF_EDGE(MinIndex,Digits) \
428
+ { \
429
+ if (MinIndex) { --Index; RET_SUCCESS; } \
430
+ SMRESTART(Digits); \
431
+ }
432
+#else
433
+#define LEAF_EDGE(MaxIndex,Digits) \
434
+ { \
435
+ if ((MaxIndex) != JU_LEASTBYTES(cJU_ALLONES, Digits)) \
436
+ { ++Index; RET_SUCCESS; } \
437
+ SMRESTART(Digits); \
438
+ }
439
+#endif
440
+
441
+// Same as above except Index is not already set to match the lowest/highest
442
+// index, so do that before decrementing/incrementing it:
443
+
444
+#ifdef JUDYPREV
445
+#define LEAF_EDGE_SET(MinIndex,Digits) \
446
+ { \
447
+ if (MinIndex) \
448
+ { JU_SETDIGITS(Index, MinIndex, Digits); --Index; RET_SUCCESS; } \
449
+ SMRESTART(Digits); \
450
+ }
451
+#else
452
+#define LEAF_EDGE_SET(MaxIndex,Digits) \
453
+ { \
454
+ if ((MaxIndex) != JU_LEASTBYTES(cJU_ALLONES, Digits)) \
455
+ { JU_SETDIGITS(Index, MaxIndex, Digits); ++Index; RET_SUCCESS; } \
456
+ SMRESTART(Digits); \
457
+ }
458
+#endif
459
+
460
+
461
+// FIND A HOLE (EMPTY INDEX) IN AN IMMEDIATE OR LEAF:
462
+//
463
+// Given an index location in a leaf (or equivalently an immediate JP) known to
464
+// contain a usable hole (an empty index less/greater than Index), and the LSBs
465
+// of a minimum/maximum index to locate, find the previous/next empty index and
466
+// return it.
467
+//
468
+// Note: "Even" index sizes (1,2,4[,8] bytes) have corresponding native C
469
+// types; "odd" index sizes dont, but they are not represented here because
470
+// they are handled completely differently; see elsewhere.
471
+
472
+#ifdef JUDYPREV
473
+
474
+#define LEAF_HOLE_EVEN(cDigits,Pjll,IndexLSB) \
475
+ { \
476
+ while (*(Pjll) > (IndexLSB)) --(Pjll); /* too high */ \
477
+ if (*(Pjll) < (IndexLSB)) RET_SUCCESS /* Index is empty */ \
478
+ while (*(--(Pjll)) == --(IndexLSB)) /* null, find a hole */;\
479
+ JU_SETDIGITS(Index, IndexLSB, cDigits); \
480
+ RET_SUCCESS; \
481
+ }
482
+#else
483
+#define LEAF_HOLE_EVEN(cDigits,Pjll,IndexLSB) \
484
+ { \
485
+ while (*(Pjll) < (IndexLSB)) ++(Pjll); /* too low */ \
486
+ if (*(Pjll) > (IndexLSB)) RET_SUCCESS /* Index is empty */ \
487
+ while (*(++(Pjll)) == ++(IndexLSB)) /* null, find a hole */;\
488
+ JU_SETDIGITS(Index, IndexLSB, cDigits); \
489
+ RET_SUCCESS; \
490
+ }
491
+#endif
492
+
493
+
494
+// SEARCH FOR AN EMPTY INDEX IN AN IMMEDIATE OR LEAF:
495
+//
496
+// Given a pointer to the first index in a leaf (or equivalently an immediate
497
+// JP), the population of the leaf, and a first empty Index to find (inclusive,
498
+// as Index in the context), where Index is known to fall within the expanse of
499
+// the leaf to search, efficiently find the previous/next empty index in the
500
+// leaf, if any. For simplicity the following overview is stated in terms of
501
+// Judy*NextEmpty() only, but the same concepts apply symmetrically for
502
+// Judy*PrevEmpty(). Also, in each case the comparisons are for the LSBs of
503
+// Index and leaf indexes, according to the leafs level.
504
+//
505
+// 1. If Index is GREATER than the last (highest) index in the leaf
506
+// (maxindex), return success, Index is empty. (Remember, Index is known
507
+// to be in the leafs expanse.)
508
+//
509
+// 2. If Index is EQUAL to maxindex: If maxindex is not at the edge of the
510
+// leafs expanse, increment Index and return success, there is an empty
511
+// Index one higher than any in the leaf; otherwise restart with Index
512
+// reset to the upper edge of the leafs expanse. Note: This might cause
513
+// an extra cache line fill, but this is OK for repeatedly-called search
514
+// code, and it saves CPU time.
515
+//
516
+// 3. If Index is LESS than maxindex, check for "dense to end of leaf":
517
+// Subtract Index from maxindex, and back up that many slots in the leaf.
518
+// If the resulting offset is not before the start of the leaf then compare
519
+// the index at this offset (baseindex) with Index:
520
+//
521
+// 3a. If GREATER, the leaf must be corrupt, since indexes are sorted and
522
+// there are no duplicates.
523
+//
524
+// 3b. If EQUAL, the leaf is "dense" from Index to maxindex, meaning there is
525
+// no reason to search it. "Slide right" to the high end of the leaf
526
+// (modify Index to maxindex) and continue with step 2 above.
527
+//
528
+// 3c. If LESS, continue with step 4.
529
+//
530
+// 4. If the offset based on maxindex minus Index falls BEFORE the start of
531
+// the leaf, or if, per 3c above, baseindex is LESS than Index, the leaf is
532
+// guaranteed "not dense to the end" and a usable empty Index must exist.
533
+// This supports a more efficient search loop. Start at the FIRST index in
534
+// the leaf, or one BEYOND baseindex, respectively, and search the leaf as
535
+// follows, comparing each current index (currindex) with Index:
536
+//
537
+// 4a. If LESS, keep going to next index. Note: This is certain to terminate
538
+// because maxindex is known to be greater than Index, hence the loop can
539
+// be small and fast.
540
+//
541
+// 4b. If EQUAL, loop and increment Index until finding currindex greater than
542
+// Index, and return success with the modified Index.
543
+//
544
+// 4c. If GREATER, return success, Index (unmodified) is empty.
545
+//
546
+// Note: These are macros rather than functions for speed.
547
+
548
+#ifdef JUDYPREV
549
+
550
+#define JSLE_EVEN(Addr,Pop0,cDigits,LeafType) \
551
+ { \
552
+ LeafType * PjllLSB = (LeafType *) (Addr); \
553
+ LeafType IndexLSB = Index; /* auto-masking */ \
554
+ \
555
+ /* Index before or at start of leaf: */ \
556
+ \
557
+ if (*PjllLSB >= IndexLSB) /* no need to search */ \
558
+ { \
559
+ if (*PjllLSB > IndexLSB) RET_SUCCESS; /* Index empty */ \
560
+ LEAF_EDGE(*PjllLSB, cDigits); \
561
+ } \
562
+ \
563
+ /* Index in or after leaf: */ \
564
+ \
565
+ offset = IndexLSB - *PjllLSB; /* tentative offset */ \
566
+ if (offset <= (Pop0)) /* can check density */ \
567
+ { \
568
+ PjllLSB += offset; /* move to slot */ \
569
+ \
570
+ if (*PjllLSB <= IndexLSB) /* dense or corrupt */ \
571
+ { \
572
+ if (*PjllLSB == IndexLSB) /* dense, check edge */ \
573
+ LEAF_EDGE_SET(PjllLSB[-offset], cDigits); \
574
+ RET_CORRUPT; \
575
+ } \
576
+ --PjllLSB; /* not dense, start at previous */ \
577
+ } \
578
+ else PjllLSB = ((LeafType *) (Addr)) + (Pop0); /* start at max */ \
579
+ \
580
+ LEAF_HOLE_EVEN(cDigits, PjllLSB, IndexLSB); \
581
+ }
582
+
583
+// JSLE_ODD is completely different from JSLE_EVEN because its important to
584
+// minimize copying odd indexes to compare them (see 4.14). Furthermore, a
585
+// very complex version (4.17, but abandoned before fully debugged) that
586
+// avoided calling j__udySearchLeaf*() ran twice as fast as 4.14, but still
587
+// half as fast as SearchValid. Doug suggested that to minimize complexity and
588
+// share common code we should use j__udySearchLeaf*() for the initial search
589
+// to establish if Index is empty, which should be common. If Index is valid
590
+// in a leaf or immediate indexes, odds are good that an empty Index is nearby,
591
+// so for simplicity just use a *COPY* function to linearly search the
592
+// remainder.
593
+//
594
+// TBD: Pathological case? Average performance should be good, but worst-case
595
+// might suffer. When Search says the initial Index is valid, so a linear
596
+// copy-and-compare is begun, if the caller builds fairly large leaves with
597
+// dense clusters AND frequently does a SearchEmpty at one end of such a
598
+// cluster, performance wont be very good. Might a dense-check help? This
599
+// means checking offset against the index at offset, and then against the
600
+// first/last index in the leaf. We doubt the pathological case will appear
601
+// much in real applications because they will probably alternate SearchValid
602
+// and SearchEmpty calls.
603
+
604
+#define JSLE_ODD(cDigits,Pjll,Pop0,Search,Copy) \
605
+ { \
606
+ Word_t IndexLSB; /* least bytes only */ \
607
+ Word_t IndexFound; /* in leaf */ \
608
+ \
609
+ if ((offset = Search(Pjll, (Pop0) + 1, Index)) < 0) \
610
+ RET_SUCCESS; /* Index is empty */ \
611
+ \
612
+ IndexLSB = JU_LEASTBYTES(Index, cDigits); \
613
+ offset *= (cDigits); \
614
+ \
615
+ while ((offset -= (cDigits)) >= 0) \
616
+ { /* skip until empty or start */ \
617
+ Copy(IndexFound, ((uint8_t *) (Pjll)) + offset); \
618
+ if (IndexFound != (--IndexLSB)) /* found an empty */ \
619
+ { JU_SETDIGITS(Index, IndexLSB, cDigits); RET_SUCCESS; }\
620
+ } \
621
+ LEAF_EDGE_SET(IndexLSB, cDigits); \
622
+ }
623
+
624
+#else // JUDYNEXT
625
+
626
+#define JSLE_EVEN(Addr,Pop0,cDigits,LeafType) \
627
+ { \
628
+ LeafType * PjllLSB = ((LeafType *) (Addr)) + (Pop0); \
629
+ LeafType IndexLSB = Index; /* auto-masking */ \
630
+ \
631
+ /* Index at or after end of leaf: */ \
632
+ \
633
+ if (*PjllLSB <= IndexLSB) /* no need to search */ \
634
+ { \
635
+ if (*PjllLSB < IndexLSB) RET_SUCCESS; /* Index empty */\
636
+ LEAF_EDGE(*PjllLSB, cDigits); \
637
+ } \
638
+ \
639
+ /* Index before or in leaf: */ \
640
+ \
641
+ offset = *PjllLSB - IndexLSB; /* tentative offset */ \
642
+ if (offset <= (Pop0)) /* can check density */ \
643
+ { \
644
+ PjllLSB -= offset; /* move to slot */ \
645
+ \
646
+ if (*PjllLSB >= IndexLSB) /* dense or corrupt */ \
647
+ { \
648
+ if (*PjllLSB == IndexLSB) /* dense, check edge */ \
649
+ LEAF_EDGE_SET(PjllLSB[offset], cDigits); \
650
+ RET_CORRUPT; \
651
+ } \
652
+ ++PjllLSB; /* not dense, start at next */ \
653
+ } \
654
+ else PjllLSB = (LeafType *) (Addr); /* start at minimum */ \
655
+ \
656
+ LEAF_HOLE_EVEN(cDigits, PjllLSB, IndexLSB); \
657
+ }
658
+
659
+#define JSLE_ODD(cDigits,Pjll,Pop0,Search,Copy) \
660
+ { \
661
+ Word_t IndexLSB; /* least bytes only */ \
662
+ Word_t IndexFound; /* in leaf */ \
663
+ int offsetmax; /* in bytes */ \
664
+ \
665
+ if ((offset = Search(Pjll, (Pop0) + 1, Index)) < 0) \
666
+ RET_SUCCESS; /* Index is empty */ \
667
+ \
668
+ IndexLSB = JU_LEASTBYTES(Index, cDigits); \
669
+ offset *= (cDigits); \
670
+ offsetmax = (Pop0) * (cDigits); /* single multiply */ \
671
+ \
672
+ while ((offset += (cDigits)) <= offsetmax) \
673
+ { /* skip until empty or end */ \
674
+ Copy(IndexFound, ((uint8_t *) (Pjll)) + offset); \
675
+ if (IndexFound != (++IndexLSB)) /* found an empty */ \
676
+ { JU_SETDIGITS(Index, IndexLSB, cDigits); RET_SUCCESS; } \
677
+ } \
678
+ LEAF_EDGE_SET(IndexLSB, cDigits); \
679
+ }
680
+
681
+#endif // JUDYNEXT
682
+
683
+// Note: Immediate indexes never fill a single index group, so for odd index
684
+// sizes, save time by calling JSLE_ODD_IMM instead of JSLE_ODD.
685
+
686
+#define j__udySearchLeafEmpty1(Addr,Pop0) \
687
+ JSLE_EVEN(Addr, Pop0, 1, uint8_t)
688
+
689
+#define j__udySearchLeafEmpty2(Addr,Pop0) \
690
+ JSLE_EVEN(Addr, Pop0, 2, uint16_t)
691
+
692
+#define j__udySearchLeafEmpty3(Addr,Pop0) \
693
+ JSLE_ODD(3, Addr, Pop0, j__udySearchLeaf3, JU_COPY3_PINDEX_TO_LONG)
694
+
695
+#ifndef JU_64BIT
696
+
697
+#define j__udySearchLeafEmptyL(Addr,Pop0) \
698
+ JSLE_EVEN(Addr, Pop0, 4, Word_t)
699
+
700
+#else
701
+
702
+#define j__udySearchLeafEmpty4(Addr,Pop0) \
703
+ JSLE_EVEN(Addr, Pop0, 4, uint32_t)
704
+
705
+#define j__udySearchLeafEmpty5(Addr,Pop0) \
706
+ JSLE_ODD(5, Addr, Pop0, j__udySearchLeaf5, JU_COPY5_PINDEX_TO_LONG)
707
+
708
+#define j__udySearchLeafEmpty6(Addr,Pop0) \
709
+ JSLE_ODD(6, Addr, Pop0, j__udySearchLeaf6, JU_COPY6_PINDEX_TO_LONG)
710
+
711
+#define j__udySearchLeafEmpty7(Addr,Pop0) \
712
+ JSLE_ODD(7, Addr, Pop0, j__udySearchLeaf7, JU_COPY7_PINDEX_TO_LONG)
713
+
714
+#define j__udySearchLeafEmptyL(Addr,Pop0) \
715
+ JSLE_EVEN(Addr, Pop0, 8, Word_t)
716
+
717
+#endif // JU_64BIT
718
+
719
+
720
+// ----------------------------------------------------------------------------
721
+// START OF CODE:
722
+//
723
+// CHECK FOR SHORTCUTS:
724
+//
725
+// Error out if PIndex is null.
726
+
727
+ if (PIndex == (PWord_t) NULL)
728
+ {
729
+ JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
730
+ return(JERRI);
731
+ }
732
+
733
+ Index = *PIndex; // fast local copy.
734
+
735
+// Set and pre-decrement/increment Index, watching for underflow/overflow:
736
+//
737
+// An out-of-bounds Index means failure: No previous/next empty index.
738
+
739
+SMGetRestart: // return here with revised Index.
740
+
741
+#ifdef JUDYPREV
742
+ if (Index-- == 0) return(0);
743
+#else
744
+ if (++Index == 0) return(0);
745
+#endif
746
+
747
+// An empty array with an in-bounds (not underflowed/overflowed) Index means
748
+// success:
749
+//
750
+// Note: This check is redundant after restarting at SMGetRestart, but should
751
+// take insignificant time.
752
+
753
+ if (PArray == (Pvoid_t) NULL) RET_SUCCESS;
754
+
755
+// ----------------------------------------------------------------------------
756
+// ROOT-LEVEL LEAF that starts with a Pop0 word; just look within the leaf:
757
+//
758
+// If Index is not in the leaf, return success; otherwise return the first
759
+// empty Index, if any, below/above where it would belong.
760
+
761
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
762
+ {
763
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
764
+ pop0 = Pjlw[0];
765
+
766
+#ifdef JUDY1
767
+ if (pop0 == 0) // special case.
768
+ {
769
+#ifdef JUDYPREV
770
+ if ((Index != Pjlw[1]) || (Index-- != 0)) RET_SUCCESS;
771
+#else
772
+ if ((Index != Pjlw[1]) || (++Index != 0)) RET_SUCCESS;
773
+#endif
774
+ return(0); // no previous/next empty index.
775
+ }
776
+#endif // JUDY1
777
+
778
+ j__udySearchLeafEmptyL(Pjlw + 1, pop0);
779
+
780
+// No return -- thanks ALAN
781
+
782
+ }
783
+ else
784
+
785
+// ----------------------------------------------------------------------------
786
+// HANDLE JRP Branch:
787
+//
788
+// For JRP branches, traverse the JPM; handle LEAFW
789
+// directly; but look for the most common cases first.
790
+
791
+ {
792
+ Pjpm_t Pjpm = P_JPM(PArray);
793
+ Pjp = &(Pjpm->jpm_JP);
794
+
795
+// goto SMGetContinue;
796
+ }
797
+
798
+
799
+// ============================================================================
800
+// STATE MACHINE -- GET INDEX:
801
+//
802
+// Search for Index (already decremented/incremented so as to be an inclusive
803
+// search). If not found (empty index), return success. Otherwise do a
804
+// previous/next search, and if successful modify Index to the empty index
805
+// found. See function header comments.
806
+//
807
+// ENTRY: Pjp points to next JP to interpret, whose Decode bytes have not yet
808
+// been checked.
809
+//
810
+// Note: Check Decode bytes at the start of each loop, not after looking up a
811
+// new JP, so its easy to do constant shifts/masks.
812
+//
813
+// EXIT: Return, or branch to SMGetRestart with modified Index, or branch to
814
+// SMGetContinue with a modified Pjp, as described elsewhere.
815
+//
816
+// WARNING: For run-time efficiency the following cases replicate code with
817
+// varying constants, rather than using common code with variable values!
818
+
819
+SMGetContinue: // return here for next branch/leaf.
820
+
821
+#ifdef TRACEJPSE
822
+ JudyPrintJP(Pjp, "sf", __LINE__);
823
+#endif
824
+
825
+ switch (JU_JPTYPE(Pjp))
826
+ {
827
+
828
+
829
+// ----------------------------------------------------------------------------
830
+// LINEAR BRANCH:
831
+//
832
+// Check Decode bytes, if any, in the current JP, then search for a JP for the
833
+// next digit in Index.
834
+
835
+ case cJU_JPBRANCH_L2: CHECKDCD(2); SMPREPB2(SMBranchL);
836
+ case cJU_JPBRANCH_L3: CHECKDCD(3); SMPREPB3(SMBranchL);
837
+#ifdef JU_64BIT
838
+ case cJU_JPBRANCH_L4: CHECKDCD(4); SMPREPB4(SMBranchL);
839
+ case cJU_JPBRANCH_L5: CHECKDCD(5); SMPREPB5(SMBranchL);
840
+ case cJU_JPBRANCH_L6: CHECKDCD(6); SMPREPB6(SMBranchL);
841
+ case cJU_JPBRANCH_L7: CHECKDCD(7); SMPREPB7(SMBranchL);
842
+#endif
843
+ case cJU_JPBRANCH_L: SMPREPBL(SMBranchL);
844
+
845
+// Common code (state-independent) for all cases of linear branches:
846
+
847
+SMBranchL:
848
+ Pjbl = P_JBL(Pjp->jp_Addr);
849
+
850
+// First, check if Indexs expanse (digit) is below/above the first/last
851
+// populated expanse in the BranchL, in which case Index is empty; otherwise
852
+// find the offset of the lowest/highest populated expanse at or above/below
853
+// digit, if any:
854
+//
855
+// Note: The for-loop is guaranteed to exit eventually because the first/last
856
+// expanse is known to be a terminator.
857
+//
858
+// Note: Cannot use j__udySearchLeaf*Empty1() here because it only applies to
859
+// leaves and does not know about partial versus full JPs, unlike the use of
860
+// j__udySearchLeaf1() for BranchLs in SearchValid code. Also, since linear
861
+// leaf expanse lists are small, dont waste time calling j__udySearchLeaf1(),
862
+// just scan the expanse list.
863
+
864
+#ifdef JUDYPREV
865
+ if ((Pjbl->jbl_Expanse[0]) > digit) RET_SUCCESS;
866
+
867
+ for (offset = (Pjbl->jbl_NumJPs) - 1; /* null */; --offset)
868
+#else
869
+ if ((Pjbl->jbl_Expanse[(Pjbl->jbl_NumJPs) - 1]) < digit)
870
+ RET_SUCCESS;
871
+
872
+ for (offset = 0; /* null */; ++offset)
873
+#endif
874
+ {
875
+
876
+// Too low/high, keep going; or too high/low, meaning the loop passed a hole
877
+// and the initial Index is empty:
878
+
879
+#ifdef JUDYPREV
880
+ if ((Pjbl->jbl_Expanse[offset]) > digit) continue;
881
+ if ((Pjbl->jbl_Expanse[offset]) < digit) RET_SUCCESS;
882
+#else
883
+ if ((Pjbl->jbl_Expanse[offset]) < digit) continue;
884
+ if ((Pjbl->jbl_Expanse[offset]) > digit) RET_SUCCESS;
885
+#endif
886
+
887
+// Found expanse matching digit; if its not full, traverse through it:
888
+
889
+ if (! JPFULL((Pjbl->jbl_jp) + offset))
890
+ {
891
+ Pjp = (Pjbl->jbl_jp) + offset;
892
+ goto SMGetContinue;
893
+ }
894
+
895
+// Common code: While searching for a lower/higher hole or a non-full JP, upon
896
+// finding a lower/higher hole, adjust Index using the revised digit and
897
+// return; or upon finding a consecutive lower/higher expanse, if the expanses
898
+// JP is non-full, modify Index and traverse through the JP:
899
+
900
+#define BRANCHL_CHECK(OpIncDec,OpLeastDigits,Digit,Digits) \
901
+ { \
902
+ if ((Pjbl->jbl_Expanse[offset]) != OpIncDec digit) \
903
+ SET_AND_RETURN(OpLeastDigits, Digit, Digits); \
904
+ \
905
+ if (! JPFULL((Pjbl->jbl_jp) + offset)) \
906
+ { \
907
+ Pjp = (Pjbl->jbl_jp) + offset; \
908
+ SET_AND_CONTINUE(OpLeastDigits, Digit, Digits); \
909
+ } \
910
+ }
911
+
912
+// BranchL primary dead end: Expanse matching Index/digit is full (rare except
913
+// for dense/sequential indexes):
914
+//
915
+// Search for a lower/higher hole, a non-full JP, or the end of the expanse
916
+// list, while decrementing/incrementing digit.
917
+
918
+#ifdef JUDYPREV
919
+ while (--offset >= 0)
920
+ BRANCHL_CHECK(--, SETLEASTDIGITS_D, digit, digits)
921
+#else
922
+ while (++offset < Pjbl->jbl_NumJPs)
923
+ BRANCHL_CHECK(++, CLEARLEASTDIGITS_D, digit, digits)
924
+#endif
925
+
926
+// Passed end of BranchL expanse list after finding a matching but full
927
+// expanse:
928
+//
929
+// Digit now matches the lowest/highest expanse, which is a full expanse; if
930
+// digit is at the end of BranchLs expanse (no hole before/after), break out
931
+// of the loop; otherwise modify Index to the next lower/higher digit and
932
+// return success:
933
+
934
+#ifdef JUDYPREV
935
+ if (digit == 0) break;
936
+ --digit; SET_AND_RETURN(SETLEASTDIGITS_D, digit, digits);
937
+#else
938
+ if (digit == JU_LEASTBYTES(cJU_ALLONES, 1)) break;
939
+ ++digit; SET_AND_RETURN(CLEARLEASTDIGITS_D, digit, digits);
940
+#endif
941
+ } // for-loop
942
+
943
+// BranchL secondary dead end, no non-full previous/next JP:
944
+
945
+ SMRESTART(digits);
946
+
947
+
948
+// ----------------------------------------------------------------------------
949
+// BITMAP BRANCH:
950
+//
951
+// Check Decode bytes, if any, in the current JP, then search for a JP for the
952
+// next digit in Index.
953
+
954
+ case cJU_JPBRANCH_B2: CHECKDCD(2); SMPREPB2(SMBranchB);
955
+ case cJU_JPBRANCH_B3: CHECKDCD(3); SMPREPB3(SMBranchB);
956
+#ifdef JU_64BIT
957
+ case cJU_JPBRANCH_B4: CHECKDCD(4); SMPREPB4(SMBranchB);
958
+ case cJU_JPBRANCH_B5: CHECKDCD(5); SMPREPB5(SMBranchB);
959
+ case cJU_JPBRANCH_B6: CHECKDCD(6); SMPREPB6(SMBranchB);
960
+ case cJU_JPBRANCH_B7: CHECKDCD(7); SMPREPB7(SMBranchB);
961
+#endif
962
+ case cJU_JPBRANCH_B: SMPREPBL(SMBranchB);
963
+
964
+// Common code (state-independent) for all cases of bitmap branches:
965
+
966
+SMBranchB:
967
+ Pjbb = P_JBB(Pjp->jp_Addr);
968
+
969
+// Locate the digits JP in the subexpanse list, if present:
970
+
971
+ subexp = digit / cJU_BITSPERSUBEXPB;
972
+ assert(subexp < cJU_NUMSUBEXPB); // falls in expected range.
973
+ bitposmaskB = JU_BITPOSMASKB(digit);
974
+
975
+// Absent JP = no JP matches current digit in Index:
976
+
977
+// if (! JU_BITMAPTESTB(Pjbb, digit)) // slower.
978
+ if (! (JU_JBB_BITMAP(Pjbb, subexp) & bitposmaskB)) // faster.
979
+ RET_SUCCESS;
980
+
981
+// Non-full JP matches current digit in Index:
982
+//
983
+// Iterate to the subsidiary non-full JP.
984
+
985
+ offset = SEARCHBITMAPB(JU_JBB_BITMAP(Pjbb, subexp), digit,
986
+ bitposmaskB);
987
+ // not negative since at least one bit is set:
988
+ assert(offset >= 0);
989
+ assert(offset < (int) cJU_BITSPERSUBEXPB);
990
+
991
+// Watch for null JP subarray pointer with non-null bitmap (a corruption):
992
+
993
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp)))
994
+ == (Pjp_t) NULL) RET_CORRUPT;
995
+
996
+ Pjp += offset;
997
+ if (! JPFULL(Pjp)) goto SMGetContinue;
998
+
999
+// BranchB primary dead end:
1000
+//
1001
+// Upon hitting a full JP in a BranchB for the next digit in Index, search
1002
+// sideways for a previous/next absent JP (unset bit) or non-full JP (set bit
1003
+// with non-full JP); first in the current bitmap subexpanse, then in
1004
+// lower/higher subexpanses. Upon entry, Pjp points to a known-unusable JP,
1005
+// ready to decrement/increment.
1006
+//
1007
+// Note: The preceding code is separate from this loop because Index does not
1008
+// need revising (see SET_AND_*()) if the initial index is an empty index.
1009
+//
1010
+// TBD: For speed, shift bitposmaskB instead of using JU_BITMAPTESTB or
1011
+// JU_BITPOSMASKB, but this shift has knowledge of bit order that really should
1012
+// be encapsulated in a header file.
1013
+
1014
+#define BRANCHB_CHECKBIT(OpLeastDigits) \
1015
+ if (! (JU_JBB_BITMAP(Pjbb, subexp) & bitposmaskB)) /* absent JP */ \
1016
+ SET_AND_RETURN(OpLeastDigits, digit, digits)
1017
+
1018
+#define BRANCHB_CHECKJPFULL(OpLeastDigits) \
1019
+ if (! JPFULL(Pjp)) \
1020
+ SET_AND_CONTINUE(OpLeastDigits, digit, digits)
1021
+
1022
+#define BRANCHB_STARTSUBEXP(OpLeastDigits) \
1023
+ if (! JU_JBB_BITMAP(Pjbb, subexp)) /* empty subexpanse, shortcut */ \
1024
+ SET_AND_RETURN(OpLeastDigits, digit, digits) \
1025
+ if ((Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp))) == (Pjp_t) NULL) RET_CORRUPT
1026
+
1027
+#ifdef JUDYPREV
1028
+
1029
+ --digit; // skip initial digit.
1030
+ bitposmaskB >>= 1; // see TBD above.
1031
+
1032
+BranchBNextSubexp: // return here to check next bitmap subexpanse.
1033
+
1034
+ while (bitposmaskB) // more bits to check in subexp.
1035
+ {
1036
+ BRANCHB_CHECKBIT(SETLEASTDIGITS_D);
1037
+ --Pjp; // previous in subarray.
1038
+ BRANCHB_CHECKJPFULL(SETLEASTDIGITS_D);
1039
+ assert(digit >= 0);
1040
+ --digit;
1041
+ bitposmaskB >>= 1;
1042
+ }
1043
+
1044
+ if (subexp-- > 0) // more subexpanses.
1045
+ {
1046
+ BRANCHB_STARTSUBEXP(SETLEASTDIGITS_D);
1047
+ Pjp += SEARCHBITMAPMAXB(JU_JBB_BITMAP(Pjbb, subexp)) + 1;
1048
+ bitposmaskB = (1U << (cJU_BITSPERSUBEXPB - 1));
1049
+ goto BranchBNextSubexp;
1050
+ }
1051
+
1052
+#else // JUDYNEXT
1053
+
1054
+ ++digit; // skip initial digit.
1055
+ bitposmaskB <<= 1; // note: BITMAPB_t.
1056
+
1057
+BranchBNextSubexp: // return here to check next bitmap subexpanse.
1058
+
1059
+ while (bitposmaskB) // more bits to check in subexp.
1060
+ {
1061
+ BRANCHB_CHECKBIT(CLEARLEASTDIGITS_D);
1062
+ ++Pjp; // previous in subarray.
1063
+ BRANCHB_CHECKJPFULL(CLEARLEASTDIGITS_D);
1064
+ assert(digit < cJU_SUBEXPPERSTATE);
1065
+ ++digit;
1066
+ bitposmaskB <<= 1; // note: BITMAPB_t.
1067
+ }
1068
+
1069
+ if (++subexp < cJU_NUMSUBEXPB) // more subexpanses.
1070
+ {
1071
+ BRANCHB_STARTSUBEXP(CLEARLEASTDIGITS_D);
1072
+ --Pjp; // pre-decrement.
1073
+ bitposmaskB = 1;
1074
+ goto BranchBNextSubexp;
1075
+ }
1076
+
1077
+#endif // JUDYNEXT
1078
+
1079
+// BranchB secondary dead end, no non-full previous/next JP:
1080
+
1081
+ SMRESTART(digits);
1082
+
1083
+
1084
+// ----------------------------------------------------------------------------
1085
+// UNCOMPRESSED BRANCH:
1086
+//
1087
+// Check Decode bytes, if any, in the current JP, then search for a JP for the
1088
+// next digit in Index.
1089
+
1090
+ case cJU_JPBRANCH_U2: CHECKDCD(2); SMPREPB2(SMBranchU);
1091
+ case cJU_JPBRANCH_U3: CHECKDCD(3); SMPREPB3(SMBranchU);
1092
+#ifdef JU_64BIT
1093
+ case cJU_JPBRANCH_U4: CHECKDCD(4); SMPREPB4(SMBranchU);
1094
+ case cJU_JPBRANCH_U5: CHECKDCD(5); SMPREPB5(SMBranchU);
1095
+ case cJU_JPBRANCH_U6: CHECKDCD(6); SMPREPB6(SMBranchU);
1096
+ case cJU_JPBRANCH_U7: CHECKDCD(7); SMPREPB7(SMBranchU);
1097
+#endif
1098
+ case cJU_JPBRANCH_U: SMPREPBL(SMBranchU);
1099
+
1100
+// Common code (state-independent) for all cases of uncompressed branches:
1101
+
1102
+SMBranchU:
1103
+ Pjbu = P_JBU(Pjp->jp_Addr);
1104
+ Pjp = (Pjbu->jbu_jp) + digit;
1105
+
1106
+// Absent JP = null JP for current digit in Index:
1107
+
1108
+ if (JPNULL(JU_JPTYPE(Pjp))) RET_SUCCESS;
1109
+
1110
+// Non-full JP matches current digit in Index:
1111
+//
1112
+// Iterate to the subsidiary JP.
1113
+
1114
+ if (! JPFULL(Pjp)) goto SMGetContinue;
1115
+
1116
+// BranchU primary dead end:
1117
+//
1118
+// Upon hitting a full JP in a BranchU for the next digit in Index, search
1119
+// sideways for a previous/next null or non-full JP. BRANCHU_CHECKJP() is
1120
+// shorthand for common code.
1121
+//
1122
+// Note: The preceding code is separate from this loop because Index does not
1123
+// need revising (see SET_AND_*()) if the initial index is an empty index.
1124
+
1125
+#define BRANCHU_CHECKJP(OpIncDec,OpLeastDigits) \
1126
+ { \
1127
+ OpIncDec Pjp; \
1128
+ \
1129
+ if (JPNULL(JU_JPTYPE(Pjp))) \
1130
+ SET_AND_RETURN(OpLeastDigits, digit, digits) \
1131
+ \
1132
+ if (! JPFULL(Pjp)) \
1133
+ SET_AND_CONTINUE(OpLeastDigits, digit, digits) \
1134
+ }
1135
+
1136
+#ifdef JUDYPREV
1137
+ while (digit-- > 0)
1138
+ BRANCHU_CHECKJP(--, SETLEASTDIGITS_D);
1139
+#else
1140
+ while (++digit < cJU_BRANCHUNUMJPS)
1141
+ BRANCHU_CHECKJP(++, CLEARLEASTDIGITS_D);
1142
+#endif
1143
+
1144
+// BranchU secondary dead end, no non-full previous/next JP:
1145
+
1146
+ SMRESTART(digits);
1147
+
1148
+
1149
+// ----------------------------------------------------------------------------
1150
+// LINEAR LEAF:
1151
+//
1152
+// Check Decode bytes, if any, in the current JP, then search the leaf for the
1153
+// previous/next empty index starting at Index. Primary leaf dead end is
1154
+// hidden within j__udySearchLeaf*Empty*(). In case of secondary leaf dead
1155
+// end, restart at the top of the tree.
1156
+//
1157
+// Note: Pword is the name known to GET*; think of it as Pjlw.
1158
+
1159
+#define SMLEAFL(cDigits,Func) \
1160
+ Pword = (PWord_t) P_JLW(Pjp->jp_Addr); \
1161
+ pop0 = JU_JPLEAF_POP0(Pjp); \
1162
+ Func(Pword, pop0)
1163
+
1164
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
1165
+ case cJU_JPLEAF1: CHECKDCD(1); SMLEAFL(1, j__udySearchLeafEmpty1);
1166
+#endif
1167
+ case cJU_JPLEAF2: CHECKDCD(2); SMLEAFL(2, j__udySearchLeafEmpty2);
1168
+ case cJU_JPLEAF3: CHECKDCD(3); SMLEAFL(3, j__udySearchLeafEmpty3);
1169
+
1170
+#ifdef JU_64BIT
1171
+ case cJU_JPLEAF4: CHECKDCD(4); SMLEAFL(4, j__udySearchLeafEmpty4);
1172
+ case cJU_JPLEAF5: CHECKDCD(5); SMLEAFL(5, j__udySearchLeafEmpty5);
1173
+ case cJU_JPLEAF6: CHECKDCD(6); SMLEAFL(6, j__udySearchLeafEmpty6);
1174
+ case cJU_JPLEAF7: CHECKDCD(7); SMLEAFL(7, j__udySearchLeafEmpty7);
1175
+#endif
1176
+
1177
+
1178
+// ----------------------------------------------------------------------------
1179
+// BITMAP LEAF:
1180
+//
1181
+// Check Decode bytes, if any, in the current JP, then search the leaf for the
1182
+// previous/next empty index starting at Index.
1183
+
1184
+ case cJU_JPLEAF_B1:
1185
+
1186
+ CHECKDCD(1);
1187
+
1188
+ Pjlb = P_JLB(Pjp->jp_Addr);
1189
+ digit = JU_DIGITATSTATE(Index, 1);
1190
+ subexp = digit / cJU_BITSPERSUBEXPL;
1191
+ bitposmaskL = JU_BITPOSMASKL(digit);
1192
+ assert(subexp < cJU_NUMSUBEXPL); // falls in expected range.
1193
+
1194
+// Absent index = no index matches current digit in Index:
1195
+
1196
+// if (! JU_BITMAPTESTL(Pjlb, digit)) // slower.
1197
+ if (! (JU_JLB_BITMAP(Pjlb, subexp) & bitposmaskL)) // faster.
1198
+ RET_SUCCESS;
1199
+
1200
+// LeafB1 primary dead end:
1201
+//
1202
+// Upon hitting a valid (non-empty) index in a LeafB1 for the last digit in
1203
+// Index, search sideways for a previous/next absent index, first in the
1204
+// current bitmap subexpanse, then in lower/higher subexpanses.
1205
+// LEAFB1_CHECKBIT() is shorthand for common code to handle one bit in one
1206
+// bitmap subexpanse.
1207
+//
1208
+// Note: The preceding code is separate from this loop because Index does not
1209
+// need revising (see SET_AND_*()) if the initial index is an empty index.
1210
+//
1211
+// TBD: For speed, shift bitposmaskL instead of using JU_BITMAPTESTL or
1212
+// JU_BITPOSMASKL, but this shift has knowledge of bit order that really should
1213
+// be encapsulated in a header file.
1214
+
1215
+#define LEAFB1_CHECKBIT(OpLeastDigits) \
1216
+ if (! (JU_JLB_BITMAP(Pjlb, subexp) & bitposmaskL)) \
1217
+ SET_AND_RETURN(OpLeastDigits, digit, 1)
1218
+
1219
+#define LEAFB1_STARTSUBEXP(OpLeastDigits) \
1220
+ if (! JU_JLB_BITMAP(Pjlb, subexp)) /* empty subexp */ \
1221
+ SET_AND_RETURN(OpLeastDigits, digit, 1)
1222
+
1223
+#ifdef JUDYPREV
1224
+
1225
+ --digit; // skip initial digit.
1226
+ bitposmaskL >>= 1; // see TBD above.
1227
+
1228
+LeafB1NextSubexp: // return here to check next bitmap subexpanse.
1229
+
1230
+ while (bitposmaskL) // more bits to check in subexp.
1231
+ {
1232
+ LEAFB1_CHECKBIT(SETLEASTDIGITS_D);
1233
+ assert(digit >= 0);
1234
+ --digit;
1235
+ bitposmaskL >>= 1;
1236
+ }
1237
+
1238
+ if (subexp-- > 0) // more subexpanses.
1239
+ {
1240
+ LEAFB1_STARTSUBEXP(SETLEASTDIGITS_D);
1241
+ bitposmaskL = (1UL << (cJU_BITSPERSUBEXPL - 1));
1242
+ goto LeafB1NextSubexp;
1243
+ }
1244
+
1245
+#else // JUDYNEXT
1246
+
1247
+ ++digit; // skip initial digit.
1248
+ bitposmaskL <<= 1; // note: BITMAPL_t.
1249
+
1250
+LeafB1NextSubexp: // return here to check next bitmap subexpanse.
1251
+
1252
+ while (bitposmaskL) // more bits to check in subexp.
1253
+ {
1254
+ LEAFB1_CHECKBIT(CLEARLEASTDIGITS_D);
1255
+ assert(digit < cJU_SUBEXPPERSTATE);
1256
+ ++digit;
1257
+ bitposmaskL <<= 1; // note: BITMAPL_t.
1258
+ }
1259
+
1260
+ if (++subexp < cJU_NUMSUBEXPL) // more subexpanses.
1261
+ {
1262
+ LEAFB1_STARTSUBEXP(CLEARLEASTDIGITS_D);
1263
+ bitposmaskL = 1;
1264
+ goto LeafB1NextSubexp;
1265
+ }
1266
+
1267
+#endif // JUDYNEXT
1268
+
1269
+// LeafB1 secondary dead end, no empty index:
1270
+
1271
+ SMRESTART(1);
1272
+
1273
+
1274
+#ifdef JUDY1
1275
+// ----------------------------------------------------------------------------
1276
+// FULL POPULATION:
1277
+//
1278
+// If the Decode bytes do not match, Index is empty (without modification);
1279
+// otherwise restart.
1280
+
1281
+ case cJ1_JPFULLPOPU1:
1282
+
1283
+ CHECKDCD(1);
1284
+ SMRESTART(1);
1285
+#endif
1286
+
1287
+
1288
+// ----------------------------------------------------------------------------
1289
+// IMMEDIATE:
1290
+//
1291
+// Pop1 = 1 Immediate JPs:
1292
+//
1293
+// If Index is not in the immediate JP, return success; otherwise check if
1294
+// there is an empty index below/above the immediate JPs index, and if so,
1295
+// return success with modified Index, else restart.
1296
+//
1297
+// Note: Doug says its fast enough to calculate the index size (digits) in
1298
+// the following; no need to set it separately for each case.
1299
+
1300
+ case cJU_JPIMMED_1_01:
1301
+ case cJU_JPIMMED_2_01:
1302
+ case cJU_JPIMMED_3_01:
1303
+#ifdef JU_64BIT
1304
+ case cJU_JPIMMED_4_01:
1305
+ case cJU_JPIMMED_5_01:
1306
+ case cJU_JPIMMED_6_01:
1307
+ case cJU_JPIMMED_7_01:
1308
+#endif
1309
+ if (JU_JPDCDPOP0(Pjp) != JU_TRIMTODCDSIZE(Index)) RET_SUCCESS;
1310
+ digits = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_01 + 1;
1311
+ LEAF_EDGE(JU_LEASTBYTES(JU_JPDCDPOP0(Pjp), digits), digits);
1312
+
1313
+// Immediate JPs with Pop1 > 1:
1314
+
1315
+#define IMM_MULTI(Func,BaseJPType) \
1316
+ JUDY1CODE(Pword = (PWord_t) (Pjp->jp_1Index);) \
1317
+ JUDYLCODE(Pword = (PWord_t) (Pjp->jp_LIndex);) \
1318
+ Func(Pword, JU_JPTYPE(Pjp) - (BaseJPType) + 1)
1319
+
1320
+ case cJU_JPIMMED_1_02:
1321
+ case cJU_JPIMMED_1_03:
1322
+#if (defined(JUDY1) || defined(JU_64BIT))
1323
+ case cJU_JPIMMED_1_04:
1324
+ case cJU_JPIMMED_1_05:
1325
+ case cJU_JPIMMED_1_06:
1326
+ case cJU_JPIMMED_1_07:
1327
+#endif
1328
+#if (defined(JUDY1) && defined(JU_64BIT))
1329
+ case cJ1_JPIMMED_1_08:
1330
+ case cJ1_JPIMMED_1_09:
1331
+ case cJ1_JPIMMED_1_10:
1332
+ case cJ1_JPIMMED_1_11:
1333
+ case cJ1_JPIMMED_1_12:
1334
+ case cJ1_JPIMMED_1_13:
1335
+ case cJ1_JPIMMED_1_14:
1336
+ case cJ1_JPIMMED_1_15:
1337
+#endif
1338
+ IMM_MULTI(j__udySearchLeafEmpty1, cJU_JPIMMED_1_02);
1339
+
1340
+#if (defined(JUDY1) || defined(JU_64BIT))
1341
+ case cJU_JPIMMED_2_02:
1342
+ case cJU_JPIMMED_2_03:
1343
+#endif
1344
+#if (defined(JUDY1) && defined(JU_64BIT))
1345
+ case cJ1_JPIMMED_2_04:
1346
+ case cJ1_JPIMMED_2_05:
1347
+ case cJ1_JPIMMED_2_06:
1348
+ case cJ1_JPIMMED_2_07:
1349
+#endif
1350
+#if (defined(JUDY1) || defined(JU_64BIT))
1351
+ IMM_MULTI(j__udySearchLeafEmpty2, cJU_JPIMMED_2_02);
1352
+#endif
1353
+
1354
+#if (defined(JUDY1) || defined(JU_64BIT))
1355
+ case cJU_JPIMMED_3_02:
1356
+#endif
1357
+#if (defined(JUDY1) && defined(JU_64BIT))
1358
+ case cJ1_JPIMMED_3_03:
1359
+ case cJ1_JPIMMED_3_04:
1360
+ case cJ1_JPIMMED_3_05:
1361
+#endif
1362
+#if (defined(JUDY1) || defined(JU_64BIT))
1363
+ IMM_MULTI(j__udySearchLeafEmpty3, cJU_JPIMMED_3_02);
1364
+#endif
1365
+
1366
+#if (defined(JUDY1) && defined(JU_64BIT))
1367
+ case cJ1_JPIMMED_4_02:
1368
+ case cJ1_JPIMMED_4_03:
1369
+ IMM_MULTI(j__udySearchLeafEmpty4, cJ1_JPIMMED_4_02);
1370
+
1371
+ case cJ1_JPIMMED_5_02:
1372
+ case cJ1_JPIMMED_5_03:
1373
+ IMM_MULTI(j__udySearchLeafEmpty5, cJ1_JPIMMED_5_02);
1374
+
1375
+ case cJ1_JPIMMED_6_02:
1376
+ IMM_MULTI(j__udySearchLeafEmpty6, cJ1_JPIMMED_6_02);
1377
+
1378
+ case cJ1_JPIMMED_7_02:
1379
+ IMM_MULTI(j__udySearchLeafEmpty7, cJ1_JPIMMED_7_02);
1380
+#endif
1381
+
1382
+
1383
+// ----------------------------------------------------------------------------
1384
+// INVALID JP TYPE:
1385
+
1386
+ default: RET_CORRUPT;
1387
+
1388
+ } // SMGet switch.
1389
+
1390
+} // Judy1PrevEmpty() / Judy1NextEmpty() / JudyLPrevEmpty() / JudyLNextEmpty()
libnetdata/libjudy/src/JudyL/JudyLTablesGen.c
new
+296
@@ -0,0 +1,296 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.37 $ $Source: /judy/src/JudyCommon/JudyTables.c $
19
+
20
+#ifndef JU_WIN
21
+#include <unistd.h> // unavailable on win_*.
22
+#endif
23
+
24
+#include <stdlib.h>
25
+#include <stdio.h>
26
+
27
+#if (! (defined(JUDY1) || defined(JUDYL)))
28
+#error: One of -DJUDY1 or -DJUDYL must be specified.
29
+#endif
30
+
31
+#define TERMINATOR 999 // terminator for Alloc tables
32
+
33
+#define BPW sizeof(Word_t) // define bytes per word
34
+
35
+#ifdef JUDY1
36
+#include "Judy1.h"
37
+#else
38
+#include "JudyL.h"
39
+#endif
40
+
41
+FILE *fd;
42
+
43
+// Definitions come from header files Judy1.h and JudyL.h:
44
+
45
+int AllocSizes[] = ALLOCSIZES;
46
+
47
+#define ROUNDUP(BYTES,BPW,OFFSETW) \
48
+ ((((BYTES) + (BPW) - 1) / (BPW)) + (OFFSETW))
49
+
50
+
51
+// ****************************************************************************
52
+// G E N T A B L E
53
+//
54
+// Note: "const" is required for newer compilers.
55
+
56
+FUNCTION void GenTable(
57
+ const char * TableName, // name of table string
58
+ const char * TableSize, // dimentioned size string
59
+ int IndexBytes, // bytes per Index
60
+ int LeafSize, // number elements in object
61
+ int ValueBytes, // bytes per Value
62
+ int OffsetWords) // 1 for LEAFW
63
+{
64
+ int * PAllocSizes = AllocSizes;
65
+ int OWord;
66
+ int CurWord;
67
+ int IWord;
68
+ int ii;
69
+ int BytesOfIndex;
70
+ int BytesOfObject;
71
+ int Index;
72
+ int LastWords;
73
+ int Words [1000] = { 0 };
74
+ int Offset[1000] = { 0 };
75
+ int MaxWords;
76
+
77
+ MaxWords = ROUNDUP((IndexBytes + ValueBytes) * LeafSize, BPW, OffsetWords);
78
+ Words[0] = 0;
79
+ Offset[0] = 0;
80
+ CurWord = TERMINATOR;
81
+
82
+// Walk through all number of Indexes in table:
83
+
84
+ for (Index = 1; /* null */; ++Index)
85
+ {
86
+
87
+// Calculate byte required for next size:
88
+
89
+ BytesOfIndex = IndexBytes * Index;
90
+ BytesOfObject = (IndexBytes + ValueBytes) * Index;
91
+
92
+// Round up and calculate words required for next size:
93
+
94
+ OWord = ROUNDUP(BytesOfObject, BPW, OffsetWords);
95
+ IWord = ROUNDUP(BytesOfIndex, BPW, OffsetWords);
96
+
97
+// Root-level leaves of population of 1 and 2 do not have the 1 word offset:
98
+
99
+// Save minimum value of offset:
100
+
101
+ Offset[Index] = IWord;
102
+
103
+// Round up to next available size of words:
104
+
105
+ while (OWord > *PAllocSizes) PAllocSizes++;
106
+
107
+ if (Index == LeafSize)
108
+ {
109
+ CurWord = Words[Index] = OWord;
110
+ break;
111
+ }
112
+// end of available sizes ?
113
+
114
+ if (*PAllocSizes == TERMINATOR)
115
+ {
116
+ fprintf(stderr, "BUG, in %sPopToWords, sizes not big enough for object\n", TableName);
117
+ exit(1);
118
+ }
119
+
120
+// Save words required and last word:
121
+
122
+ if (*PAllocSizes < MaxWords) { CurWord = Words[Index] = *PAllocSizes; }
123
+ else { CurWord = Words[Index] = MaxWords; }
124
+
125
+ } // for each index
126
+
127
+ LastWords = TERMINATOR;
128
+
129
+// Round up to largest size in each group of malloc sizes:
130
+
131
+ for (ii = LeafSize; ii > 0; ii--)
132
+ {
133
+ if (LastWords > (Words[ii] - ii)) LastWords = Offset[ii];
134
+ else Offset[ii] = LastWords;
135
+ }
136
+
137
+// Print the PopToWords[] table:
138
+
139
+ fprintf(fd,"\n//\tobject uses %d words\n", CurWord);
140
+ fprintf(fd,"//\t%s = %d\n", TableSize, LeafSize);
141
+
142
+ fprintf(fd,"const uint8_t\n");
143
+ fprintf(fd,"%sPopToWords[%s + 1] =\n", TableName, TableSize);
144
+ fprintf(fd,"{\n\t 0,");
145
+
146
+ for (ii = 1; ii <= LeafSize; ii++)
147
+ {
148
+
149
+// 8 columns per line, starting with 1:
150
+
151
+ if ((ii % 8) == 1) fprintf(fd,"\n\t");
152
+
153
+ fprintf(fd,"%2d", Words[ii]);
154
+
155
+// If not last number place comma:
156
+
157
+ if (ii != LeafSize) fprintf(fd,", ");
158
+ }
159
+ fprintf(fd,"\n};\n");
160
+
161
+// Print the Offset table if needed:
162
+
163
+ if (! ValueBytes) return;
164
+
165
+ fprintf(fd,"const uint8_t\n");
166
+ fprintf(fd,"%sOffset[%s + 1] =\n", TableName, TableSize);
167
+ fprintf(fd,"{\n");
168
+ fprintf(fd,"\t 0,");
169
+
170
+ for (ii = 1; ii <= LeafSize; ii++)
171
+ {
172
+ if ((ii % 8) == 1) fprintf(fd,"\n\t");
173
+
174
+ fprintf(fd,"%2d", Offset[ii]);
175
+
176
+ if (ii != LeafSize) fprintf(fd,", ");
177
+ }
178
+ fprintf(fd,"\n};\n");
179
+
180
+} // GenTable()
181
+
182
+
183
+// ****************************************************************************
184
+// M A I N
185
+
186
+FUNCTION int main()
187
+{
188
+ int ii;
189
+
190
+#ifdef JUDY1
191
+ char *fname = "Judy1Tables.c";
192
+#else
193
+ char *fname = "JudyLTables.c";
194
+#endif
195
+
196
+ if ((fd = fopen(fname, "w")) == NULL){
197
+ perror("FATAL ERROR: could not write to Judy[1L]Tables.c file\n");
198
+ return (-1);
199
+ }
200
+
201
+
202
+ fprintf(fd,"// @(#) From generation tool: $Revision: 4.37 $ $Source: /judy/src/JudyCommon/JudyTables.c $\n");
203
+ fprintf(fd,"//\n\n");
204
+
205
+
206
+// ================================ Judy1 =================================
207
+#ifdef JUDY1
208
+
209
+ fprintf(fd,"#include \"Judy1.h\"\n");
210
+
211
+ fprintf(fd,"// Leave the malloc() sizes readable in the binary (via "
212
+ "strings(1)):\n");
213
+ fprintf(fd,"const char * Judy1MallocSizes = \"Judy1MallocSizes =");
214
+
215
+ for (ii = 0; AllocSizes[ii] != TERMINATOR; ii++)
216
+ fprintf(fd," %d,", AllocSizes[ii]);
217
+
218
+#ifndef JU_64BIT
219
+ fprintf(fd," Leaf1 = %d\";\n\n", cJ1_LEAF1_MAXPOP1);
220
+#else
221
+ fprintf(fd,"\";\n\n"); // no Leaf1 in this case.
222
+#endif
223
+
224
+// ================================ 32 bit ================================
225
+#ifndef JU_64BIT
226
+
227
+ GenTable("j__1_BranchBJP","cJU_BITSPERSUBEXPB", 8, cJU_BITSPERSUBEXPB,0,0);
228
+
229
+ GenTable("j__1_Leaf1", "cJ1_LEAF1_MAXPOP1", 1, cJ1_LEAF1_MAXPOP1, 0, 0);
230
+ GenTable("j__1_Leaf2", "cJ1_LEAF2_MAXPOP1", 2, cJ1_LEAF2_MAXPOP1, 0, 0);
231
+ GenTable("j__1_Leaf3", "cJ1_LEAF3_MAXPOP1", 3, cJ1_LEAF3_MAXPOP1, 0, 0);
232
+ GenTable("j__1_LeafW", "cJ1_LEAFW_MAXPOP1", 4, cJ1_LEAFW_MAXPOP1, 0, 1);
233
+
234
+#endif
235
+
236
+// ================================ 64 bit ================================
237
+#ifdef JU_64BIT
238
+ GenTable("j__1_BranchBJP","cJU_BITSPERSUBEXPB",16, cJU_BITSPERSUBEXPB,0,0);
239
+
240
+ GenTable("j__1_Leaf2", "cJ1_LEAF2_MAXPOP1", 2, cJ1_LEAF2_MAXPOP1, 0, 0);
241
+ GenTable("j__1_Leaf3", "cJ1_LEAF3_MAXPOP1", 3, cJ1_LEAF3_MAXPOP1, 0, 0);
242
+ GenTable("j__1_Leaf4", "cJ1_LEAF4_MAXPOP1", 4, cJ1_LEAF4_MAXPOP1, 0, 0);
243
+ GenTable("j__1_Leaf5", "cJ1_LEAF5_MAXPOP1", 5, cJ1_LEAF5_MAXPOP1, 0, 0);
244
+ GenTable("j__1_Leaf6", "cJ1_LEAF6_MAXPOP1", 6, cJ1_LEAF6_MAXPOP1, 0, 0);
245
+ GenTable("j__1_Leaf7", "cJ1_LEAF7_MAXPOP1", 7, cJ1_LEAF7_MAXPOP1, 0, 0);
246
+ GenTable("j__1_LeafW", "cJ1_LEAFW_MAXPOP1", 8, cJ1_LEAFW_MAXPOP1, 0, 1);
247
+#endif
248
+#endif // JUDY1
249
+
250
+
251
+// ================================ JudyL =================================
252
+#ifdef JUDYL
253
+
254
+ fprintf(fd,"#include \"JudyL.h\"\n");
255
+
256
+ fprintf(fd,"// Leave the malloc() sizes readable in the binary (via "
257
+ "strings(1)):\n");
258
+ fprintf(fd,"const char * JudyLMallocSizes = \"JudyLMallocSizes =");
259
+
260
+ for (ii = 0; AllocSizes[ii] != TERMINATOR; ii++)
261
+ fprintf(fd," %d,", AllocSizes[ii]);
262
+
263
+ fprintf(fd," Leaf1 = %ld\";\n\n", (Word_t)cJL_LEAF1_MAXPOP1);
264
+
265
+#ifndef JU_64BIT
266
+// ================================ 32 bit ================================
267
+ GenTable("j__L_BranchBJP","cJU_BITSPERSUBEXPB", 8, cJU_BITSPERSUBEXPB, 0,0);
268
+
269
+ GenTable("j__L_Leaf1", "cJL_LEAF1_MAXPOP1", 1, cJL_LEAF1_MAXPOP1, BPW,0);
270
+ GenTable("j__L_Leaf2", "cJL_LEAF2_MAXPOP1", 2, cJL_LEAF2_MAXPOP1, BPW,0);
271
+ GenTable("j__L_Leaf3", "cJL_LEAF3_MAXPOP1", 3, cJL_LEAF3_MAXPOP1, BPW,0);
272
+ GenTable("j__L_LeafW", "cJL_LEAFW_MAXPOP1", 4, cJL_LEAFW_MAXPOP1, BPW,1);
273
+ GenTable("j__L_LeafV", "cJU_BITSPERSUBEXPL", 4, cJU_BITSPERSUBEXPL, 0,0);
274
+#endif // 32 BIT
275
+
276
+#ifdef JU_64BIT
277
+// ================================ 64 bit ================================
278
+ GenTable("j__L_BranchBJP","cJU_BITSPERSUBEXPB",16, cJU_BITSPERSUBEXPB, 0,0);
279
+
280
+ GenTable("j__L_Leaf1", "cJL_LEAF1_MAXPOP1", 1, cJL_LEAF1_MAXPOP1, BPW,0);
281
+ GenTable("j__L_Leaf2", "cJL_LEAF2_MAXPOP1", 2, cJL_LEAF2_MAXPOP1, BPW,0);
282
+ GenTable("j__L_Leaf3", "cJL_LEAF3_MAXPOP1", 3, cJL_LEAF3_MAXPOP1, BPW,0);
283
+ GenTable("j__L_Leaf4", "cJL_LEAF4_MAXPOP1", 4, cJL_LEAF4_MAXPOP1, BPW,0);
284
+ GenTable("j__L_Leaf5", "cJL_LEAF5_MAXPOP1", 5, cJL_LEAF5_MAXPOP1, BPW,0);
285
+ GenTable("j__L_Leaf6", "cJL_LEAF6_MAXPOP1", 6, cJL_LEAF6_MAXPOP1, BPW,0);
286
+ GenTable("j__L_Leaf7", "cJL_LEAF7_MAXPOP1", 7, cJL_LEAF7_MAXPOP1, BPW,0);
287
+ GenTable("j__L_LeafW", "cJL_LEAFW_MAXPOP1", 8, cJL_LEAFW_MAXPOP1, BPW,1);
288
+ GenTable("j__L_LeafV", "cJU_BITSPERSUBEXPL", 8, cJU_BITSPERSUBEXPL, 0,0);
289
+#endif // 64 BIT
290
+
291
+#endif // JUDYL
292
+ fclose(fd);
293
+
294
+ return(0);
295
+
296
+} // main()
libnetdata/libjudy/src/JudyL/j__udyLGet.c
new
+1094
@@ -0,0 +1,1094 @@
1
+// Copyright (C) 2000 - 2002 Hewlett-Packard Company
2
+//
3
+// This program is free software; you can redistribute it and/or modify it
4
+// under the term of the GNU Lesser General Public License as published by the
5
+// Free Software Foundation; either version 2 of the License, or (at your
6
+// option) any later version.
7
+//
8
+// This program is distributed in the hope that it will be useful, but WITHOUT
9
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11
+// for more details.
12
+//
13
+// You should have received a copy of the GNU Lesser General Public License
14
+// along with this program; if not, write to the Free Software Foundation,
15
+// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+// _________________
17
+
18
+// @(#) $Revision: 4.43 $ $Source: /judy/src/JudyCommon/JudyGet.c $
19
+//
20
+// Judy1Test() and JudyLGet() functions for Judy1 and JudyL.
21
+// Compile with one of -DJUDY1 or -DJUDYL.
22
+
23
+#if (! (defined(JUDY1) || defined(JUDYL)))
24
+#error: One of -DJUDY1 or -DJUDYL must be specified.
25
+#endif
26
+
27
+#ifdef JUDY1
28
+#include "Judy1.h"
29
+#else
30
+#include "JudyL.h"
31
+#endif
32
+
33
+#include "JudyPrivate1L.h"
34
+
35
+#ifdef TRACEJPR // different macro name, for "retrieval" only.
36
+#include "JudyPrintJP.c"
37
+#endif
38
+
39
+
40
+// ****************************************************************************
41
+// J U D Y 1 T E S T
42
+// J U D Y L G E T
43
+//
44
+// See the manual entry for details. Note support for "shortcut" entries to
45
+// trees known to start with a JPM.
46
+
47
+#ifdef JUDY1
48
+
49
+#ifdef JUDYGETINLINE
50
+FUNCTION int j__udy1Test
51
+#else
52
+FUNCTION int Judy1Test
53
+#endif
54
+
55
+#else // JUDYL
56
+
57
+#ifdef JUDYGETINLINE
58
+FUNCTION PPvoid_t j__udyLGet
59
+#else
60
+FUNCTION PPvoid_t JudyLGet
61
+#endif
62
+
63
+#endif // JUDYL
64
+ (
65
+#ifdef JUDYGETINLINE
66
+ Pvoid_t PArray, // from which to retrieve.
67
+ Word_t Index // to retrieve.
68
+#else
69
+ Pcvoid_t PArray, // from which to retrieve.
70
+ Word_t Index, // to retrieve.
71
+ PJError_t PJError // optional, for returning error info.
72
+#endif
73
+ )
74
+{
75
+ Pjp_t Pjp; // current JP while walking the tree.
76
+ Pjpm_t Pjpm; // for global accounting.
77
+ uint8_t Digit; // byte just decoded from Index.
78
+ Word_t Pop1; // leaf population (number of indexes).
79
+ Pjll_t Pjll; // pointer to LeafL.
80
+ DBGCODE(uint8_t ParentJPType;)
81
+
82
+#ifndef JUDYGETINLINE
83
+
84
+ if (PArray == (Pcvoid_t) NULL) // empty array.
85
+ {
86
+ JUDY1CODE(return(0);)
87
+ JUDYLCODE(return((PPvoid_t) NULL);)
88
+ }
89
+
90
+// ****************************************************************************
91
+// PROCESS TOP LEVEL BRANCHES AND LEAF:
92
+
93
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
94
+ {
95
+ Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
96
+ int posidx; // signed offset in leaf.
97
+
98
+ Pop1 = Pjlw[0] + 1;
99
+ posidx = j__udySearchLeafW(Pjlw + 1, Pop1, Index);
100
+
101
+ if (posidx >= 0)
102
+ {
103
+ JUDY1CODE(return(1);)
104
+ JUDYLCODE(return((PPvoid_t) (JL_LEAFWVALUEAREA(Pjlw, Pop1) + posidx));)
105
+ }
106
+ JUDY1CODE(return(0);)
107
+ JUDYLCODE(return((PPvoid_t) NULL);)
108
+ }
109
+
110
+#endif // ! JUDYGETINLINE
111
+
112
+ Pjpm = P_JPM(PArray);
113
+ Pjp = &(Pjpm->jpm_JP); // top branch is below JPM.
114
+
115
+// ****************************************************************************
116
+// WALK THE JUDY TREE USING A STATE MACHINE:
117
+
118
+ContinueWalk: // for going down one level; come here with Pjp set.
119
+
120
+#ifdef TRACEJPR
121
+ JudyPrintJP(Pjp, "g", __LINE__);
122
+#endif
123
+ switch (JU_JPTYPE(Pjp))
124
+ {
125
+
126
+// Ensure the switch table starts at 0 for speed; otherwise more code is
127
+// executed:
128
+
129
+ case 0: goto ReturnCorrupt; // save a little code.
130
+
131
+
132
+// ****************************************************************************
133
+// JPNULL*:
134
+//
135
+// Note: These are legitimate in a BranchU (only) and do not constitute a
136
+// fault.
137
+
138
+ case cJU_JPNULL1:
139
+ case cJU_JPNULL2:
140
+ case cJU_JPNULL3:
141
+#ifdef JU_64BIT
142
+ case cJU_JPNULL4:
143
+ case cJU_JPNULL5:
144
+ case cJU_JPNULL6:
145
+ case cJU_JPNULL7:
146
+#endif
147
+ assert(ParentJPType >= cJU_JPBRANCH_U2);
148
+ assert(ParentJPType <= cJU_JPBRANCH_U);
149
+ JUDY1CODE(return(0);)
150
+ JUDYLCODE(return((PPvoid_t) NULL);)
151
+
152
+
153
+// ****************************************************************************
154
+// JPBRANCH_L*:
155
+//
156
+// Note: The use of JU_DCDNOTMATCHINDEX() in branches is not strictly
157
+// required,since this can be done at leaf level, but it costs nothing to do it
158
+// sooner, and it aborts an unnecessary traversal sooner.
159
+
160
+ case cJU_JPBRANCH_L2:
161
+
162
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
163
+ Digit = JU_DIGITATSTATE(Index, 2);
164
+ goto JudyBranchL;
165
+
166
+ case cJU_JPBRANCH_L3:
167
+
168
+#ifdef JU_64BIT // otherwise its a no-op:
169
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
170
+#endif
171
+ Digit = JU_DIGITATSTATE(Index, 3);
172
+ goto JudyBranchL;
173
+
174
+#ifdef JU_64BIT
175
+ case cJU_JPBRANCH_L4:
176
+
177
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
178
+ Digit = JU_DIGITATSTATE(Index, 4);
179
+ goto JudyBranchL;
180
+
181
+ case cJU_JPBRANCH_L5:
182
+
183
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
184
+ Digit = JU_DIGITATSTATE(Index, 5);
185
+ goto JudyBranchL;
186
+
187
+ case cJU_JPBRANCH_L6:
188
+
189
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
190
+ Digit = JU_DIGITATSTATE(Index, 6);
191
+ goto JudyBranchL;
192
+
193
+ case cJU_JPBRANCH_L7:
194
+
195
+ // JU_DCDNOTMATCHINDEX() would be a no-op.
196
+ Digit = JU_DIGITATSTATE(Index, 7);
197
+ goto JudyBranchL;
198
+
199
+#endif // JU_64BIT
200
+
201
+ case cJU_JPBRANCH_L:
202
+ {
203
+ Pjbl_t Pjbl;
204
+ int posidx;
205
+
206
+ Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
207
+
208
+// Common code for all BranchLs; come here with Digit set:
209
+
210
+JudyBranchL:
211
+ Pjbl = P_JBL(Pjp->jp_Addr);
212
+
213
+ posidx = 0;
214
+
215
+ do {
216
+ if (Pjbl->jbl_Expanse[posidx] == Digit)
217
+ { // found Digit; continue traversal:
218
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
219
+ Pjp = Pjbl->jbl_jp + posidx;
220
+ goto ContinueWalk;
221
+ }
222
+ } while (++posidx != Pjbl->jbl_NumJPs);
223
+
224
+ break;
225
+ }
226
+
227
+
228
+// ****************************************************************************
229
+// JPBRANCH_B*:
230
+
231
+ case cJU_JPBRANCH_B2:
232
+
233
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
234
+ Digit = JU_DIGITATSTATE(Index, 2);
235
+ goto JudyBranchB;
236
+
237
+ case cJU_JPBRANCH_B3:
238
+
239
+#ifdef JU_64BIT // otherwise its a no-op:
240
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
241
+#endif
242
+ Digit = JU_DIGITATSTATE(Index, 3);
243
+ goto JudyBranchB;
244
+
245
+
246
+#ifdef JU_64BIT
247
+ case cJU_JPBRANCH_B4:
248
+
249
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
250
+ Digit = JU_DIGITATSTATE(Index, 4);
251
+ goto JudyBranchB;
252
+
253
+ case cJU_JPBRANCH_B5:
254
+
255
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
256
+ Digit = JU_DIGITATSTATE(Index, 5);
257
+ goto JudyBranchB;
258
+
259
+ case cJU_JPBRANCH_B6:
260
+
261
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
262
+ Digit = JU_DIGITATSTATE(Index, 6);
263
+ goto JudyBranchB;
264
+
265
+ case cJU_JPBRANCH_B7:
266
+
267
+ // JU_DCDNOTMATCHINDEX() would be a no-op.
268
+ Digit = JU_DIGITATSTATE(Index, 7);
269
+ goto JudyBranchB;
270
+
271
+#endif // JU_64BIT
272
+
273
+ case cJU_JPBRANCH_B:
274
+ {
275
+ Pjbb_t Pjbb;
276
+ Word_t subexp; // in bitmap, 0..7.
277
+ BITMAPB_t BitMap; // for one subexpanse.
278
+ BITMAPB_t BitMask; // bit in BitMap for Indexs Digit.
279
+
280
+ Digit = JU_DIGITATSTATE(Index, cJU_ROOTSTATE);
281
+
282
+// Common code for all BranchBs; come here with Digit set:
283
+
284
+JudyBranchB:
285
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
286
+ Pjbb = P_JBB(Pjp->jp_Addr);
287
+ subexp = Digit / cJU_BITSPERSUBEXPB;
288
+
289
+ BitMap = JU_JBB_BITMAP(Pjbb, subexp);
290
+ Pjp = P_JP(JU_JBB_PJP(Pjbb, subexp));
291
+
292
+ BitMask = JU_BITPOSMASKB(Digit);
293
+
294
+// No JP in subexpanse for Index => Index not found:
295
+
296
+ if (! (BitMap & BitMask)) break;
297
+
298
+// Count JPs in the subexpanse below the one for Index:
299
+
300
+ Pjp += j__udyCountBitsB(BitMap & (BitMask - 1));
301
+
302
+ goto ContinueWalk;
303
+
304
+ } // case cJU_JPBRANCH_B*
305
+
306
+
307
+// ****************************************************************************
308
+// JPBRANCH_U*:
309
+//
310
+// Notice the reverse order of the cases, and falling through to the next case,
311
+// for performance.
312
+
313
+ case cJU_JPBRANCH_U:
314
+
315
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
316
+ Pjp = JU_JBU_PJP(Pjp, Index, cJU_ROOTSTATE);
317
+
318
+// If not a BranchU, traverse; otherwise fall into the next case, which makes
319
+// this very fast code for a large Judy array (mainly BranchUs), especially
320
+// when branches are already in the cache, such as for prev/next:
321
+
322
+#ifndef JU_64BIT
323
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U3) goto ContinueWalk;
324
+#else
325
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U7) goto ContinueWalk;
326
+#endif
327
+
328
+#ifdef JU_64BIT
329
+ case cJU_JPBRANCH_U7:
330
+
331
+ // JU_DCDNOTMATCHINDEX() would be a no-op.
332
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
333
+ Pjp = JU_JBU_PJP(Pjp, Index, 7);
334
+
335
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U6) goto ContinueWalk;
336
+ // and fall through.
337
+
338
+ case cJU_JPBRANCH_U6:
339
+
340
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
341
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
342
+ Pjp = JU_JBU_PJP(Pjp, Index, 6);
343
+
344
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U5) goto ContinueWalk;
345
+ // and fall through.
346
+
347
+ case cJU_JPBRANCH_U5:
348
+
349
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
350
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
351
+ Pjp = JU_JBU_PJP(Pjp, Index, 5);
352
+
353
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U4) goto ContinueWalk;
354
+ // and fall through.
355
+
356
+ case cJU_JPBRANCH_U4:
357
+
358
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
359
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
360
+ Pjp = JU_JBU_PJP(Pjp, Index, 4);
361
+
362
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U3) goto ContinueWalk;
363
+ // and fall through.
364
+
365
+#endif // JU_64BIT
366
+
367
+ case cJU_JPBRANCH_U3:
368
+
369
+#ifdef JU_64BIT // otherwise its a no-op:
370
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
371
+#endif
372
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
373
+ Pjp = JU_JBU_PJP(Pjp, Index, 3);
374
+
375
+ if (JU_JPTYPE(Pjp) != cJU_JPBRANCH_U2) goto ContinueWalk;
376
+ // and fall through.
377
+
378
+ case cJU_JPBRANCH_U2:
379
+
380
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
381
+ DBGCODE(ParentJPType = JU_JPTYPE(Pjp);)
382
+ Pjp = JU_JBU_PJP(Pjp, Index, 2);
383
+
384
+// Note: BranchU2 is a special case that must continue traversal to a leaf,
385
+// immed, full, or null type:
386
+
387
+ goto ContinueWalk;
388
+
389
+
390
+// ****************************************************************************
391
+// JPLEAF*:
392
+//
393
+// Note: Here the calls of JU_DCDNOTMATCHINDEX() are necessary and check
394
+// whether Index is out of the expanse of a narrow pointer.
395
+
396
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
397
+
398
+ case cJU_JPLEAF1:
399
+ {
400
+ int posidx; // signed offset in leaf.
401
+
402
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
403
+
404
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
405
+ Pjll = P_JLL(Pjp->jp_Addr);
406
+
407
+ if ((posidx = j__udySearchLeaf1(Pjll, Pop1, Index)) < 0) break;
408
+
409
+ JUDY1CODE(return(1);)
410
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF1VALUEAREA(Pjll, Pop1) + posidx));)
411
+ }
412
+
413
+#endif // (JUDYL || (! JU_64BIT))
414
+
415
+ case cJU_JPLEAF2:
416
+ {
417
+ int posidx; // signed offset in leaf.
418
+
419
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 2)) break;
420
+
421
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
422
+ Pjll = P_JLL(Pjp->jp_Addr);
423
+
424
+ if ((posidx = j__udySearchLeaf2(Pjll, Pop1, Index)) < 0) break;
425
+
426
+ JUDY1CODE(return(1);)
427
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF2VALUEAREA(Pjll, Pop1) + posidx));)
428
+ }
429
+ case cJU_JPLEAF3:
430
+ {
431
+ int posidx; // signed offset in leaf.
432
+
433
+#ifdef JU_64BIT // otherwise its a no-op:
434
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 3)) break;
435
+#endif
436
+
437
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
438
+ Pjll = P_JLL(Pjp->jp_Addr);
439
+
440
+ if ((posidx = j__udySearchLeaf3(Pjll, Pop1, Index)) < 0) break;
441
+
442
+ JUDY1CODE(return(1);)
443
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF3VALUEAREA(Pjll, Pop1) + posidx));)
444
+ }
445
+#ifdef JU_64BIT
446
+ case cJU_JPLEAF4:
447
+ {
448
+ int posidx; // signed offset in leaf.
449
+
450
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 4)) break;
451
+
452
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
453
+ Pjll = P_JLL(Pjp->jp_Addr);
454
+
455
+ if ((posidx = j__udySearchLeaf4(Pjll, Pop1, Index)) < 0) break;
456
+
457
+ JUDY1CODE(return(1);)
458
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF4VALUEAREA(Pjll, Pop1) + posidx));)
459
+ }
460
+ case cJU_JPLEAF5:
461
+ {
462
+ int posidx; // signed offset in leaf.
463
+
464
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 5)) break;
465
+
466
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
467
+ Pjll = P_JLL(Pjp->jp_Addr);
468
+
469
+ if ((posidx = j__udySearchLeaf5(Pjll, Pop1, Index)) < 0) break;
470
+
471
+ JUDY1CODE(return(1);)
472
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF5VALUEAREA(Pjll, Pop1) + posidx));)
473
+ }
474
+
475
+ case cJU_JPLEAF6:
476
+ {
477
+ int posidx; // signed offset in leaf.
478
+
479
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 6)) break;
480
+
481
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
482
+ Pjll = P_JLL(Pjp->jp_Addr);
483
+
484
+ if ((posidx = j__udySearchLeaf6(Pjll, Pop1, Index)) < 0) break;
485
+
486
+ JUDY1CODE(return(1);)
487
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF6VALUEAREA(Pjll, Pop1) + posidx));)
488
+ }
489
+ case cJU_JPLEAF7:
490
+ {
491
+ int posidx; // signed offset in leaf.
492
+
493
+ // JU_DCDNOTMATCHINDEX() would be a no-op.
494
+ Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
495
+ Pjll = P_JLL(Pjp->jp_Addr);
496
+
497
+ if ((posidx = j__udySearchLeaf7(Pjll, Pop1, Index)) < 0) break;
498
+
499
+ JUDY1CODE(return(1);)
500
+ JUDYLCODE(return((PPvoid_t) (JL_LEAF7VALUEAREA(Pjll, Pop1) + posidx));)
501
+ }
502
+#endif // JU_64BIT
503
+
504
+
505
+// ****************************************************************************
506
+// JPLEAF_B1:
507
+
508
+ case cJU_JPLEAF_B1:
509
+ {
510
+ Pjlb_t Pjlb;
511
+#ifdef JUDYL
512
+ int posidx;
513
+ Word_t subexp; // in bitmap, 0..7.
514
+ BITMAPL_t BitMap; // for one subexpanse.
515
+ BITMAPL_t BitMask; // bit in BitMap for Indexs Digit.
516
+ Pjv_t Pjv;
517
+#endif
518
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
519
+
520
+ Pjlb = P_JLB(Pjp->jp_Addr);
521
+
522
+#ifdef JUDY1
523
+
524
+// Simply check if Indexs bit is set in the bitmap:
525
+
526
+ if (JU_BITMAPTESTL(Pjlb, Index)) return(1);
527
+ break;
528
+
529
+#else // JUDYL
530
+
531
+// JudyL is much more complicated because of value area subarrays:
532
+
533
+ Digit = JU_DIGITATSTATE(Index, 1);
534
+ subexp = Digit / cJU_BITSPERSUBEXPL;
535
+ BitMap = JU_JLB_BITMAP(Pjlb, subexp);
536
+ BitMask = JU_BITPOSMASKL(Digit);
537
+
538
+// No value in subexpanse for Index => Index not found:
539
+
540
+ if (! (BitMap & BitMask)) break;
541
+
542
+// Count value areas in the subexpanse below the one for Index:
543
+
544
+ Pjv = P_JV(JL_JLB_PVALUE(Pjlb, subexp));
545
+ assert(Pjv != (Pjv_t) NULL);
546
+ posidx = j__udyCountBitsL(BitMap & (BitMask - 1));
547
+
548
+ return((PPvoid_t) (Pjv + posidx));
549
+
550
+#endif // JUDYL
551
+
552
+ } // case cJU_JPLEAF_B1
553
+
554
+#ifdef JUDY1
555
+
556
+// ****************************************************************************
557
+// JPFULLPOPU1:
558
+//
559
+// If the Index is in the expanse, it is necessarily valid (found).
560
+
561
+ case cJ1_JPFULLPOPU1:
562
+
563
+ if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
564
+ return(1);
565
+
566
+#ifdef notdef // for future enhancements
567
+#ifdef JU_64BIT
568
+
569
+// Note: Need ? if (JU_DCDNOTMATCHINDEX(Index, Pjp, 1)) break;
570
+
571
+ case cJ1_JPFULLPOPU1m15:
572
+ if (Pjp->jp_1Index[14] == (uint8_t)Index) break;
573
+ case cJ1_JPFULLPOPU1m14:
574
+ if (Pjp->jp_1Index[13] == (uint8_t)Index) break;
575
+ case cJ1_JPFULLPOPU1m13:
576
+ if (Pjp->jp_1Index[12] == (uint8_t)Index) break;
577
+ case cJ1_JPFULLPOPU1m12:
578
+ if (Pjp->jp_1Index[11] == (uint8_t)Index) break;
579
+ case cJ1_JPFULLPOPU1m11:
580
+ if (Pjp->jp_1Index[10] == (uint8_t)Index) break;
581
+ case cJ1_JPFULLPOPU1m10:
582
+ if (Pjp->jp_1Index[9] == (uint8_t)Index) break;
583
+ case cJ1_JPFULLPOPU1m9:
584
+ if (Pjp->jp_1Index[8] == (uint8_t)Index) break;
585
+ case cJ1_JPFULLPOPU1m8:
586
+ if (Pjp->jp_1Index[7] == (uint8_t)Index) break;
587
+#endif
588
+ case cJ1_JPFULLPOPU1m7:
589
+ if (Pjp->jp_1Index[6] == (uint8_t)Index) break;
590
+ case cJ1_JPFULLPOPU1m6:
591
+ if (Pjp->jp_1Index[5] == (uint8_t)Index) break;
592
+ case cJ1_JPFULLPOPU1m5:
593
+ if (Pjp->jp_1Index[4] == (uint8_t)Index) break;
594
+ case cJ1_JPFULLPOPU1m4:
595
+ if (Pjp->jp_1Index[3] == (uint8_t)Index) break;
596
+ case cJ1_JPFULLPOPU1m3:
597
+ if (Pjp->jp_1Index[2] == (uint8_t)Index) break;
598
+ case cJ1_JPFULLPOPU1m2:
599
+ if (Pjp->jp_1Index[1] == (uint8_t)Index) break;
600
+ case cJ1_JPFULLPOPU1m1:
601
+ if (Pjp->jp_1Index[0] == (uint8_t)Index) break;
602
+
603
+ return(1); // found, not in exclusion list
604
+
605
+#endif // JUDY1
606
+#endif // notdef
607
+
608
+// ****************************************************************************
609
+// JPIMMED*:
610
+//
611
+// Note that the contents of jp_DcdPopO are different for cJU_JPIMMED_*_01:
612
+
613
+ case cJU_JPIMMED_1_01:
614
+ case cJU_JPIMMED_2_01:
615
+ case cJU_JPIMMED_3_01:
616
+#ifdef JU_64BIT
617
+ case cJU_JPIMMED_4_01:
618
+ case cJU_JPIMMED_5_01:
619
+ case cJU_JPIMMED_6_01:
620
+ case cJU_JPIMMED_7_01:
621
+#endif
622
+ if (JU_JPDCDPOP0(Pjp) != JU_TRIMTODCDSIZE(Index)) break;
623
+
624
+ JUDY1CODE(return(1);)
625
+ JUDYLCODE(return((PPvoid_t) &(Pjp->jp_Addr));) // immediate value area.
626
+
627
+
628
+// Macros to make code more readable and avoid dup errors
629
+
630
+#ifdef JUDY1
631
+
632
+#define CHECKINDEXNATIVE(LEAF_T, PJP, IDX, INDEX) \
633
+if (((LEAF_T *)((PJP)->jp_1Index))[(IDX) - 1] == (LEAF_T)(INDEX)) \
634
+ return(1)
635
+
636
+#define CHECKLEAFNONNAT(LFBTS, PJP, INDEX, IDX, COPY) \
637
+{ \
638
+ Word_t i_ndex; \
639
+ uint8_t *a_ddr; \
640
+ a_ddr = (PJP)->jp_1Index + (((IDX) - 1) * (LFBTS)); \
641
+ COPY(i_ndex, a_ddr); \
642
+ if (i_ndex == JU_LEASTBYTES((INDEX), (LFBTS))) \
643
+ return(1); \
644
+}
645
+#endif
646
+
647
+#ifdef JUDYL
648
+
649
+#define CHECKINDEXNATIVE(LEAF_T, PJP, IDX, INDEX) \
650
+if (((LEAF_T *)((PJP)->jp_LIndex))[(IDX) - 1] == (LEAF_T)(INDEX)) \
651
+ return((PPvoid_t)(P_JV((PJP)->jp_Addr) + (IDX) - 1))
652
+
653
+#define CHECKLEAFNONNAT(LFBTS, PJP, INDEX, IDX, COPY) \
654
+{ \
655
+ Word_t i_ndex; \
656
+ uint8_t *a_ddr; \
657
+ a_ddr = (PJP)->jp_LIndex + (((IDX) - 1) * (LFBTS)); \
658
+ COPY(i_ndex, a_ddr); \
659
+ if (i_ndex == JU_LEASTBYTES((INDEX), (LFBTS))) \
660
+ return((PPvoid_t)(P_JV((PJP)->jp_Addr) + (IDX) - 1)); \
661
+}
662
+#endif
663
+
664
+#if (defined(JUDY1) && defined(JU_64BIT))
665
+ case cJ1_JPIMMED_1_15: CHECKINDEXNATIVE(uint8_t, Pjp, 15, Index);
666
+ case cJ1_JPIMMED_1_14: CHECKINDEXNATIVE(uint8_t, Pjp, 14, Index);
667
+ case cJ1_JPIMMED_1_13: CHECKINDEXNATIVE(uint8_t, Pjp, 13, Index);
668
+ case cJ1_JPIMMED_1_12: CHECKINDEXNATIVE(uint8_t, Pjp, 12, Index);
669
+ case cJ1_JPIMMED_1_11: CHECKINDEXNATIVE(uint8_t, Pjp, 11, Index);
670
+ case cJ1_JPIMMED_1_10: CHECKINDEXNATIVE(uint8_t, Pjp, 10, Index);
671
+ case cJ1_JPIMMED_1_09: CHECKINDEXNATIVE(uint8_t, Pjp, 9, Index);
672
+ case cJ1_JPIMMED_1_08: CHECKINDEXNATIVE(uint8_t, Pjp, 8, Index);
673
+#endif
674
+#if (defined(JUDY1) || defined(JU_64BIT))
675
+ case cJU_JPIMMED_1_07: CHECKINDEXNATIVE(uint8_t, Pjp, 7, Index);
676
+ case cJU_JPIMMED_1_06: CHECKINDEXNATIVE(uint8_t, Pjp, 6, Index);
677
+ case cJU_JPIMMED_1_05: CHECKINDEXNATIVE(uint8_t, Pjp, 5, Index);
678
+ case cJU_JPIMMED_1_04: CHECKINDEXNATIVE(uint8_t, Pjp, 4, Index);
679
+#endif
680
+ case cJU_JPIMMED_1_03: CHECKINDEXNATIVE(uint8_t, Pjp, 3, Index);
681
+ case cJU_JPIMMED_1_02: CHECKINDEXNATIVE(uint8_t, Pjp, 2, Index);
682
+ CHECKINDEXNATIVE(uint8_t, Pjp, 1, Index);
683
+ break;
684
+
685
+#if (defined(JUDY1) && defined(JU_64BIT))
686
+ case cJ1_JPIMMED_2_07: CHECKINDEXNATIVE(uint16_t, Pjp, 7, Index);
687
+ case cJ1_JPIMMED_2_06: CHECKINDEXNATIVE(uint16_t, Pjp, 6, Index);
688
+ case cJ1_JPIMMED_2_05: CHECKINDEXNATIVE(uint16_t, Pjp, 5, Index);
689
+ case cJ1_JPIMMED_2_04: CHECKINDEXNATIVE(uint16_t, Pjp, 4, Index);
690
+#endif
691
+#if (defined(JUDY1) || defined(JU_64BIT))
692
+ case cJU_JPIMMED_2_03: CHECKINDEXNATIVE(uint16_t, Pjp, 3, Index);
693
+ case cJU_JPIMMED_2_02: CHECKINDEXNATIVE(uint16_t, Pjp, 2, Index);
694
+ CHECKINDEXNATIVE(uint16_t, Pjp, 1, Index);
695
+ break;
696
+#endif
697
+
698
+#if (defined(JUDY1) && defined(JU_64BIT))
699
+ case cJ1_JPIMMED_3_05:
700
+ CHECKLEAFNONNAT(3, Pjp, Index, 5, JU_COPY3_PINDEX_TO_LONG);
701
+ case cJ1_JPIMMED_3_04:
702
+ CHECKLEAFNONNAT(3, Pjp, Index, 4, JU_COPY3_PINDEX_TO_LONG);
703
+ case cJ1_JPIMMED_3_03:
704
+ CHECKLEAFNONNAT(3, Pjp, Index, 3, JU_COPY3_PINDEX_TO_LONG);
705
+#endif
706
+#if (defined(JUDY1) || defined(JU_64BIT))
707
+ case cJU_JPIMMED_3_02:
708
+ CHECKLEAFNONNAT(3, Pjp, Index, 2, JU_COPY3_PINDEX_TO_LONG);
709
+ CHECKLEAFNONNAT(3, Pjp, Index, 1, JU_COPY3_PINDEX_TO_LONG);
710
+ break;
711
+#endif
712
+
713
+#if (defined(JUDY1) && defined(JU_64BIT))
714
+
715
+ case cJ1_JPIMMED_4_03: CHECKINDEXNATIVE(uint32_t, Pjp, 3, Index);
716
+ case cJ1_JPIMMED_4_02: CHECKINDEXNATIVE(uint32_t, Pjp, 2, Index);
717
+ CHECKINDEXNATIVE(uint32_t, Pjp, 1, Index);
718
+ break;
719
+
720
+ case cJ1_JPIMMED_5_03:
721
+ CHECKLEAFNONNAT(5, Pjp, Index, 3, JU_COPY5_PINDEX_TO_LONG);
722
+ case cJ1_JPIMMED_5_02:
723
+ CHECKLEAFNONNAT(5, Pjp, Index, 2, JU_COPY5_PINDEX_TO_LONG);
724
+ CHECKLEAFNONNAT(5, Pjp, Index, 1, JU_COPY5_PINDEX_TO_LONG);
725
+ break;
726
+
727
+ case cJ1_JPIMMED_6_02:
728
+ CHECKLEAFNONNAT(6, Pjp, Index, 2, JU_COPY6_PINDEX_TO_LONG);
729
+ CHECKLEAFNONNAT(6, Pjp, Index, 1, JU_COPY6_PINDEX_TO_LONG);
730
+ break;
731
+
732
+ case cJ1_JPIMMED_7_02:
733
+ CHECKLEAFNONNAT(7, Pjp, Index, 2, JU_COPY7_PINDEX_TO_LONG);
734
+ CHECKLEAFNONNAT(7, Pjp, Index, 1, JU_COPY7_PINDEX_TO_LONG);
735
+ break;
736
+
737
+#endif // (JUDY1 && JU_64BIT)
738
+
739
+
740
+// ****************************************************************************
741
+// INVALID JP TYPE:
742
+
743
+ default:
744
+
745
+ReturnCorrupt:
746
+
747
+#ifdef JUDYGETINLINE // Pjpm is known to be non-null:
748
+ JU_SET_ERRNO_NONNULL(Pjpm, JU_ERRNO_CORRUPT);
749
+#else
750
+ JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
751
+#endif
752
+ JUDY1CODE(return(JERRI );)
753
+ JUDYLCODE(return(PPJERR);)
754
+
755
+ } // switch on JP type
756
+
757
+JUDY1CODE(return(0);)
758
+JUDYLCODE(return((PPvoid_t) NULL);)
759
+
760
+} // Judy1Test() / JudyLGet()
761
+
762
+
763
+#ifndef JUDYGETINLINE // only compile the following function once:
764
+#ifdef DEBUG
765
+
766
+// ****************************************************************************
767
+// J U D Y C H E C K P O P
768
+//
769
+// Given a pointer to a Judy array, traverse the entire array to ensure
770
+// population counts add up correctly. This can catch various coding errors.
771
+//
772
+// Since walking the entire tree is probably time-consuming, enable this
773
+// function by setting env parameter $CHECKPOP to first call at which to start
774
+// checking. Note: This function is called both from insert and delete code.
775
+//
776
+// Note: Even though this function does nothing useful for LEAFW leaves, its
777
+// good practice to call it anyway, and cheap too.
778
+//
779
+// TBD: This is a debug-only check function similar to JudyCheckSorted(), but
780
+// since it walks the tree it is Judy1/JudyL-specific and must live in a source
781
+// file that is built both ways.
782
+//
783
+// TBD: As feared, enabling this code for every insert/delete makes Judy
784
+// deathly slow, even for a small tree (10K indexes). Its not so bad if
785
+// present but disabled (<1% slowdown measured). Still, should it be ifdefd
786
+// other than DEBUG and/or called less often?
787
+//
788
+// TBD: Should this "population checker" be expanded to a comprehensive tree
789
+// checker? It currently detects invalid LEAFW/JP types as well as inconsistent
790
+// pop1s. Other possible checks, all based on essentially redundant data in
791
+// the Judy tree, include:
792
+//
793
+// - Zero LS bits in jp_Addr field.
794
+//
795
+// - Correct Dcd bits.
796
+//
797
+// - Consistent JP types (always descending down the tree).
798
+//
799
+// - Sorted linear lists in BranchLs and leaves (using JudyCheckSorted(), but
800
+// ideally that function is already called wherever appropriate after any
801
+// linear list is modified).
802
+//
803
+// - Any others possible?
804
+
805
+#include <stdlib.h> // for getenv() and atol().
806
+
807
+static Word_t JudyCheckPopSM(Pjp_t Pjp, Word_t RootPop1);
808
+
809
+FUNCTION void JudyCheckPop(
810
+ Pvoid_t PArray)
811
+{
812
+static bool_t checked = FALSE; // already checked env parameter.
813
+static bool_t enabled = FALSE; // env parameter set.
814
+static bool_t active = FALSE; // calls >= callsmin.
815
+static Word_t callsmin; // start point from $CHECKPOP.
816
+static Word_t calls = 0; // times called so far.
817
+
818
+
819
+// CHECK FOR EXTERNAL ENABLING:
820
+
821
+ if (! checked) // only check once.
822
+ {
823
+ char * value; // for getenv().
824
+
825
+ checked = TRUE;
826
+
827
+ if ((value = getenv("CHECKPOP")) == (char *) NULL)
828
+ {
829
+#ifdef notdef
830
+// Take this out because nightly tests want to be flavor-independent; its not
831
+// OK to emit special non-error output from the debug flavor:
832
+
833
+ (void) puts("JudyCheckPop() present but not enabled by "
834
+ "$CHECKPOP env parameter; set it to the number of "
835
+ "calls at which to begin checking");
836
+#endif
837
+ return;
838
+ }
839
+
840
+ callsmin = atol(value); // note: non-number evaluates to 0.
841
+ enabled = TRUE;
842
+
843
+ (void) printf("JudyCheckPop() present and enabled; callsmin = "
844
+ "%lu\n", callsmin);
845
+ }
846
+ else if (! enabled) return;
847
+
848
+// Previously or just now enabled; check if non-active or newly active:
849
+
850
+ if (! active)
851
+ {
852
+ if (++calls < callsmin) return;
853
+
854
+ (void) printf("JudyCheckPop() activated at call %lu\n", calls);
855
+ active = TRUE;
856
+ }
857
+
858
+// IGNORE LEAFW AT TOP OF TREE:
859
+
860
+ if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
861
+ return;
862
+
863
+// Check JPM pop0 against tree, recursively:
864
+//
865
+// Note: The traversal code in JudyCheckPopSM() is simplest when the case
866
+// statement for each JP type compares the pop1 for that JP to its subtree (if
867
+// any) after traversing the subtree (thats the hard part) and adding up
868
+// actual pop1s. A top branchs JP in the JPM does not have room for a
869
+// full-word pop1, so pass it in as a special case.
870
+
871
+ {
872
+ Pjpm_t Pjpm = P_JPM(PArray);
873
+ (void) JudyCheckPopSM(&(Pjpm->jpm_JP), Pjpm->jpm_Pop0 + 1);
874
+ return;
875
+ }
876
+
877
+} // JudyCheckPop()
878
+
879
+
880
+// ****************************************************************************
881
+// J U D Y C H E C K P O P S M
882
+//
883
+// Recursive state machine (subroutine) for JudyCheckPop(): Given a Pjp (other
884
+// than JPNULL*; caller should shortcut) and the root population for top-level
885
+// branches, check the subtrees actual pop1 against its nominal value, and
886
+// return the total pop1 for the subtree.
887
+//
888
+// Note: Expect RootPop1 to be ignored at lower levels, so pass down 0, which
889
+// should pop an assertion if this expectation is violated.
890
+
891
+FUNCTION static Word_t JudyCheckPopSM(
892
+ Pjp_t Pjp, // top of subtree.
893
+ Word_t RootPop1) // whole array, for top-level branches only.
894
+{
895
+ Word_t pop1_jp; // nominal population from the JP.
896
+ Word_t pop1 = 0; // actual population at this level.
897
+ Word_t offset; // in a branch.
898
+
899
+#define PREPBRANCH(cPopBytes,Next) \
900
+ pop1_jp = JU_JPBRANCH_POP0(Pjp, cPopBytes) + 1; goto Next
901
+
902
+assert((((Word_t) (Pjp->jp_Addr)) & 7) == 3);
903
+ switch (JU_JPTYPE(Pjp))
904
+ {
905
+
906
+ case cJU_JPBRANCH_L2: PREPBRANCH(2, BranchL);
907
+ case cJU_JPBRANCH_L3: PREPBRANCH(3, BranchL);
908
+#ifdef JU_64BIT
909
+ case cJU_JPBRANCH_L4: PREPBRANCH(4, BranchL);
910
+ case cJU_JPBRANCH_L5: PREPBRANCH(5, BranchL);
911
+ case cJU_JPBRANCH_L6: PREPBRANCH(6, BranchL);
912
+ case cJU_JPBRANCH_L7: PREPBRANCH(7, BranchL);
913
+#endif
914
+ case cJU_JPBRANCH_L: pop1_jp = RootPop1;
915
+ {
916
+ Pjbl_t Pjbl;
917
+BranchL:
918
+ Pjbl = P_JBL(Pjp->jp_Addr);
919
+
920
+ for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
921
+ pop1 += JudyCheckPopSM((Pjbl->jbl_jp) + offset, 0);
922
+
923
+ assert(pop1_jp == pop1);
924
+ return(pop1);
925
+ }
926
+
927
+ case cJU_JPBRANCH_B2: PREPBRANCH(2, BranchB);
928
+ case cJU_JPBRANCH_B3: PREPBRANCH(3, BranchB);
929
+#ifdef JU_64BIT
930
+ case cJU_JPBRANCH_B4: PREPBRANCH(4, BranchB);
931
+ case cJU_JPBRANCH_B5: PREPBRANCH(5, BranchB);
932
+ case cJU_JPBRANCH_B6: PREPBRANCH(6, BranchB);
933
+ case cJU_JPBRANCH_B7: PREPBRANCH(7, BranchB);
934
+#endif
935
+ case cJU_JPBRANCH_B: pop1_jp = RootPop1;
936
+ {
937
+ Word_t subexp;
938
+ Word_t jpcount;
939
+ Pjbb_t Pjbb;
940
+BranchB:
941
+ Pjbb = P_JBB(Pjp->jp_Addr);
942
+
943
+ for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
944
+ {
945
+ jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
946
+
947
+ for (offset = 0; offset < jpcount; ++offset)
948
+ {
949
+ pop1 += JudyCheckPopSM(P_JP(JU_JBB_PJP(Pjbb, subexp))
950
+ + offset, 0);
951
+ }
952
+ }
953
+
954
+ assert(pop1_jp == pop1);
955
+ return(pop1);
956
+ }
957
+
958
+ case cJU_JPBRANCH_U2: PREPBRANCH(2, BranchU);
959
+ case cJU_JPBRANCH_U3: PREPBRANCH(3, BranchU);
960
+#ifdef JU_64BIT
961
+ case cJU_JPBRANCH_U4: PREPBRANCH(4, BranchU);
962
+ case cJU_JPBRANCH_U5: PREPBRANCH(5, BranchU);
963
+ case cJU_JPBRANCH_U6: PREPBRANCH(6, BranchU);
964
+ case cJU_JPBRANCH_U7: PREPBRANCH(7, BranchU);
965
+#endif
966
+ case cJU_JPBRANCH_U: pop1_jp = RootPop1;
967
+ {
968
+ Pjbu_t Pjbu;
969
+BranchU:
970
+ Pjbu = P_JBU(Pjp->jp_Addr);
971
+
972
+ for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
973
+ {
974
+ if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
975
+ && ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
976
+ {
977
+ continue; // skip null JP to save time.
978
+ }
979
+
980
+ pop1 += JudyCheckPopSM((Pjbu->jbu_jp) + offset, 0);
981
+ }
982
+
983
+ assert(pop1_jp == pop1);
984
+ return(pop1);
985
+ }
986
+
987
+
988
+// -- Cases below here terminate and do not recurse. --
989
+//
990
+// For all of these cases except JPLEAF_B1, there is no way to check the JPs
991
+// pop1 against the object itself; just return the pop1; but for linear leaves,
992
+// a bounds check is possible.
993
+
994
+#define CHECKLEAF(MaxPop1) \
995
+ pop1 = JU_JPLEAF_POP0(Pjp) + 1; \
996
+ assert(pop1 >= 1); \
997
+ assert(pop1 <= (MaxPop1)); \
998
+ return(pop1)
999
+
1000
+#if (defined(JUDYL) || (! defined(JU_64BIT)))
1001
+ case cJU_JPLEAF1: CHECKLEAF(cJU_LEAF1_MAXPOP1);
1002
+#endif
1003
+ case cJU_JPLEAF2: CHECKLEAF(cJU_LEAF2_MAXPOP1);
1004
+ case cJU_JPLEAF3: CHECKLEAF(cJU_LEAF3_MAXPOP1);
1005
+#ifdef JU_64BIT
1006
+ case cJU_JPLEAF4: CHECKLEAF(cJU_LEAF4_MAXPOP1);
1007
+ case cJU_JPLEAF5: CHECKLEAF(cJU_LEAF5_MAXPOP1);
1008
+ case cJU_JPLEAF6: CHECKLEAF(cJU_LEAF6_MAXPOP1);
1009
+ case cJU_JPLEAF7: CHECKLEAF(cJU_LEAF7_MAXPOP1);
1010
+#endif
1011
+
1012
+ case cJU_JPLEAF_B1:
1013
+ {
1014
+ Word_t subexp;
1015
+ Pjlb_t Pjlb;
1016
+
1017
+ pop1_jp = JU_JPLEAF_POP0(Pjp) + 1;
1018
+
1019
+ Pjlb = P_JLB(Pjp->jp_Addr);
1020
+
1021
+ for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
1022
+ pop1 += j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
1023
+
1024
+ assert(pop1_jp == pop1);
1025
+ return(pop1);
1026
+ }
1027
+
1028
+ JUDY1CODE(case cJ1_JPFULLPOPU1: return(cJU_JPFULLPOPU1_POP0);)
1029
+
1030
+ case cJU_JPIMMED_1_01: return(1);
1031
+ case cJU_JPIMMED_2_01: return(1);
1032
+ case cJU_JPIMMED_3_01: return(1);
1033
+#ifdef JU_64BIT
1034
+ case cJU_JPIMMED_4_01: return(1);
1035
+ case cJU_JPIMMED_5_01: return(1);
1036
+ case cJU_JPIMMED_6_01: return(1);
1037
+ case cJU_JPIMMED_7_01: return(1);
1038
+#endif
1039
+
1040
+ case cJU_JPIMMED_1_02: return(2);
1041
+ case cJU_JPIMMED_1_03: return(3);
1042
+#if (defined(JUDY1) || defined(JU_64BIT))
1043
+ case cJU_JPIMMED_1_04: return(4);
1044
+ case cJU_JPIMMED_1_05: return(5);
1045
+ case cJU_JPIMMED_1_06: return(6);
1046
+ case cJU_JPIMMED_1_07: return(7);
1047
+#endif
1048
+#if (defined(JUDY1) && defined(JU_64BIT))
1049
+ case cJ1_JPIMMED_1_08: return(8);
1050
+ case cJ1_JPIMMED_1_09: return(9);
1051
+ case cJ1_JPIMMED_1_10: return(10);
1052
+ case cJ1_JPIMMED_1_11: return(11);
1053
+ case cJ1_JPIMMED_1_12: return(12);
1054
+ case cJ1_JPIMMED_1_13: return(13);
1055
+ case cJ1_JPIMMED_1_14: return(14);
1056
+ case cJ1_JPIMMED_1_15: return(15);
1057
+#endif
1058
+
1059
+#if (defined(JUDY1) || defined(JU_64BIT))
1060
+ case cJU_JPIMMED_2_02: return(2);
1061
+ case cJU_JPIMMED_2_03: return(3);
1062
+#endif
1063
+#if (defined(JUDY1) && defined(JU_64BIT))
1064
+ case cJ1_JPIMMED_2_04: return(4);
1065
+ case cJ1_JPIMMED_2_05: return(5);
1066
+ case cJ1_JPIMMED_2_06: return(6);
1067
+ case cJ1_JPIMMED_2_07: return(7);
1068
+#endif
1069
+
1070
+#if (defined(JUDY1) || defined(JU_64BIT))
1071
+ case cJU_JPIMMED_3_02: return(2);
1072
+#endif
1073
+#if (defined(JUDY1) && defined(JU_64BIT))
1074
+ case cJ1_JPIMMED_3_03: return(3);
1075
+ case cJ1_JPIMMED_3_04: return(4);
1076
+ case cJ1_JPIMMED_3_05: return(5);
1077
+
1078
+ case cJ1_JPIMMED_4_02: return(2);
1079
+ case cJ1_JPIMMED_4_03: return(3);
1080
+ case cJ1_JPIMMED_5_02: return(2);
1081
+ case cJ1_JPIMMED_5_03: return(3);
1082
+ case cJ1_JPIMMED_6_02: return(2);
1083
+ case cJ1_JPIMMED_7_02: return(2);
1084
+#endif
1085
+
1086
+ } // switch (JU_JPTYPE(Pjp))
1087
+
1088
+ assert(FALSE); // unrecognized JP type => corruption.
1089
+ return(0); // to make some compilers happy.
1090
+
1091
+} // JudyCheckPopSM()
1092
+
1093
+#endif // DEBUG
1094
+#endif // ! JUDYGETINLINE
netdata-installer.sh
-96
@@ -307,7 +307,6 @@ while [ -n "${1}" ]; do
307
"--disable-https") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-https)}" | sed 's/$/ --disable-plugin-https/g')" ;;
308
"--disable-dbengine")
309
NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-dbengine)}" | sed 's/$/ --disable-dbengine/g')"
310
- NETDATA_DISABLE_DBENGINE=1
310
;;
311
"--enable-plugin-nfacct") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--enable-plugin-nfacct)}" | sed 's/$/ --enable-plugin-nfacct/g')" ;;
312
"--disable-plugin-nfacct") NETDATA_CONFIGURE_OPTIONS="$(echo "${NETDATA_CONFIGURE_OPTIONS%--disable-plugin-nfacct)}" | sed 's/$/ --disable-plugin-nfacct/g')" ;;
@@ -367,9 +366,6 @@ while [ -n "${1}" ]; do
366
"--build-json-c")
367
NETDATA_BUILD_JSON_C=1
368
;;
370
- "--build-judy")
371
- NETDATA_BUILD_JUDY=1
372
- ;;
369
"--install")
370
NETDATA_PREFIX="${2}/netdata"
371
shift 1
@@ -658,98 +654,6 @@ bundle_protobuf() {
654
655
bundle_protobuf
656
661
-# -----------------------------------------------------------------------------
662
-
663
-build_judy() {
664
- env_cmd=''
665
- libtoolize="libtoolize"
666
-
667
- if [ -z "${DONT_SCRUB_CFLAGS_EVEN_THOUGH_IT_MAY_BREAK_THINGS}" ]; then
668
- env_cmd="env CFLAGS='-fPIC -pipe' CXXFLAGS='-fPIC -pipe' LDFLAGS="
669
- fi
670
-
671
- if [ "$(uname)" = "Darwin" ]; then
672
- libtoolize="glibtoolize"
673
- fi
674
-
675
- cd "${1}" > /dev/null || return 1
676
- if run eval "${env_cmd} ${libtoolize} --force --copy" &&
677
- run eval "${env_cmd} aclocal" &&
678
- run eval "${env_cmd} autoheader" &&
679
- run eval "${env_cmd} automake --add-missing --force --copy --include-deps" &&
680
- run eval "${env_cmd} autoconf" &&
681
- run eval "${env_cmd} ./configure" &&
682
- run eval "${env_cmd} ${make} ${MAKEOPTS} -C src" &&
683
- run eval "${env_cmd} ar -r src/libJudy.a src/Judy*/*.o"; then
684
- cd - > /dev/null || return 1
685
- else
686
- cd - > /dev/null || return 1
687
- return 1
688
- fi
689
-}
690
-
691
-copy_judy() {
692
- target_dir="${PWD}/externaldeps/libJudy"
693
-
694
- run mkdir -p "${target_dir}" || return 1
695
-
696
- run cp "${1}/src/libJudy.a" "${target_dir}/libJudy.a" || return 1
697
- run cp "${1}/src/Judy.h" "${target_dir}/Judy.h" || return 1
698
-}
699
-
700
-bundle_judy() {
701
- # If --build-judy flag or no Judy on the system and we're building the dbengine, bundle our own libJudy.
702
- # shellcheck disable=SC2235,SC2030,SC2031
703
- if [ -n "${NETDATA_DISABLE_DBENGINE}" ] || ([ -z "${NETDATA_BUILD_JUDY}" ] && [ -e /usr/include/Judy.h ]); then
704
- return 0
705
- elif [ -n "${NETDATA_BUILD_JUDY}" ]; then
706
- progress "User requested bundling of libJudy, building it now"
707
- elif [ ! -e /usr/include/Judy.h ]; then
708
- progress "/usr/include/Judy.h does not exist, but we need libJudy, building our own copy"
709
- fi
710
-
711
- [ -n "${GITHUB_ACTIONS}" ] && echo "::group::Bundling libJudy."
712
-
713
- progress "Prepare libJudy"
714
-
715
- JUDY_PACKAGE_VERSION="$(cat packaging/judy.version)"
716
-
717
- tmp="$(mktemp -d -t netdata-judy-XXXXXX)"
718
- JUDY_PACKAGE_BASENAME="v${JUDY_PACKAGE_VERSION}.tar.gz"
719
-
720
- if fetch_and_verify "judy" \
721
- "https://github.com/netdata/libjudy/archive/${JUDY_PACKAGE_BASENAME}" \
722
- "${JUDY_PACKAGE_BASENAME}" \
723
- "${tmp}" \
724
- "${NETDATA_LOCAL_TARBALL_OVERRIDE_JUDY}"; then
725
- if run tar --no-same-owner -xf "${tmp}/${JUDY_PACKAGE_BASENAME}" -C "${tmp}" &&
726
- build_judy "${tmp}/libjudy-${JUDY_PACKAGE_VERSION}" &&
727
- copy_judy "${tmp}/libjudy-${JUDY_PACKAGE_VERSION}" &&
728
- rm -rf "${tmp}"; then
729
- run_ok "libJudy built and prepared."
730
- NETDATA_CONFIGURE_OPTIONS="${NETDATA_CONFIGURE_OPTIONS} --with-bundled-libJudy"
731
- else
732
- if [ -n "${NETDATA_BUILD_JUDY}" ]; then
733
- [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
734
- fatal "failed to build libJudy." I0003
735
- else
736
- run_failed "Failed to build libJudy, dbengine support will be disabled."
737
- fi
738
- fi
739
- else
740
- if [ -n "${NETDATA_BUILD_JUDY}" ]; then
741
- [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
742
- fatal "Unable to fetch sources for libJudy, which is required for this build of Netdata." I0004
743
- else
744
- run_failed "Unable to fetch sources for libJudy, which is required for this build of Netdata."
745
- fi
746
- fi
747
-
748
- [ -n "${GITHUB_ACTIONS}" ] && echo "::endgroup::"
749
-}
750
-
751
-bundle_judy
752
-
657
# -----------------------------------------------------------------------------
658
build_jsonc() {
659
env_cmd=''
netdata.spec.in
-9
@@ -143,14 +143,12 @@ BuildRequires: openssl-devel
143
%if 0%{?suse_version}
144
BuildRequires: protobuf-devel
145
BuildRequires: libprotobuf-c-devel
146
-BuildRequires: judy-devel
146
BuildRequires: liblz4-devel
147
BuildRequires: libjson-c-devel
148
%else
149
%if 0%{?fedora}
150
BuildRequires: protobuf-devel
151
BuildRequires: protobuf-c-devel
153
-BuildRequires: Judy-devel
152
BuildRequires: lz4-devel
153
BuildRequires: json-c-devel
154
%else
@@ -227,10 +225,6 @@ happened, on your systems and applications.
225
226
%prep
227
%setup -q -n %{name}-%{version}
230
-# Only bundle libJudy if this isn't Fedora or SUSE
231
-%if 0%{!?fedora:1} && 0%{!?suse_version:1}
232
-export CFLAGS="${CFLAGS} -fPIC" && ${RPM_BUILD_DIR}/%{name}-%{version}/packaging/bundle-judy.sh ${RPM_BUILD_DIR}/%{name}-%{version}
233
-%endif
228
# Only bundle protobuf on CentOS 7 or earlier
229
%if 0%{?centos_ver:1}
230
%if %{centos_ver} < 8
@@ -259,9 +253,6 @@ autoreconf -ivf
253
%if 0%{!?_have_ebpf}
254
--disable-ebpf
255
%endif
262
- %if 0%{!?fedora:1} && 0%{!?suse_version:1}
263
- --with-bundled-libJudy \
264
- %endif
256
%if 0%{?centos_ver:1}
257
%if %{centos_ver} < 8
258
--with-bundled-protobuf \
packaging/bundle-judy.sh
deleted
-23
@@ -1,23 +0,0 @@
1
-#!/bin/sh
2
-
3
-JUDY_TARBALL="v$(cat "${1}/packaging/judy.version").tar.gz"
4
-JUDY_BUILD_PATH="${1}/externaldeps/libJudy/libjudy-$(cat "${1}/packaging/judy.version")"
5
-
6
-mkdir -p "${1}/externaldeps/libJudy" || exit 1
7
-curl -sSL --connect-timeout 10 --retry 3 "https://github.com/netdata/libjudy/archive/${JUDY_TARBALL}" > "${JUDY_TARBALL}" || exit 1
8
-sha256sum -c "${1}/packaging/judy.checksums" || exit 1
9
-tar -xzf "${JUDY_TARBALL}" -C "${1}/externaldeps/libJudy" || exit 1
10
-OLDPWD="${PWD}"
11
-cd "${JUDY_BUILD_PATH}" || exit 1
12
-libtoolize --force --copy || exit 1
13
-aclocal || exit 1
14
-autoheader || exit 1
15
-automake --add-missing --force --copy --include-deps || exit 1
16
-autoconf || exit 1
17
-./configure --disable-dependency-tracking || exit 1
18
-make -C src || exit 1
19
-ar -r src/libJudy.a src/Judy*/*.o || exit 1
20
-cd "${OLDPWD}" || exit 1
21
-
22
-cp -a "${JUDY_BUILD_PATH}/src/libJudy.a" "${1}/externaldeps/libJudy" || exit 1
23
-cp -a "${JUDY_BUILD_PATH}/src/Judy.h" "${1}/externaldeps/libJudy" || exit 1
packaging/docker/Dockerfile
-2
@@ -8,8 +8,6 @@ FROM netdata/builder:latest as builder
8
# One of 'nightly' or 'stable'
9
ARG RELEASE_CHANNEL=nightly
10
11
-ENV JUDY_VER 1.0.5
12
-
11
ARG CFLAGS
12
13
ENV CFLAGS=$CFLAGS
packaging/installer/dependencies/arch.sh
-1
@@ -24,7 +24,6 @@ declare -a package_tree=(
24
libuv
25
lz4
26
openssl
27
- judy
27
libelf
28
git
29
pkgconfig
packaging/installer/dependencies/centos.sh
-3
@@ -139,9 +139,6 @@ validate_tree_centos() {
139
echo >&2 " > Updating libarchive ..."
140
dnf ${opts} install libarchive
141
142
- echo >&2 " > Installing Judy-devel directly ..."
143
- dnf ${opts} install http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.x86_64.rpm
144
- dnf makecache --refresh
142
elif [[ $(os_version) =~ ^7(\..*)?$ ]]; then
143
package_manager=yum
144
echo >&2 " > Checking for EPEL ..."
packaging/installer/dependencies/debian.sh
-1
@@ -31,7 +31,6 @@ package_tree="
31
libuv1-dev
32
liblz4-dev
33
libssl-dev
34
- libjudy-dev
34
libelf-dev
35
python
36
python3
packaging/installer/dependencies/fedora.sh
-1
@@ -43,7 +43,6 @@ declare -a package_tree=(
43
libuv-devel
44
lz4-devel
45
openssl-devel
46
- Judy-devel
46
elfutils-libelf-devel
47
git
48
pkgconfig
packaging/installer/dependencies/freebsd.sh
-1
@@ -25,7 +25,6 @@ package_tree="
25
libuv
26
liblz4
27
openssl
28
- Judy
28
python3
29
"
30
packaging/installer/dependencies/gentoo.sh
-1
@@ -28,7 +28,6 @@ package_tree="
28
dev-libs/libuv
29
app-arch/lz4
30
dev-libs/openssl
31
- dev-libs/judy
31
virtual/libelf
32
dev-lang/python
33
dev-libs/libuv
packaging/installer/dependencies/opensuse.sh
-1
@@ -29,7 +29,6 @@ declare -a package_tree=(
29
libuv-devel
30
liblz4-devel
31
libopenssl-devel
32
- judy-devel
32
libelf-devel
33
git
34
tar
packaging/installer/dependencies/ubuntu.sh
-1
@@ -31,7 +31,6 @@ package_tree="
31
libuv1-dev
32
liblz4-dev
33
libssl-dev
34
- libjudy-dev
34
libelf-dev
35
python3
36
"
packaging/installer/install-required-packages.sh
-23
@@ -665,13 +665,6 @@ declare -A pkg_automake=(
665
['default']="automake"
666
)
667
668
-# required to bundle libJudy
669
-declare -A pkg_libtool=(
670
- ['gentoo']="sys-devel/libtool"
671
- ['clearlinux']="c-basic"
672
- ['default']="libtool"
673
-)
674
-
668
# Required to build libwebsockets and libmosquitto on some systems.
669
declare -A pkg_cmake=(
670
['gentoo']="dev-util/cmake"
@@ -1112,17 +1105,6 @@ declare -A pkg_openssl=(
1105
['default']="openssl-devel"
1106
)
1107
1115
-declare -A pkg_judy=(
1116
- ['debian']="libjudy-dev"
1117
- ['ubuntu']="libjudy-dev"
1118
- ['suse']="judy-devel"
1119
- ['gentoo']="dev-libs/judy"
1120
- ['arch']="judy"
1121
- ['freebsd']="Judy"
1122
- ['fedora']="Judy-devel"
1123
- ['default']="NOTREQUIRED"
1124
-)
1125
-
1108
declare -A pkg_python3=(
1109
['gentoo']="dev-lang/python"
1110
['sabayon']="dev-lang/python:3.4"
@@ -1289,7 +1271,6 @@ packages() {
1271
suitable_package autoconf-archive
1272
require_cmd autogen || suitable_package autogen
1273
require_cmd automake || suitable_package automake
1292
- require_cmd libtoolize || suitable_package libtool
1274
require_cmd pkg-config || suitable_package pkg-config
1275
require_cmd cmake || suitable_package cmake
1276
@@ -1361,7 +1342,6 @@ packages() {
1342
suitable_package libuv
1343
suitable_package lz4
1344
suitable_package openssl
1364
- suitable_package judy
1345
fi
1346
1347
# -------------------------------------------------------------------------
@@ -1579,9 +1559,6 @@ validate_tree_centos() {
1559
echo >&2 " > Updating libarchive ..."
1560
run ${sudo} yum ${opts} install libarchive
1561
1582
- echo >&2 " > Installing Judy-devel directly ..."
1583
- run ${sudo} yum ${opts} install http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.x86_64.rpm
1584
-
1562
elif [[ "${version}" =~ ^7(\..*)?$ ]]; then
1563
echo >&2 " > Checking for EPEL ..."
1564
if ! rpm -qa | grep epel-release > /dev/null; then
packaging/installer/methods/freebsd.md
+1
-1
@@ -20,7 +20,7 @@ This is how to install the latest Netdata version on FreeBSD:
20
Install required packages (**need root permission**):
21
22
```sh
23
-pkg install bash e2fsprogs-libuuid git curl autoconf automake pkgconf pidof Judy liblz4 libuv json-c cmake gmake
23
+pkg install bash e2fsprogs-libuuid git curl autoconf automake pkgconf pidof liblz4 libuv json-c cmake gmake
24
```
25
26
Download Netdata:
packaging/installer/methods/manual.md
+4
-10
@@ -25,9 +25,6 @@ and other operating systems and is regularly tested. You can find this tool [her
25
- **Alpine** Linux and its derivatives
26
- You have to install `bash` yourself, before using the installer.
27
28
-- **Arch** Linux and its derivatives
29
- - You need arch/aur for package Judy.
30
-
28
- **Gentoo** Linux and its derivatives
29
30
- **Debian** Linux and its derivatives (including **Ubuntu**, **Mint**)
@@ -67,16 +64,16 @@ This is how to do it by hand:
64
65
```sh
66
# Debian / Ubuntu
70
-apt-get install zlib1g-dev uuid-dev libuv1-dev liblz4-dev libjudy-dev libssl-dev libelf-dev libmnl-dev libprotobuf-dev protobuf-compiler gcc g++ make git autoconf autoconf-archive autogen automake pkg-config curl python cmake
67
+apt-get install zlib1g-dev uuid-dev libuv1-dev liblz4-dev libssl-dev libelf-dev libmnl-dev libprotobuf-dev protobuf-compiler gcc g++ make git autoconf autoconf-archive autogen automake pkg-config curl python cmake
68
69
# Fedora
73
-dnf install zlib-devel libuuid-devel libuv-devel lz4-devel Judy-devel openssl-devel elfutils-libelf-devel libmnl-devel protobuf-devel protobuf-compiler gcc gcc-c++ make git autoconf autoconf-archive autogen automake pkgconfig curl findutils python cmake
70
+dnf install zlib-devel libuuid-devel libuv-devel lz4-devel openssl-devel elfutils-libelf-devel libmnl-devel protobuf-devel protobuf-compiler gcc gcc-c++ make git autoconf autoconf-archive autogen automake pkgconfig curl findutils python cmake
71
72
# CentOS / Red Hat Enterprise Linux
76
-yum install autoconf automake curl gcc gcc-c++ git libmnl-devel libuuid-devel openssl-devel libuv-devel lz4-devel Judy-devel elfutils-libelf-devel protobuf protobuf-devel protobuf-compiler make nc pkgconfig python zlib-devel cmake
73
+yum install autoconf automake curl gcc gcc-c++ git libmnl-devel libuuid-devel openssl-devel libuv-devel lz4-devel elfutils-libelf-devel protobuf protobuf-devel protobuf-compiler make nc pkgconfig python zlib-devel cmake
74
75
# openSUSE
79
-zypper install zlib-devel libuuid-devel libuv-devel liblz4-devel judy-devel libopenssl-devel libelf-devel libmnl-devel protobuf-devel gcc gcc-c++ make git autoconf autoconf-archive autogen automake pkgconfig curl findutils python cmake
76
+zypper install zlib-devel libuuid-devel libuv-devel liblz4-devel libopenssl-devel libelf-devel libmnl-devel protobuf-devel gcc gcc-c++ make git autoconf autoconf-archive autogen automake pkgconfig curl findutils python cmake
77
```
78
79
Once Netdata is compiled, to run it the following packages are required (already installed using the above commands):
@@ -117,7 +114,6 @@ Netdata DB engine can be enabled when these are installed (they are optional):
114
| package | description|
115
|:-----:|-----------|
116
| `liblz4` | Extremely fast compression algorithm, version r129 or greater|
120
-| `Judy` | General purpose dynamic array|
117
| `openssl`| Cryptography and SSL/TLS toolkit|
118
119
*Netdata will greatly benefit if you have the above packages installed, but it will still work without them.*
@@ -175,8 +171,6 @@ yum install -y http://repo.okay.com.mx/centos/8/x86_64/release/okay-release-1-3.
171
# Install Devel Packages
172
yum install autoconf automake curl gcc git cmake libuuid-devel openssl-devel libuv-devel lz4-devel make nc pkgconfig python3 zlib-devel
173
178
-# Install Judy-Devel directly
179
-yum install -y http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/Judy-devel-1.0.5-18.module_el8.1.0+217+4d875839.x86_64.rpm
174
```
175
176
## Install Netdata
packaging/installer/methods/pfsense.md
-1
@@ -25,7 +25,6 @@ pkg install -y pkgconf bash e2fsprogs-libuuid libuv nano
25
Then run the following commands to download various dependencies from the FreeBSD repository.
26
27
```sh
28
-pkg add http://pkg.freebsd.org/FreeBSD:12:amd64/latest/All/Judy-1.0.5_3.txz
28
pkg add http://pkg.freebsd.org/FreeBSD:12:amd64/latest/All/json-c-0.15_1.txz
29
pkg add http://pkg.freebsd.org/FreeBSD:12:amd64/latest/All/py38-certifi-2021.10.8.txz
30
pkg add http://pkg.freebsd.org/FreeBSD:12:amd64/latest/All/py38-asn1crypto-1.4.0.txz
packaging/installer/methods/source.md
-1
@@ -32,7 +32,6 @@ Additionally, the following build time features require additional dependencies:
32
- dbengine metric storage:
33
- liblz4 r129 or newer
34
- OpenSSL 1.0 or newer (LibreSSL _amy_ work, but is largely untested).
35
- - [libJudy](http://judy.sourceforge.net/)
35
- Netdata Cloud support:
36
- A working internet connection
37
- A recent version of CMake
packaging/judy.checksums
deleted
-1
@@ -1 +0,0 @@
1
-e623a06bf091758b43f5cd97c3609f8109442d1a0441bc44819b60f2861c61b1 v1.0.5-netdata2.tar.gz
packaging/judy.version
deleted
-1
@@ -1 +0,0 @@
1
-1.0.5-netdata2