Hello community, here is the log from the commit of package tdb for openSUSE:Factory checked in at 2014-09-25 09:33:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/tdb (Old) and /work/SRC/openSUSE:Factory/.tdb.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "tdb" Changes: -------- --- /work/SRC/openSUSE:Factory/tdb/tdb.changes 2014-05-26 14:40:19.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.tdb.new/tdb.changes 2014-09-25 09:33:38.000000000 +0200 @@ -1,0 +2,20 @@ +Tue Sep 23 17:02:44 UTC 2014 - [email protected] + +- Update to version 1.3.1. + + tools: fix a compiler warning + + defragment the freelist in tdb_allocate_from_freelist() + + add "freelist_size" sub-command to tdbtool + + use tdb_freelist_merge_adjacent in tdb_freelist_size() + + add tdb_freelist_merge_adjacent() + + add utility function check_merge_ptr_with_left_record() + + simplify tdb_free() using check_merge_with_left_record() + + add utility function check_merge_with_left_record() + + improve comments for tdb_free(). + + factor merge_with_left_record() out of tdb_free() + + fix debug message in tdb_free() + + reduce indentation in tdb_free() for merging left + + increase readability of read_record_on_left() + + factor read_record_on_left() out of tdb_free() + + build: improve detection of srcdir. + +------------------------------------------------------------------- Old: ---- tdb-1.3.0.tar.asc tdb-1.3.0.tar.gz New: ---- tdb-1.3.1.tar.asc tdb-1.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ tdb.spec ++++++ --- /var/tmp/diff_new_pack.c32GMM/_old 2014-09-25 09:33:39.000000000 +0200 +++ /var/tmp/diff_new_pack.c32GMM/_new 2014-09-25 09:33:39.000000000 +0200 @@ -37,7 +37,7 @@ %endif BuildRequires: python-devel Url: http://tdb.samba.org/ -Version: 1.3.0 +Version: 1.3.1 Release: 0 Summary: Samba Trivial Database License: GPL-3.0+ ++++++ tdb-1.3.0.tar.gz -> tdb-1.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/ABI/tdb-1.3.1.sigs new/tdb-1.3.1/ABI/tdb-1.3.1.sigs --- old/tdb-1.3.0/ABI/tdb-1.3.1.sigs 1970-01-01 01:00:00.000000000 +0100 +++ new/tdb-1.3.1/ABI/tdb-1.3.1.sigs 2014-09-16 20:04:31.000000000 +0200 @@ -0,0 +1,68 @@ +tdb_add_flags: void (struct tdb_context *, unsigned int) +tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) +tdb_chainlock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) +tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock: int (struct tdb_context *, TDB_DATA) +tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) +tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_close: int (struct tdb_context *) +tdb_delete: int (struct tdb_context *, TDB_DATA) +tdb_dump_all: void (struct tdb_context *) +tdb_enable_seqnum: void (struct tdb_context *) +tdb_error: enum TDB_ERROR (struct tdb_context *) +tdb_errorstr: const char *(struct tdb_context *) +tdb_exists: int (struct tdb_context *, TDB_DATA) +tdb_fd: int (struct tdb_context *) +tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_firstkey: TDB_DATA (struct tdb_context *) +tdb_freelist_size: int (struct tdb_context *) +tdb_get_flags: int (struct tdb_context *) +tdb_get_logging_private: void *(struct tdb_context *) +tdb_get_seqnum: int (struct tdb_context *) +tdb_hash_size: int (struct tdb_context *) +tdb_increment_seqnum_nonblock: void (struct tdb_context *) +tdb_jenkins_hash: unsigned int (TDB_DATA *) +tdb_lock_nonblock: int (struct tdb_context *, int, int) +tdb_lockall: int (struct tdb_context *) +tdb_lockall_mark: int (struct tdb_context *) +tdb_lockall_nonblock: int (struct tdb_context *) +tdb_lockall_read: int (struct tdb_context *) +tdb_lockall_read_nonblock: int (struct tdb_context *) +tdb_lockall_unmark: int (struct tdb_context *) +tdb_log_fn: tdb_log_func (struct tdb_context *) +tdb_map_size: size_t (struct tdb_context *) +tdb_name: const char *(struct tdb_context *) +tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) +tdb_null: dptr = 0xXXXX, dsize = 0 +tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) +tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) +tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_printfreelist: int (struct tdb_context *) +tdb_remove_flags: void (struct tdb_context *, unsigned int) +tdb_reopen: int (struct tdb_context *) +tdb_reopen_all: int (int) +tdb_repack: int (struct tdb_context *) +tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) +tdb_runtime_check_for_robust_mutexes: bool (void) +tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) +tdb_set_max_dead: void (struct tdb_context *, int) +tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) +tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) +tdb_summary: char *(struct tdb_context *) +tdb_transaction_cancel: int (struct tdb_context *) +tdb_transaction_commit: int (struct tdb_context *) +tdb_transaction_prepare_commit: int (struct tdb_context *) +tdb_transaction_start: int (struct tdb_context *) +tdb_transaction_start_nonblock: int (struct tdb_context *) +tdb_transaction_write_lock_mark: int (struct tdb_context *) +tdb_transaction_write_lock_unmark: int (struct tdb_context *) +tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) +tdb_unlock: int (struct tdb_context *, int, int) +tdb_unlockall: int (struct tdb_context *) +tdb_unlockall_read: int (struct tdb_context *) +tdb_validate_freelist: int (struct tdb_context *, int *) +tdb_wipe_all: int (struct tdb_context *) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/buildtools/wafadmin/Tools/perl.py new/tdb-1.3.1/buildtools/wafadmin/Tools/perl.py --- old/tdb-1.3.0/buildtools/wafadmin/Tools/perl.py 2014-05-20 14:32:13.000000000 +0200 +++ new/tdb-1.3.1/buildtools/wafadmin/Tools/perl.py 2014-09-16 20:04:31.000000000 +0200 @@ -98,53 +98,12 @@ conf.env.EXTUTILS_TYPEMAP = read_out('print "$Config{privlib}/ExtUtils/typemap"') conf.env.perlext_PATTERN = '%s.' + read_out('print $Config{dlext}')[0] - def try_any(keys): - for k in keys: - conf.start_msg("Checking for perl $Config{%s}:" % k) - try: - v = read_out('print $Config{%s}' % k)[0] - conf.end_msg("'%s'" % (v), 'GREEN') - return v - except IndexError: - conf.end_msg(False, 'YELLOW') - pass - return None - - perl_arch_install_dir = None - if getattr(Options.options, 'perl_arch_install_dir', None): - perl_arch_install_dir = Options.options.perl_arch_install_dir - if perl_arch_install_dir is None: - perl_arch_install_dir = try_any(['vendorarch', 'sitearch', 'archlib']) - if perl_arch_install_dir is None: - conf.fatal('No perl arch install directory autodetected.' + - 'Please define it with --with-perl-arch-install-dir.') - conf.start_msg("PERL_ARCH_INSTALL_DIR: ") - conf.end_msg("'%s'" % (perl_arch_install_dir), 'GREEN') - conf.env.PERL_ARCH_INSTALL_DIR = perl_arch_install_dir - - perl_lib_install_dir = None - if getattr(Options.options, 'perl_lib_install_dir', None): - perl_lib_install_dir = Options.options.perl_lib_install_dir - if perl_lib_install_dir is None: - perl_lib_install_dir = try_any(['vendorlib', 'sitelib', 'privlib']) - if perl_lib_install_dir is None: - conf.fatal('No perl lib install directory autodetected. ' + - 'Please define it with --with-perl-lib-install-dir.') - conf.start_msg("PERL_LIB_INSTALL_DIR: ") - conf.end_msg("'%s'" % (perl_lib_install_dir), 'GREEN') - conf.env.PERL_LIB_INSTALL_DIR = perl_lib_install_dir + if getattr(Options.options, 'perlarchdir', None): + conf.env.ARCHDIR_PERL = Options.options.perlarchdir + else: + conf.env.ARCHDIR_PERL = read_out('print $Config{sitearch}')[0] def set_options(opt): opt.add_option("--with-perl-binary", type="string", dest="perlbinary", help = 'Specify alternate perl binary', default=None) + opt.add_option("--with-perl-archdir", type="string", dest="perlarchdir", help = 'Specify directory where to install arch specific files', default=None) - opt.add_option("--with-perl-arch-install-dir", - type="string", - dest="perl_arch_install_dir", - help = ('Specify directory where to install arch specific files'), - default=None) - - opt.add_option("--with-perl-lib-install-dir", - type="string", - dest="perl_lib_install_dir", - help = ('Specify directory where to install vendor specific files'), - default=None) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/buildtools/wafsamba/samba3.py new/tdb-1.3.1/buildtools/wafsamba/samba3.py --- old/tdb-1.3.0/buildtools/wafsamba/samba3.py 2013-06-04 16:21:30.000000000 +0200 +++ new/tdb-1.3.1/buildtools/wafsamba/samba3.py 2014-09-16 20:04:31.000000000 +0200 @@ -94,12 +94,6 @@ else: extra_includes += [ '../lib/popt' ] - if bld.CONFIG_SET('USING_SYSTEM_INIPARSER'): - (iniparser_includes, iniparser_ldflags, iniparser_cpppath) = library_flags(bld, 'iniparser') - extra_includes += iniparser_cpppath - else: - extra_includes += [ '../lib/iniparser' ] - # s3 builds assume that they will have a bunch of extra include paths includes = [] for d in extra_includes: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/buildtools/wafsamba/samba_dist.py new/tdb-1.3.1/buildtools/wafsamba/samba_dist.py --- old/tdb-1.3.0/buildtools/wafsamba/samba_dist.py 2013-01-27 12:51:43.000000000 +0100 +++ new/tdb-1.3.1/buildtools/wafsamba/samba_dist.py 2014-09-16 20:04:31.000000000 +0200 @@ -127,11 +127,14 @@ add_tarfile(tar, fname, abspath, srcsubdir) - def list_directory_files(abspath): + def list_directory_files(path): + curdir = os.getcwd() + os.chdir(srcdir) out_files = [] - for root, dirs, files in os.walk(abspath): + for root, dirs, files in os.walk(path): for f in files: out_files.append(os.path.join(root, f)) + os.chdir(curdir) return out_files diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/buildtools/wafsamba/samba_patterns.py new/tdb-1.3.1/buildtools/wafsamba/samba_patterns.py --- old/tdb-1.3.0/buildtools/wafsamba/samba_patterns.py 2014-05-05 10:00:41.000000000 +0200 +++ new/tdb-1.3.1/buildtools/wafsamba/samba_patterns.py 2014-09-16 20:04:31.000000000 +0200 @@ -139,9 +139,7 @@ fp.write(" output(screen, \" sizeof(char): %lu\\n\",(unsigned long)sizeof(char));\n") fp.write(" output(screen, \" sizeof(int): %lu\\n\",(unsigned long)sizeof(int));\n") fp.write(" output(screen, \" sizeof(long): %lu\\n\",(unsigned long)sizeof(long));\n") - fp.write("#if HAVE_LONGLONG\n") fp.write(" output(screen, \" sizeof(long long): %lu\\n\",(unsigned long)sizeof(long long));\n") - fp.write("#endif\n") fp.write(" output(screen, \" sizeof(uint8): %lu\\n\",(unsigned long)sizeof(uint8));\n") fp.write(" output(screen, \" sizeof(uint16): %lu\\n\",(unsigned long)sizeof(uint16));\n") fp.write(" output(screen, \" sizeof(uint32): %lu\\n\",(unsigned long)sizeof(uint32));\n") @@ -207,6 +205,6 @@ '''generate the bld_options.c for Samba''' t = bld.SAMBA_GENERATOR(target, rule=write_build_options, - target=target, - always=True) + dep_vars=['defines'], + target=target) Build.BuildContext.SAMBA_BLDOPTIONS = SAMBA_BLDOPTIONS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/buildtools/wafsamba/samba_perl.py new/tdb-1.3.1/buildtools/wafsamba/samba_perl.py --- old/tdb-1.3.0/buildtools/wafsamba/samba_perl.py 1970-01-01 01:00:00.000000000 +0100 +++ new/tdb-1.3.1/buildtools/wafsamba/samba_perl.py 2014-09-16 20:04:31.000000000 +0200 @@ -0,0 +1,62 @@ +import Build +from samba_utils import * +from Configure import conf + +done = {} + +@conf +def SAMBA_CHECK_PERL(conf, mandatory=True, version=(5,0,0)): + # + # TODO: use the @runonce mechanism for this. + # The problem is that @runonce currently does + # not seem to work together with @conf... + # So @runonce (and/or) @conf needs fixing. + # + if "done" in done: + return + done["done"] = True + conf.find_program('perl', var='PERL', mandatory=mandatory) + conf.check_tool('perl') + path_perl = conf.find_program('perl') + conf.env.PERL_SPECIFIED = (conf.env.PERL != path_perl) + conf.check_perl_version(version) + + def read_perl_config_var(cmd): + return Utils.to_list(Utils.cmd_output([conf.env.PERL, '-MConfig', '-e', cmd])) + + def check_perl_config_var(var): + conf.start_msg("Checking for perl $Config{%s}:" % var) + try: + v = read_perl_config_var('print $Config{%s}' % var)[0] + conf.end_msg("'%s'" % (v), 'GREEN') + return v + except IndexError: + conf.end_msg(False, 'YELLOW') + pass + return None + + vendor_prefix = check_perl_config_var('vendorprefix') + + perl_arch_install_dir = None + if vendor_prefix == conf.env.PREFIX: + perl_arch_install_dir = check_perl_config_var('vendorarch'); + if perl_arch_install_dir is None: + perl_arch_install_dir = "${LIBDIR}/perl5"; + conf.start_msg("PERL_ARCH_INSTALL_DIR: ") + conf.end_msg("'%s'" % (perl_arch_install_dir), 'GREEN') + conf.env.PERL_ARCH_INSTALL_DIR = perl_arch_install_dir + + perl_lib_install_dir = None + if vendor_prefix == conf.env.PREFIX: + perl_lib_install_dir = check_perl_config_var('vendorlib'); + if perl_lib_install_dir is None: + perl_lib_install_dir = "${DATADIR}/perl5"; + conf.start_msg("PERL_LIB_INSTALL_DIR: ") + conf.end_msg("'%s'" % (perl_lib_install_dir), 'GREEN') + conf.env.PERL_LIB_INSTALL_DIR = perl_lib_install_dir + + perl_inc = read_perl_config_var('print "@INC"') + perl_inc.remove('.') + conf.start_msg("PERL_INC: ") + conf.end_msg("%s" % (perl_inc), 'GREEN') + conf.env.PERL_INC = perl_inc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/buildtools/wafsamba/samba_third_party.py new/tdb-1.3.1/buildtools/wafsamba/samba_third_party.py --- old/tdb-1.3.0/buildtools/wafsamba/samba_third_party.py 1970-01-01 01:00:00.000000000 +0100 +++ new/tdb-1.3.1/buildtools/wafsamba/samba_third_party.py 2014-09-16 20:04:31.000000000 +0200 @@ -0,0 +1,35 @@ +# functions to support third party libraries + +from Configure import conf +import sys, Logs, os +from samba_bundled import * + +@conf +def CHECK_FOR_THIRD_PARTY(conf): + return os.path.exists(os.path.join(Utils.g_module.srcdir, 'third_party')) + +Build.BuildContext.CHECK_FOR_THIRD_PARTY = CHECK_FOR_THIRD_PARTY + +@conf +def CHECK_ZLIB(conf): + version_check=''' + #if (ZLIB_VERNUM >= 0x1230) + #else + #error "ZLIB_VERNUM < 0x1230" + #endif + z_stream *z; + inflateInit2(z, -15); + ''' + return conf.CHECK_BUNDLED_SYSTEM('z', minversion='1.2.3', pkg='zlib', + checkfunctions='zlibVersion', + headers='zlib.h', + checkcode=version_check, + implied_deps='replace') + +Build.BuildContext.CHECK_ZLIB = CHECK_ZLIB + +@conf +def CHECK_POPT(conf): + return conf.CHECK_BUNDLED_SYSTEM('popt', checkfunctions='poptGetContext', headers='popt.h') + +Build.BuildContext.CHECK_POPT = CHECK_POPT diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/buildtools/wafsamba/wafsamba.py new/tdb-1.3.1/buildtools/wafsamba/wafsamba.py --- old/tdb-1.3.0/buildtools/wafsamba/wafsamba.py 2014-05-05 10:00:41.000000000 +0200 +++ new/tdb-1.3.1/buildtools/wafsamba/wafsamba.py 2014-09-16 20:04:31.000000000 +0200 @@ -16,8 +16,10 @@ from samba_pidl import * from samba_autoproto import * from samba_python import * +from samba_perl import * from samba_deps import * from samba_bundled import * +from samba_third_party import * import samba_install import samba_conftests import samba_abi @@ -588,6 +590,7 @@ public_headers_install=True, header_path=None, vars=None, + dep_vars=[], always=False): '''A generic source generator target''' @@ -597,11 +600,8 @@ if not enabled: return - dep_vars = [] - if isinstance(vars, dict): - dep_vars = vars.keys() - elif isinstance(vars, list): - dep_vars = vars + dep_vars.append('ruledeps') + dep_vars.append('SAMBA_GENERATOR_VARS') bld.SET_BUILD_GROUP(group) t = bld( @@ -613,9 +613,13 @@ before='cc', ext_out='.c', samba_type='GENERATOR', - dep_vars = [rule] + dep_vars, + dep_vars = dep_vars, name=name) + if vars is None: + vars = {} + t.env.SAMBA_GENERATOR_VARS = vars + if always: t.always = True @@ -711,8 +715,6 @@ replacement="""sys.path.insert(0, "%s") sys.path.insert(1, "%s")""" % (task.env["PYTHONARCHDIR"], task.env["PYTHONDIR"]) - shebang = None - if task.env["PYTHON"][0] == "/": replacement_shebang = "#!%s\n" % task.env["PYTHON"] else: @@ -734,9 +736,38 @@ os.chmod(installed_location, 0755) return 0 +def copy_and_fix_perl_path(task): + pattern='use lib "$RealBin/lib";' + + replacement = "" + if not task.env["PERL_LIB_INSTALL_DIR"] in task.env["PERL_INC"]: + replacement = 'use lib "%s";' % task.env["PERL_LIB_INSTALL_DIR"] + + if task.env["PERL"][0] == "/": + replacement_shebang = "#!%s\n" % task.env["PERL"] + else: + replacement_shebang = "#!/usr/bin/env %s\n" % task.env["PERL"] + + installed_location=task.outputs[0].bldpath(task.env) + source_file = open(task.inputs[0].srcpath(task.env)) + installed_file = open(installed_location, 'w') + lineno = 0 + for line in source_file: + newline = line + if lineno == 0 and task.env["PERL_SPECIFIED"] == True and line[:2] == "#!": + newline = replacement_shebang + elif pattern in line: + newline = line.replace(pattern, replacement) + installed_file.write(newline) + lineno = lineno + 1 + installed_file.close() + os.chmod(installed_location, 0755) + return 0 + def install_file(bld, destdir, file, chmod=MODE_644, flat=False, - python_fixup=False, destname=None, base_name=None): + python_fixup=False, perl_fixup=False, + destname=None, base_name=None): '''install a file''' destdir = bld.EXPAND_VARIABLES(destdir) if not destname: @@ -745,16 +776,22 @@ destname = os.path.basename(destname) dest = os.path.join(destdir, destname) if python_fixup: - # fixup the python path it will use to find Samba modules + # fix the path python will use to find Samba modules inst_file = file + '.inst' bld.SAMBA_GENERATOR('python_%s' % destname, rule=copy_and_fix_python_path, + dep_vars=["PYTHON","PYTHON_SPECIFIED","PYTHONDIR","PYTHONARCHDIR"], + source=file, + target=inst_file) + file = inst_file + if perl_fixup: + # fix the path perl will use to find Samba modules + inst_file = file + '.inst' + bld.SAMBA_GENERATOR('perl_%s' % destname, + rule=copy_and_fix_perl_path, + dep_vars=["PERL","PERL_SPECIFIED","PERL_LIB_INSTALL_DIR"], source=file, target=inst_file) - bld.add_manual_dependency(bld.path.find_or_declare(inst_file), bld.env["PYTHONARCHDIR"]) - bld.add_manual_dependency(bld.path.find_or_declare(inst_file), bld.env["PYTHONDIR"]) - bld.add_manual_dependency(bld.path.find_or_declare(inst_file), str(bld.env["PYTHON_SPECIFIED"])) - bld.add_manual_dependency(bld.path.find_or_declare(inst_file), bld.env["PYTHON"]) file = inst_file if base_name: file = os.path.join(base_name, file) @@ -762,12 +799,13 @@ def INSTALL_FILES(bld, destdir, files, chmod=MODE_644, flat=False, - python_fixup=False, destname=None, base_name=None): + python_fixup=False, perl_fixup=False, + destname=None, base_name=None): '''install a set of files''' for f in TO_LIST(files): install_file(bld, destdir, f, chmod=chmod, flat=flat, - python_fixup=python_fixup, destname=destname, - base_name=base_name) + python_fixup=python_fixup, perl_fixup=perl_fixup, + destname=destname, base_name=base_name) Build.BuildContext.INSTALL_FILES = INSTALL_FILES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/common/freelist.c new/tdb-1.3.1/common/freelist.c --- old/tdb-1.3.0/common/freelist.c 2014-05-05 10:00:41.000000000 +0200 +++ new/tdb-1.3.1/common/freelist.c 2014-09-16 20:04:31.000000000 +0200 @@ -97,10 +97,217 @@ &totalsize); } -/* Add an element into the freelist. Merge adjacent records if - necessary. */ +/** + * Read the record directly on the left. + * Fail if there is no record on the left. + */ +static int read_record_on_left(struct tdb_context *tdb, tdb_off_t rec_ptr, + tdb_off_t *left_p, + struct tdb_record *left_r) +{ + tdb_off_t left_ptr; + tdb_off_t left_size; + struct tdb_record left_rec; + int ret; + + left_ptr = rec_ptr - sizeof(tdb_off_t); + + if (left_ptr <= TDB_DATA_START(tdb->hash_size)) { + /* no record on the left */ + return -1; + } + + /* Read in tailer and jump back to header */ + ret = tdb_ofs_read(tdb, left_ptr, &left_size); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_free: left offset read failed at %u\n", left_ptr)); + return -1; + } + + /* it could be uninitialised data */ + if (left_size == 0 || left_size == TDB_PAD_U32) { + return -1; + } + + if (left_size > rec_ptr) { + return -1; + } + + left_ptr = rec_ptr - left_size; + + if (left_ptr < TDB_DATA_START(tdb->hash_size)) { + return -1; + } + + /* Now read in the left record */ + ret = tdb->methods->tdb_read(tdb, left_ptr, &left_rec, + sizeof(left_rec), DOCONV()); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "tdb_free: left read failed at %u (%u)\n", + left_ptr, left_size)); + return -1; + } + + *left_p = left_ptr; + *left_r = left_rec; + + return 0; +} + +/** + * Merge new freelist record with the direct left neighbour. + * This assumes that left_rec represents the record + * directly to the left of right_rec and that this is + * a freelist record. + */ +static int merge_with_left_record(struct tdb_context *tdb, + tdb_off_t left_ptr, + struct tdb_record *left_rec, + struct tdb_record *right_rec) +{ + int ret; + + left_rec->rec_len += sizeof(*right_rec) + right_rec->rec_len; + + ret = tdb_rec_write(tdb, left_ptr, left_rec); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "merge_with_left_record: update_left failed at %u\n", + left_ptr)); + return -1; + } + + ret = update_tailer(tdb, left_ptr, left_rec); + if (ret == -1) { + TDB_LOG((tdb, TDB_DEBUG_FATAL, + "merge_with_left_record: update_tailer failed at %u\n", + left_ptr)); + return -1; + } + + return 0; +} + +/** + * Check whether the record left of a given freelist record is + * also a freelist record, and if so, merge the two records. + * + * Return code: + * -1 upon error + * 0 if left was not a free record + * 1 if left was free and successfully merged. + * + * The currend record is handed in with pointer and fully read record. + * + * The left record pointer and struct can be retrieved as result + * in lp and lr; + */ +static int check_merge_with_left_record(struct tdb_context *tdb, + tdb_off_t rec_ptr, + struct tdb_record *rec, + tdb_off_t *lp, + struct tdb_record *lr) +{ + tdb_off_t left_ptr; + struct tdb_record left_rec; + int ret; + + ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); + if (ret != 0) { + return 0; + } + + if (left_rec.magic != TDB_FREE_MAGIC) { + return 0; + } + + /* It's free - expand to include it. */ + ret = merge_with_left_record(tdb, left_ptr, &left_rec, rec); + if (ret != 0) { + return -1; + } + + if (lp != NULL) { + *lp = left_ptr; + } + + if (lr != NULL) { + *lr = left_rec; + } + + return 1; +} + +/** + * Check whether the record left of a given freelist record is + * also a freelist record, and if so, merge the two records. + * + * Return code: + * -1 upon error + * 0 if left was not a free record + * 1 if left was free and successfully merged. + * + * In this variant, the input record is specified just as the pointer + * and is read from the database if needed. + * + * next_ptr will contain the original record's next pointer after + * successful merging (which will be lost after merging), so that + * the caller can update the last pointer. + */ +static int check_merge_ptr_with_left_record(struct tdb_context *tdb, + tdb_off_t rec_ptr, + tdb_off_t *next_ptr) +{ + tdb_off_t left_ptr; + struct tdb_record rec, left_rec; + int ret; + + ret = read_record_on_left(tdb, rec_ptr, &left_ptr, &left_rec); + if (ret != 0) { + return 0; + } + + if (left_rec.magic != TDB_FREE_MAGIC) { + return 0; + } + + /* It's free - expand to include it. */ + + ret = tdb->methods->tdb_read(tdb, rec_ptr, &rec, + sizeof(rec), DOCONV()); + if (ret != 0) { + return -1; + } + + ret = merge_with_left_record(tdb, left_ptr, &left_rec, &rec); + if (ret != 0) { + return -1; + } + + if (next_ptr != NULL) { + *next_ptr = rec.next; + } + + return 1; +} + +/** + * Add an element into the freelist. + * + * We merge the new record into the left record if it is also a + * free record, but not with the right one. This makes the + * operation O(1) instead of O(n): merging with the right record + * requires a traverse of the freelist to find the previous + * record in the free list. + * + * This prevents db traverses from being O(n^2) after a lot of deletes. + */ int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) { + int ret; + /* Allocation and tailer lock */ if (tdb_lock(tdb, -1, F_WRLCK) != 0) return -1; @@ -138,58 +345,17 @@ left: #endif - /* Look left */ - if (offset - sizeof(tdb_off_t) > TDB_DATA_START(tdb->hash_size)) { - tdb_off_t left = offset - sizeof(tdb_off_t); - struct tdb_record l; - tdb_off_t leftsize; - - /* Read in tailer and jump back to header */ - if (tdb_ofs_read(tdb, left, &leftsize) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left offset read failed at %u\n", left)); - goto update; - } - - /* it could be uninitialised data */ - if (leftsize == 0 || leftsize == TDB_PAD_U32) { - goto update; - } - - left = offset - leftsize; - - if (leftsize > offset || - left < TDB_DATA_START(tdb->hash_size)) { - goto update; - } - - /* Now read in the left record */ - if (tdb->methods->tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); - goto update; - } - - /* If it's free, expand to include it. */ - if (l.magic == TDB_FREE_MAGIC) { - /* we now merge the new record into the left record, rather than the other - way around. This makes the operation O(1) instead of O(n). This change - prevents traverse from being O(n^2) after a lot of deletes */ - l.rec_len += sizeof(*rec) + rec->rec_len; - if (tdb_rec_write(tdb, left, &l) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_left failed at %u\n", left)); - goto fail; - } - if (update_tailer(tdb, left, &l) == -1) { - TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - } + ret = check_merge_with_left_record(tdb, offset, rec, NULL, NULL); + if (ret == -1) { + goto fail; + } + if (ret == 1) { + /* merged */ + goto done; } -update: + /* Nothing to merge, prepend to free list */ - /* Now, prepend to free list */ rec->magic = TDB_FREE_MAGIC; if (tdb_ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || @@ -199,6 +365,7 @@ goto fail; } +done: /* And we're done. */ tdb_unlock(tdb, -1, F_WRLCK); return 0; @@ -282,6 +449,7 @@ tdb_len_t rec_len; } bestfit; float multiplier = 1.0; + bool merge_created_candidate; /* over-allocate to reduce fragmentation */ length *= 1.25; @@ -291,6 +459,7 @@ length = TDB_ALIGN(length, TDB_ALIGNMENT); again: + merge_created_candidate = false; last_ptr = FREELIST_TOP; /* read in the freelist top */ @@ -307,10 +476,59 @@ issues when faced with a slowly increasing record size. */ while (rec_ptr) { + int ret; + tdb_off_t left_ptr; + struct tdb_record left_rec; + if (tdb_rec_free_read(tdb, rec_ptr, rec) == -1) { return 0; } + ret = check_merge_with_left_record(tdb, rec_ptr, rec, + &left_ptr, &left_rec); + if (ret == -1) { + return 0; + } + if (ret == 1) { + /* merged */ + rec_ptr = rec->next; + ret = tdb_ofs_write(tdb, last_ptr, &rec->next); + if (ret == -1) { + return 0; + } + + /* + * We have merged the current record into the left + * neighbour. So our traverse of the freelist will + * skip it and consider the next record in the chain. + * + * But the enlarged left neighbour may be a candidate. + * If it is, we can not directly use it, though. + * The only thing we can do and have to do here is to + * update the current best fit size in the chain if the + * current best fit is the left record. (By that we may + * worsen the best fit we already had, bit this is not a + * problem.) + * + * If the current best fit is not the left record, + * all we can do is remember the fact that a merge + * created a new candidate so that we can trigger + * a second walk of the freelist if at the end of + * the first walk we have not found any fit. + * This way we can avoid expanding the database. + */ + + if (bestfit.rec_ptr == left_ptr) { + bestfit.rec_len = left_rec.rec_len; + } + + if (left_rec.rec_len > length) { + merge_created_candidate = true; + } + + continue; + } + if (rec->rec_len >= length) { if (bestfit.rec_ptr == 0 || rec->rec_len < bestfit.rec_len) { @@ -350,6 +568,10 @@ return newrec_ptr; } + if (merge_created_candidate) { + goto again; + } + /* we didn't find enough space. See if we can expand the database and if we can then try again */ if (tdb_expand(tdb, length + sizeof(*rec)) == 0) @@ -444,10 +666,69 @@ return ret; } -/* - return the size of the freelist - used to decide if we should repack -*/ -_PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb) +/** + * Merge adjacent records in the freelist. + */ +static int tdb_freelist_merge_adjacent(struct tdb_context *tdb, + int *count_records, int *count_merged) +{ + tdb_off_t cur, next; + int count = 0; + int merged = 0; + int ret; + + ret = tdb_lock(tdb, -1, F_RDLCK); + if (ret == -1) { + return -1; + } + + cur = FREELIST_TOP; + while (tdb_ofs_read(tdb, cur, &next) == 0 && next != 0) { + tdb_off_t next2; + + count++; + + ret = check_merge_ptr_with_left_record(tdb, next, &next2); + if (ret == -1) { + goto done; + } + if (ret == 1) { + /* + * merged: + * now let cur->next point to next2 instead of next + */ + + ret = tdb_ofs_write(tdb, cur, &next2); + if (ret != 0) { + goto done; + } + + next = next2; + merged++; + } + + cur = next; + } + + if (count_records != NULL) { + *count_records = count; + } + + if (count_merged != NULL) { + *count_merged = merged; + } + + ret = 0; + +done: + tdb_unlock(tdb, -1, F_RDLCK); + return ret; +} + +/** + * return the size of the freelist - no merging done + */ +static int tdb_freelist_size_no_merge(struct tdb_context *tdb) { tdb_off_t ptr; int count=0; @@ -464,3 +745,28 @@ tdb_unlock(tdb, -1, F_RDLCK); return count; } + +/** + * return the size of the freelist - used to decide if we should repack + * + * As a side effect, adjacent records are merged unless the + * database is read-only, in order to reduce the fragmentation + * without repacking. + */ +_PUBLIC_ int tdb_freelist_size(struct tdb_context *tdb) +{ + + int count = 0; + + if (tdb->read_only) { + count = tdb_freelist_size_no_merge(tdb); + } else { + int ret; + ret = tdb_freelist_merge_adjacent(tdb, &count, NULL); + if (ret != 0) { + return -1; + } + } + + return count; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/lib/replace/replace.h new/tdb-1.3.1/lib/replace/replace.h --- old/tdb-1.3.0/lib/replace/replace.h 2014-05-05 10:00:41.000000000 +0200 +++ new/tdb-1.3.1/lib/replace/replace.h 2014-09-16 20:04:31.000000000 +0200 @@ -904,4 +904,9 @@ bool socket_wrapper_enabled(void); bool uid_wrapper_enabled(void); +/* Needed for Solaris atomic_add_XX functions. */ +#if defined(HAVE_SYS_ATOMIC_H) +#include <sys/atomic.h> +#endif + #endif /* _LIBREPLACE_REPLACE_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/lib/replace/test/os2_delete.c new/tdb-1.3.1/lib/replace/test/os2_delete.c --- old/tdb-1.3.0/lib/replace/test/os2_delete.c 2013-01-27 12:51:43.000000000 +0100 +++ new/tdb-1.3.1/lib/replace/test/os2_delete.c 2014-09-16 20:04:31.000000000 +0200 @@ -22,7 +22,7 @@ static int test_readdir_os2_delete_ret; -#define FAILED(d) (printf("failure: readdir [\nFailed for %s - %d = %s\n]\n", d, errno, strerror(errno)), test_readdir_os2_delete_ret = 1, 1) +#define FAILED(d) (printf("failure: readdir [\nFailed for %s - %d = %s\n]\n", d, errno, strerror(errno)), test_readdir_os2_delete_ret = 1) #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/lib/replace/wscript new/tdb-1.3.1/lib/replace/wscript --- old/tdb-1.3.0/lib/replace/wscript 2014-05-23 00:30:38.000000000 +0200 +++ new/tdb-1.3.1/lib/replace/wscript 2014-09-16 20:04:31.000000000 +0200 @@ -5,16 +5,16 @@ blddir = 'bin' -import sys, os, Utils +import sys, os # find the buildtools directory srcdir = '.' while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5: - srcdir = '../' + srcdir + srcdir = srcdir + '/..' sys.path.insert(0, srcdir + '/buildtools/wafsamba') import wafsamba, samba_dist -import Options, os, preproc +import Options samba_dist.DIST_DIRS('lib/replace buildtools:buildtools') @@ -59,10 +59,10 @@ # Try to find the right extra flags for -Werror behaviour for f in ["-Werror", # GCC - "-errwarn=%all", # Sun Studio - "-qhalt=w", # IBM xlc - "-w2", # Tru64 - ]: + "-errwarn=%all", # Sun Studio + "-qhalt=w", # IBM xlc + "-w2", # Tru64 + ]: if conf.CHECK_CFLAGS([f], ''' '''): if not 'WERROR_CFLAGS' in conf.env: @@ -110,6 +110,7 @@ conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h') conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h malloc.h') conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h') + conf.CHECK_HEADERS('sys/atomic.h') # Check for process set name support conf.CHECK_CODE(''' @@ -229,6 +230,30 @@ msg="Checking whether we have ucontext_t", headers='signal.h sys/ucontext.h') + # Check for atomic builtins. */ + conf.CHECK_CODE(''' + int main(void) { + int i; + (void)__sync_fetch_and_add(&i, 1); + return 0; + } + ''', + 'HAVE___SYNC_FETCH_AND_ADD', + msg='Checking for __sync_fetch_and_add compiler builtin') + + conf.CHECK_CODE(''' + #include <stdint.h> + #include <sys/atomic.h> + int main(void) { + int32_t i; + atomic_add_32(&i, 1); + return 0; + } + ''', + 'HAVE_ATOMIC_ADD_32', + headers='stdint.h sys/atomic.h', + msg='Checking for atomic_add_32 compiler builtin') + # these may be builtins, so we need the link=False strategy conf.CHECK_FUNCS('strdup memmem printf memset memcpy memmove strcpy strncpy bzero', link=False) @@ -263,8 +288,8 @@ checklibc=True) if not conf.CHECK_FUNCS('getpeereid'): conf.CHECK_FUNCS_IN('getpeereid', 'bsd', headers='sys/types.h bsd/unistd.h') - if not conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h'): - conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h') + if not conf.CHECK_FUNCS_IN('setproctitle', 'setproctitle', headers='setproctitle.h'): + conf.CHECK_FUNCS_IN('setproctitle', 'bsd', headers='sys/types.h bsd/unistd.h') conf.CHECK_CODE(''' struct ucred cred; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/tools/tdbtool.c new/tdb-1.3.1/tools/tdbtool.c --- old/tdb-1.3.0/tools/tdbtool.c 2014-05-23 00:30:38.000000000 +0200 +++ new/tdb-1.3.1/tools/tdbtool.c 2014-09-16 20:04:31.000000000 +0200 @@ -55,6 +55,7 @@ CMD_DELETE, CMD_LIST_HASH_FREE, CMD_LIST_FREE, + CMD_FREELIST_SIZE, CMD_INFO, CMD_MMAP, CMD_SPEED, @@ -89,6 +90,7 @@ {"delete", CMD_DELETE}, {"list", CMD_LIST_HASH_FREE}, {"free", CMD_LIST_FREE}, + {"freelist_size", CMD_FREELIST_SIZE}, {"info", CMD_INFO}, {"speed", CMD_SPEED}, {"mmap", CMD_MMAP}, @@ -232,6 +234,7 @@ " delete key : delete a record by key\n" " list : print the database hash table and freelist\n" " free : print the database freelist\n" +" freelist_size : print the number of records in the freelist\n" " check : check the integrity of an opened database\n" " repack : repack the database\n" " speed : perform speed tests on the database\n" @@ -710,6 +713,18 @@ case CMD_LIST_FREE: tdb_printfreelist(tdb); return 0; + case CMD_FREELIST_SIZE: { + int size; + + size = tdb_freelist_size(tdb); + if (size < 0) { + printf("Error getting freelist size.\n"); + } else { + printf("freelist size: %d\n", size); + } + + return 0; + } case CMD_INFO: info_tdb(); return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/tools/tdbtorture.c new/tdb-1.3.1/tools/tdbtorture.c --- old/tdb-1.3.0/tools/tdbtorture.c 2014-05-23 00:30:38.000000000 +0200 +++ new/tdb-1.3.1/tools/tdbtorture.c 2014-09-16 20:04:31.000000000 +0200 @@ -350,6 +350,10 @@ seed = (getpid() + time(NULL)) & 0x7FFFFFFF; } + printf("Testing with %d processes, %d loops, %d hash_size, seed=%d%s\n", + num_procs, num_loops, hash_size, seed, + (always_transaction ? " (all within transactions)" : "")); + if (num_procs == 1 && !kill_random) { /* Don't fork for this case, makes debugging easier. */ error_count = run_child(test_tdb, 0, seed, num_loops, 0); @@ -376,10 +380,6 @@ for (i=0;i<num_procs;i++) { if ((pids[i]=fork()) == 0) { close(pfds[0]); - if (i == 0) { - printf("Testing with %d processes, %d loops, %d hash_size, seed=%d%s\n", - num_procs, num_loops, hash_size, seed, always_transaction ? " (all within transactions)" : ""); - } exit(run_child(test_tdb, i, seed, num_loops, 0)); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tdb-1.3.0/wscript new/tdb-1.3.1/wscript --- old/tdb-1.3.0/wscript 2014-05-23 00:30:38.000000000 +0200 +++ new/tdb-1.3.1/wscript 2014-09-16 20:04:31.000000000 +0200 @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'tdb' -VERSION = '1.3.0' +VERSION = '1.3.1' blddir = 'bin' @@ -10,7 +10,7 @@ # find the buildtools directory srcdir = '.' while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5: - srcdir = '../' + srcdir + srcdir = srcdir + '/..' sys.path.insert(0, srcdir + '/buildtools/wafsamba') import wafsamba, samba_dist, Options, Logs -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
