summaryrefslogtreecommitdiff
path: root/plugins/Dbx_kv
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2017-10-24 14:21:30 +0300
committerGeorge Hazan <ghazan@miranda.im>2017-10-24 14:21:30 +0300
commit753a9206768e249e8efedbab65c06641bb8956ac (patch)
treea91251bfd66b5279a867c9c708bd913a980f02c5 /plugins/Dbx_kv
parent3aeb9c4fc4877b04b2ec05a191a6a7b8d231f104 (diff)
we don't need these test plugins anymore
Diffstat (limited to 'plugins/Dbx_kv')
-rw-r--r--plugins/Dbx_kv/Dbx_kv_10.vcxproj319
-rw-r--r--plugins/Dbx_kv/Dbx_kv_10.vcxproj.filters182
-rw-r--r--plugins/Dbx_kv/Dbx_kv_12.vcxproj327
-rw-r--r--plugins/Dbx_kv/Dbx_kv_12.vcxproj.filters182
-rw-r--r--plugins/Dbx_kv/Dbx_kv_15.vcxproj328
-rw-r--r--plugins/Dbx_kv/Dbx_kv_15.vcxproj.filters182
-rw-r--r--plugins/Dbx_kv/res/dbx_kv.rc160
-rw-r--r--plugins/Dbx_kv/res/logo.icobin5430 -> 0 bytes
-rw-r--r--plugins/Dbx_kv/res/pass.icobin1150 -> 0 bytes
-rw-r--r--plugins/Dbx_kv/res/version.rc38
-rw-r--r--plugins/Dbx_kv/src/commonheaders.h80
-rw-r--r--plugins/Dbx_kv/src/dbcontacts.cpp262
-rw-r--r--plugins/Dbx_kv/src/dbcrypt.cpp263
-rw-r--r--plugins/Dbx_kv/src/dbevents.cpp371
-rw-r--r--plugins/Dbx_kv/src/dbintf.cpp303
-rw-r--r--plugins/Dbx_kv/src/dbintf.h308
-rw-r--r--plugins/Dbx_kv/src/dbmodulechain.cpp143
-rw-r--r--plugins/Dbx_kv/src/dbsettings.cpp605
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/AUTHORS6
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/COPYING202
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/CREDITS6
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/NEWS1
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/README261
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/config.h10
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb.h2535
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb.hpp711
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_int.h319
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_ola.h244
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_srv.h118
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/include/ham/msstdint.h259
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/include/ham/types.h143
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/0root/root.h102
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/abi.h68
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/dynamic_array.h157
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/error.cc117
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/error.h120
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/mutex.h53
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/packstart.h74
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/packstop.h36
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/pickle.h119
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/scoped_ptr.h54
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/spinlock.h127
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/util.cc36
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1base/util.h62
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1errorinducer/errorinducer.cc31
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1errorinducer/errorinducer.h116
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1globals/globals.cc60
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1globals/globals.h89
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1mem/mem.cc60
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1mem/mem.h151
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1os/file.h154
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1os/os.cc29
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1os/os.h73
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1os/os_posix.cc474
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1os/os_win32.cc542
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1os/socket.h75
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/1rb/rb.h977
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2config/db_config.h73
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2config/env_config.h102
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2device/device.h124
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2device/device_disk.h238
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2device/device_factory.h52
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2device/device_inmem.h181
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2lsn_manager/lsn_manager.h57
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2lsn_manager/lsn_manager_test.h54
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2page/page.cc103
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2page/page.h435
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2page/page_collection.h182
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2protobuf/Makefile.am15
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2protobuf/Makefile.in627
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2protobuf/messages.proto457
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2protobuf/protocol.h147
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2protoserde/Makefile.am5
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2protoserde/Makefile.in451
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2protoserde/messages.h1839
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2protoserde/messages.proto646
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2queue/queue.h131
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/2worker/worker.h106
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager.cc85
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager.h231
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_disk.cc637
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_disk.h196
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_factory.h44
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_inmem.cc148
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_inmem.h75
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_check.cc325
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_cursor.cc561
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_cursor.h246
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_erase.cc233
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_find.cc226
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_flags.h95
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_base.h475
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_default.h532
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_pax.h141
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index.cc269
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index.h455
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index_factory.h445
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_insert.cc214
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_base.h114
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_binary.h273
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_pod.h261
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_varlen.h533
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_node.h175
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_node_proxy.h609
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_base.h64
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_default.h424
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_duplicate.h1557
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_inline.h230
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_internal.h230
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_stats.cc181
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_stats.h179
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_update.cc436
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_update.h113
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_visit.cc117
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_visitor.h70
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3btree/upfront_index.h684
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3cache/cache.h244
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3changeset/changeset.cc113
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3changeset/changeset.h118
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3journal/journal.cc862
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3journal/journal.h329
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_entries.h208
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_state.h104
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_test.h58
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager.cc798
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager.h155
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_state.h121
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_test.h76
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_worker.h97
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4context/context.h57
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4cursor/cursor.cc1119
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4cursor/cursor.h555
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4db/db.cc143
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4db/db.h232
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4db/db_local.cc1776
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4db/db_local.h278
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4db/db_remote.cc635
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4db/db_remote.h131
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env.cc333
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env.h210
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env_header.h184
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env_local.cc760
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env_local.h192
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env_local_test.h56
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env_remote.cc445
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env_remote.h125
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4env/env_test.h60
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4txn/txn.h298
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_cursor.cc368
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_cursor.h170
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_factory.h63
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_local.cc676
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_local.h566
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_remote.cc108
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_remote.h98
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/5hamsterdb/hamsterdb.cc1633
-rw-r--r--plugins/Dbx_kv/src/hamsterdb/src/5hamsterdb/hola.cc704
-rw-r--r--plugins/Dbx_kv/src/init.cpp152
-rw-r--r--plugins/Dbx_kv/src/resource.h32
-rw-r--r--plugins/Dbx_kv/src/stdafx.cpp18
-rw-r--r--plugins/Dbx_kv/src/ui.cpp340
-rw-r--r--plugins/Dbx_kv/src/version.h14
162 files changed, 0 insertions, 46546 deletions
diff --git a/plugins/Dbx_kv/Dbx_kv_10.vcxproj b/plugins/Dbx_kv/Dbx_kv_10.vcxproj
deleted file mode 100644
index d74f593b59..0000000000
--- a/plugins/Dbx_kv/Dbx_kv_10.vcxproj
+++ /dev/null
@@ -1,319 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectName>Dbx_kv</ProjectName>
- <ProjectGuid>{A9F9E806-8BA6-4C6B-B511-B979D365FF54}</ProjectGuid>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
- <IgnoreImportLibrary>true</IgnoreImportLibrary>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;_DEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level3</WarningLevel>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <StringPooling>false</StringPooling>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage\lib</AdditionalLibraryDirectories>
- <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;_DEBUG;WIN32;WIN64;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>false</StringPooling>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <Optimization>Full</Optimization>
- <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
- <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;NDEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>true</StringPooling>
- <BufferSecurityCheck>false</BufferSecurityCheck>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level3</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <Optimization>Full</Optimization>
- <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
- <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;NDEBUG;WIN32;WIN64;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>true</StringPooling>
- <BufferSecurityCheck>false</BufferSecurityCheck>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level3</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="src\dbcontacts.cpp" />
- <ClCompile Include="src\dbcrypt.cpp" />
- <ClCompile Include="src\dbevents.cpp" />
- <ClCompile Include="src\dbintf.cpp" />
- <ClCompile Include="src\dbmodulechain.cpp" />
- <ClCompile Include="src\dbsettings.cpp" />
- <ClCompile Include="src\hamsterdb\src\1base\error.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\util.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1errorinducer\errorinducer.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1globals\globals.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1mem\mem.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os_win32.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\2page\page.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_disk.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_inmem.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_check.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_erase.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_find.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_index.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_insert.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_stats.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_update.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_visit.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3changeset\changeset.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3journal\journal.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3page_manager\page_manager.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4cursor\cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\5hamsterdb\hamsterdb.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\stdafx.cpp">
- <PrecompiledHeader>Create</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\init.cpp" />
- <ClCompile Include="src\ui.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\include\m_database.h" />
- <ClInclude Include="..\..\include\m_db_int.h" />
- <ClInclude Include="src\commonheaders.h" />
- <ClInclude Include="src\dbintf.h" />
- <ClInclude Include="src\hamsterdb\config.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\version.h" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="res\dbx_kv.rc" />
- <ResourceCompile Include="res\version.rc" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/plugins/Dbx_kv/Dbx_kv_10.vcxproj.filters b/plugins/Dbx_kv/Dbx_kv_10.vcxproj.filters
deleted file mode 100644
index 6ac240c4f6..0000000000
--- a/plugins/Dbx_kv/Dbx_kv_10.vcxproj.filters
+++ /dev/null
@@ -1,182 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{60d2ae39-2690-4258-aa90-e825ef024b81}</UniqueIdentifier>
- <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
- </Filter>
- <Filter Include="Header Files">
- <UniqueIdentifier>{a2637eb4-34a4-4341-9c84-0e0ecfdc0f35}</UniqueIdentifier>
- <Extensions>h;hpp;hxx;hm;inl</Extensions>
- </Filter>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{e5e10389-c0d7-4cf8-8442-6714f0d5aff1}</UniqueIdentifier>
- <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
- </Filter>
- <Filter Include="Source Files\hamsterdb">
- <UniqueIdentifier>{74e7bd75-7fa5-4c0b-b9a1-62066a38f420}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="src\dbcontacts.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbevents.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbintf.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbmodulechain.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbsettings.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\init.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\stdafx.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbcrypt.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\ui.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\error.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\util.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1errorinducer\errorinducer.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1globals\globals.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1mem\mem.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os_win32.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\2page\page.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_disk.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_inmem.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_check.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_erase.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_find.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_index.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_insert.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_stats.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_update.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_visit.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3changeset\changeset.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3journal\journal.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3page_manager\page_manager.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4cursor\cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\5hamsterdb\hamsterdb.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="src\commonheaders.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\dbintf.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\resource.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\version.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\include\m_database.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\include\m_db_int.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\hamsterdb\config.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="res\dbx_kv.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- <ResourceCompile Include="res\version.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/plugins/Dbx_kv/Dbx_kv_12.vcxproj b/plugins/Dbx_kv/Dbx_kv_12.vcxproj
deleted file mode 100644
index 0661bd7c9c..0000000000
--- a/plugins/Dbx_kv/Dbx_kv_12.vcxproj
+++ /dev/null
@@ -1,327 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectName>Dbx_kv</ProjectName>
- <ProjectGuid>{A9F9E806-8BA6-4C6B-B511-B979D365FF54}</ProjectGuid>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v120_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v120_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v120_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v120_xp</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
- <IgnoreImportLibrary>true</IgnoreImportLibrary>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;_DEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <StringPooling>false</StringPooling>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage\lib</AdditionalLibraryDirectories>
- <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- <ProjectReference />
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;_DEBUG;WIN32;WIN64;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>false</StringPooling>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- <ProjectReference />
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <Optimization>Full</Optimization>
- <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
- <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;NDEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>true</StringPooling>
- <BufferSecurityCheck>false</BufferSecurityCheck>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- <ProjectReference />
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <Optimization>Full</Optimization>
- <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
- <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;NDEBUG;WIN32;WIN64;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>true</StringPooling>
- <BufferSecurityCheck>false</BufferSecurityCheck>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- <ProjectReference />
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="src\dbcontacts.cpp" />
- <ClCompile Include="src\dbcrypt.cpp" />
- <ClCompile Include="src\dbevents.cpp" />
- <ClCompile Include="src\dbintf.cpp" />
- <ClCompile Include="src\dbmodulechain.cpp" />
- <ClCompile Include="src\dbsettings.cpp" />
- <ClCompile Include="src\hamsterdb\src\1base\error.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\util.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1errorinducer\errorinducer.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1globals\globals.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1mem\mem.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os_win32.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\2page\page.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_disk.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_inmem.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_check.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_erase.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_find.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_index.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_insert.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_stats.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_update.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_visit.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3changeset\changeset.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3journal\journal.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3page_manager\page_manager.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4cursor\cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\5hamsterdb\hamsterdb.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\stdafx.cpp">
- <PrecompiledHeader>Create</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\init.cpp" />
- <ClCompile Include="src\ui.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\include\m_database.h" />
- <ClInclude Include="..\..\include\m_db_int.h" />
- <ClInclude Include="src\commonheaders.h" />
- <ClInclude Include="src\dbintf.h" />
- <ClInclude Include="src\hamsterdb\config.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\version.h" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="res\dbx_kv.rc" />
- <ResourceCompile Include="res\version.rc" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/plugins/Dbx_kv/Dbx_kv_12.vcxproj.filters b/plugins/Dbx_kv/Dbx_kv_12.vcxproj.filters
deleted file mode 100644
index 6ac240c4f6..0000000000
--- a/plugins/Dbx_kv/Dbx_kv_12.vcxproj.filters
+++ /dev/null
@@ -1,182 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{60d2ae39-2690-4258-aa90-e825ef024b81}</UniqueIdentifier>
- <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
- </Filter>
- <Filter Include="Header Files">
- <UniqueIdentifier>{a2637eb4-34a4-4341-9c84-0e0ecfdc0f35}</UniqueIdentifier>
- <Extensions>h;hpp;hxx;hm;inl</Extensions>
- </Filter>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{e5e10389-c0d7-4cf8-8442-6714f0d5aff1}</UniqueIdentifier>
- <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
- </Filter>
- <Filter Include="Source Files\hamsterdb">
- <UniqueIdentifier>{74e7bd75-7fa5-4c0b-b9a1-62066a38f420}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="src\dbcontacts.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbevents.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbintf.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbmodulechain.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbsettings.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\init.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\stdafx.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbcrypt.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\ui.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\error.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\util.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1errorinducer\errorinducer.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1globals\globals.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1mem\mem.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os_win32.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\2page\page.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_disk.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_inmem.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_check.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_erase.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_find.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_index.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_insert.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_stats.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_update.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_visit.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3changeset\changeset.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3journal\journal.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3page_manager\page_manager.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4cursor\cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\5hamsterdb\hamsterdb.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="src\commonheaders.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\dbintf.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\resource.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\version.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\include\m_database.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\include\m_db_int.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\hamsterdb\config.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="res\dbx_kv.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- <ResourceCompile Include="res\version.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/plugins/Dbx_kv/Dbx_kv_15.vcxproj b/plugins/Dbx_kv/Dbx_kv_15.vcxproj
deleted file mode 100644
index fbd767433d..0000000000
--- a/plugins/Dbx_kv/Dbx_kv_15.vcxproj
+++ /dev/null
@@ -1,328 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Debug|x64">
- <Configuration>Debug</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|x64">
- <Configuration>Release</Configuration>
- <Platform>x64</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectName>Dbx_kv</ProjectName>
- <ProjectGuid>{A9F9E806-8BA6-4C6B-B511-B979D365FF54}</ProjectGuid>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v141_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v141_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <WholeProgramOptimization>true</WholeProgramOptimization>
- <PlatformToolset>v141_xp</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
- <ConfigurationType>DynamicLibrary</ConfigurationType>
- <CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v141_xp</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\Obj\$(ProjectName)\</IntDir>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Plugins\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Configuration)64\Obj\$(ProjectName)\</IntDir>
- <IgnoreImportLibrary>true</IgnoreImportLibrary>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;_DEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <StringPooling>false</StringPooling>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage\lib</AdditionalLibraryDirectories>
- <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- <ProjectReference />
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;_DEBUG;WIN32;WIN64;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>false</StringPooling>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- <ProjectReference />
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <ClCompile>
- <Optimization>Full</Optimization>
- <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
- <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;NDEBUG;WIN32;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
- <StringPooling>true</StringPooling>
- <BufferSecurityCheck>false</BufferSecurityCheck>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- <ProjectReference />
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
- <ClCompile>
- <Optimization>Full</Optimization>
- <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
- <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
- <AdditionalIncludeDirectories>..\..\include;..\..\..\boost;src\hamsterdb\include;src\hamsterdb\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>HAVE_CONFIG_H;NDEBUG;WIN32;WIN64;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>true</StringPooling>
- <BufferSecurityCheck>false</BufferSecurityCheck>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <FloatingPointModel>Fast</FloatingPointModel>
- <PrecompiledHeader>Use</PrecompiledHeader>
- <PrecompiledHeaderFile>commonheaders.h</PrecompiledHeaderFile>
- <WarningLevel>Level4</WarningLevel>
- <DisableSpecificWarnings>4706</DisableSpecificWarnings>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <AdditionalIncludeDirectories>..\..\include;..\..\include\msapi</AdditionalIncludeDirectories>
- </ResourceCompile>
- <Link>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <OptimizeReferences>true</OptimizeReferences>
- <EnableCOMDATFolding>true</EnableCOMDATFolding>
- <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
- <AdditionalLibraryDirectories>$(ProfileDir)..\..\libs\win$(PlatformArchitecture);..\..\..\boost\stage64\lib</AdditionalLibraryDirectories>
- <AdditionalDependencies>Ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <SubSystem>Windows</SubSystem>
- </Link>
- <ProjectReference />
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="src\dbcontacts.cpp" />
- <ClCompile Include="src\dbcrypt.cpp" />
- <ClCompile Include="src\dbevents.cpp" />
- <ClCompile Include="src\dbintf.cpp" />
- <ClCompile Include="src\dbmodulechain.cpp" />
- <ClCompile Include="src\dbsettings.cpp" />
- <ClCompile Include="src\hamsterdb\src\1base\error.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\util.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1errorinducer\errorinducer.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1globals\globals.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1mem\mem.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os_win32.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\2page\page.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_disk.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_inmem.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_check.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_erase.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_find.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_index.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_insert.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_stats.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_update.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_visit.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3changeset\changeset.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3journal\journal.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3page_manager\page_manager.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4cursor\cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_cursor.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_local.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_remote.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\5hamsterdb\hamsterdb.cc">
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\stdafx.cpp">
- <PrecompiledHeader>Create</PrecompiledHeader>
- </ClCompile>
- <ClCompile Include="src\init.cpp" />
- <ClCompile Include="src\ui.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\include\m_database.h" />
- <ClInclude Include="..\..\include\m_db_int.h" />
- <ClInclude Include="src\commonheaders.h" />
- <ClInclude Include="src\dbintf.h" />
- <ClInclude Include="src\hamsterdb\config.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\version.h" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="res\dbx_kv.rc" />
- <ResourceCompile Include="res\version.rc" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/plugins/Dbx_kv/Dbx_kv_15.vcxproj.filters b/plugins/Dbx_kv/Dbx_kv_15.vcxproj.filters
deleted file mode 100644
index 54018b6230..0000000000
--- a/plugins/Dbx_kv/Dbx_kv_15.vcxproj.filters
+++ /dev/null
@@ -1,182 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Source Files">
- <UniqueIdentifier>{60d2ae39-2690-4258-aa90-e825ef024b81}</UniqueIdentifier>
- <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
- </Filter>
- <Filter Include="Header Files">
- <UniqueIdentifier>{a2637eb4-34a4-4341-9c84-0e0ecfdc0f35}</UniqueIdentifier>
- <Extensions>h;hpp;hxx;hm;inl</Extensions>
- </Filter>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{e5e10389-c0d7-4cf8-8442-6714f0d5aff1}</UniqueIdentifier>
- <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
- </Filter>
- <Filter Include="Source Files\hamsterdb">
- <UniqueIdentifier>{74e7bd75-7fa5-4c0b-b9a1-62066a38f420}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="src\dbcontacts.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbevents.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbintf.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbmodulechain.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbsettings.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\init.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\stdafx.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\dbcrypt.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\ui.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\error.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1base\util.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1errorinducer\errorinducer.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1globals\globals.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1mem\mem.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\1os\os_win32.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\2page\page.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_disk.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3blob_manager\blob_manager_inmem.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_check.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_erase.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_find.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_index.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_insert.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_stats.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_update.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3btree\btree_visit.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3changeset\changeset.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3journal\journal.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\3page_manager\page_manager.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4cursor\cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4db\db_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4env\env.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_cursor.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_local.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\4txn\txn_remote.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- <ClCompile Include="src\hamsterdb\src\5hamsterdb\hamsterdb.cc">
- <Filter>Source Files\hamsterdb</Filter>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="src\commonheaders.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\dbintf.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\resource.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\version.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\include\m_database.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="..\..\include\m_db_int.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\hamsterdb\config.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="res\dbx_kv.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- <ResourceCompile Include="res\version.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/plugins/Dbx_kv/res/dbx_kv.rc b/plugins/Dbx_kv/res/dbx_kv.rc
deleted file mode 100644
index 3f12bcfe98..0000000000
--- a/plugins/Dbx_kv/res/dbx_kv.rc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "..\src\resource.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#include <winres.h>
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// English (United States) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Dialog
-//
-
-IDD_LOGIN DIALOGEX 0, 0, 190, 86
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
-CAPTION "Login to Miranda NG"
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- CONTROL "",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,190,26
- CTEXT "",IDC_LANG,158,34,13,13,SS_CENTERIMAGE | NOT WS_GROUP
- EDITTEXT IDC_USERPASS,21,34,128,14,ES_PASSWORD | ES_AUTOHSCROLL | WS_GROUP
- DEFPUSHBUTTON "OK",IDOK,36,64,50,14
- PUSHBUTTON "Cancel",IDCANCEL,102,64,50,14
- CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,0,55,190,1
-END
-
-IDD_NEWPASS DIALOGEX 0, 0, 190, 102
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
-CAPTION "New password"
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- CONTROL "Please enter your new password",IDC_HEADERBAR,
- "MHeaderbarCtrl",0x0,0,0,190,26
- CTEXT "",IDC_LANG,158,34,13,13,SS_CENTERIMAGE | NOT WS_GROUP
- EDITTEXT IDC_USERPASS1,21,34,128,14,ES_PASSWORD | ES_AUTOHSCROLL
- EDITTEXT IDC_USERPASS2,21,54,128,14,ES_PASSWORD | ES_AUTOHSCROLL
- DEFPUSHBUTTON "OK",IDOK,36,84,50,14
- PUSHBUTTON "Cancel",IDCANCEL,100,84,50,14
- CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,0,77,190,1
-END
-
-IDD_CHANGEPASS DIALOGEX 0, 0, 190, 148
-STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-EXSTYLE WS_EX_TOOLWINDOW
-CAPTION "Enter password"
-FONT 8, "MS Shell Dlg", 400, 0, 0x1
-BEGIN
- CONTROL "Change password",IDC_HEADERBAR,"MHeaderbarCtrl",0x0,0,0,190,26
- CTEXT "",IDC_LANG,158,42,13,13,SS_CENTERIMAGE | NOT WS_GROUP
- EDITTEXT IDC_OLDPASS,21,42,128,14,ES_PASSWORD | ES_AUTOHSCROLL
- EDITTEXT IDC_USERPASS1,21,77,128,14,ES_PASSWORD | ES_AUTOHSCROLL
- EDITTEXT IDC_USERPASS2,21,98,128,14,ES_PASSWORD | ES_AUTOHSCROLL
- DEFPUSHBUTTON "Change",IDOK,11,127,50,14
- PUSHBUTTON "Remove",IDREMOVE,69,127,50,14
- PUSHBUTTON "Cancel",IDCANCEL,126,127,50,14
- LTEXT "New password",IDC_STATIC,11,66,163,10,0,WS_EX_TRANSPARENT
- CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,0,119,190,1
- LTEXT "Old password",IDC_STATIC,11,31,140,10,0,WS_EX_TRANSPARENT
-END
-
-IDD_OPTIONS DIALOGEX 0, 0, 318, 176
-STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
-EXSTYLE WS_EX_CONTROLPARENT
-FONT 8, "MS Shell Dlg", 0, 0, 0x1
-BEGIN
- GROUPBOX "Database encryption mode",IDC_STATIC,6,22,305,125
- CONTROL "Standard",IDC_STANDARD,"Button",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,12,38,292,12
- CONTROL "Total",IDC_TOTAL,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,12,95,292,12
- LTEXT "Only critical data are encrypted (passwords, security tokens, etc). All other settings and history remains unencrypted. Fast and effective, suitable for the most cases",IDC_STATIC,22,54,284,37
- LTEXT "All string settings and all events in histories are encrypted. It also makes Miranda much slower and creates a risk of losing everything you've stored in a profile in case of losing password. Recommended only for paranoid users",IDC_STATIC,22,110,284,33
- PUSHBUTTON "Set password",IDC_USERPASS,200,153,111,17
-END
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Icon
-//
-
-// Icon with lowest ID value placed first to ensure application icon
-// remains consistent on all systems.
-IDI_LOGO ICON "logo.ico"
-IDI_ICONPASS ICON "pass.ico"
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// DESIGNINFO
-//
-
-#ifdef APSTUDIO_INVOKED
-GUIDELINES DESIGNINFO
-BEGIN
- IDD_LOGIN, DIALOG
- BEGIN
- END
-
- IDD_CHANGEPASS, DIALOG
- BEGIN
- END
-
- IDD_OPTIONS, DIALOG
- BEGIN
- END
-END
-#endif // APSTUDIO_INVOKED
-
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE
-BEGIN
- "..\\src\\resource.h\0"
-END
-
-2 TEXTINCLUDE
-BEGIN
- "#include <winres.h>\0"
-END
-
-3 TEXTINCLUDE
-BEGIN
- "\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-#endif // English (United States) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/plugins/Dbx_kv/res/logo.ico b/plugins/Dbx_kv/res/logo.ico
deleted file mode 100644
index f49bbe83d6..0000000000
--- a/plugins/Dbx_kv/res/logo.ico
+++ /dev/null
Binary files differ
diff --git a/plugins/Dbx_kv/res/pass.ico b/plugins/Dbx_kv/res/pass.ico
deleted file mode 100644
index dc47a6ed4f..0000000000
--- a/plugins/Dbx_kv/res/pass.ico
+++ /dev/null
Binary files differ
diff --git a/plugins/Dbx_kv/res/version.rc b/plugins/Dbx_kv/res/version.rc
deleted file mode 100644
index 5bfbab4754..0000000000
--- a/plugins/Dbx_kv/res/version.rc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#ifdef APSTUDIO_INVOKED
-#error this file is not editable by Microsoft Visual C++
-#endif //APSTUDIO_INVOKED
-
-#include "afxres.h"
-#include "..\src\version.h"
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION __FILEVERSION_STRING
- PRODUCTVERSION __FILEVERSION_STRING
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x0L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "000004b0"
- BEGIN
- VALUE "FileDescription", __DESCRIPTION
- VALUE "InternalName", __PLUGIN_NAME
- VALUE "LegalCopyright", __COPYRIGHT
- VALUE "OriginalFilename", __FILENAME
- VALUE "ProductName", __PLUGIN_NAME
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x0, 1200
- END
-END
diff --git a/plugins/Dbx_kv/src/commonheaders.h b/plugins/Dbx_kv/src/commonheaders.h
deleted file mode 100644
index ee0dbaeb19..0000000000
--- a/plugins/Dbx_kv/src/commonheaders.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#define _CRT_SECURE_NO_WARNINGS
-#define _WIN32_WINNT 0x0501
-
-#pragma warning(disable:4509)
-
-#include <windows.h>
-#include <time.h>
-#include <process.h>
-#include <memory>
-
-#include <newpluginapi.h>
-#include <win2k.h>
-#include <m_system_cpp.h>
-#include <m_database.h>
-#include <m_langpack.h>
-#include <m_clist.h>
-#include <m_icolib.h>
-#include <m_options.h>
-#include <m_crypto.h>
-#include <m_metacontacts.h>
-#include <m_protocols.h>
-#include <m_netlib.h>
-
-#include "ham/hamsterdb.h"
-
-#include "dbintf.h"
-#include "resource.h"
-#include "version.h"
-
-class cursor_ptr
-{
- ham_cursor_t *m_cursor;
-
-public:
- __forceinline cursor_ptr(ham_db_t *_dbi)
- {
- if (ham_cursor_create(&m_cursor, _dbi, NULL, 0) != HAM_SUCCESS)
- m_cursor = NULL;
- }
-
- __forceinline ~cursor_ptr()
- {
- if (m_cursor)
- ham_cursor_close(m_cursor);
- }
-
- __forceinline operator ham_cursor_t*() const { return m_cursor; }
-};
-
-extern HINSTANCE g_hInst;
-extern LIST<CDbxKV> g_Dbs;
-
-#ifdef __GNUC__
-#define mir_i64(x) (x##LL)
-#else
-#define mir_i64(x) (x##i64)
-#endif
diff --git a/plugins/Dbx_kv/src/dbcontacts.cpp b/plugins/Dbx_kv/src/dbcontacts.cpp
deleted file mode 100644
index a2d666fe60..0000000000
--- a/plugins/Dbx_kv/src/dbcontacts.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "commonheaders.h"
-
-int CDbxKV::CheckProto(DBCachedContact *cc, const char *proto)
-{
- if (cc->szProto == NULL) {
- char protobuf[MAX_PATH] = { 0 };
- DBVARIANT dbv;
- dbv.type = DBVT_ASCIIZ;
- dbv.pszVal = protobuf;
- dbv.cchVal = sizeof(protobuf);
- if (GetContactSettingStatic(cc->contactID, "Protocol", "p", &dbv) != 0 || (dbv.type != DBVT_ASCIIZ))
- return 0;
-
- cc->szProto = m_cache->GetCachedSetting(NULL, protobuf, 0, (int)strlen(protobuf));
- }
-
- return !strcmp(cc->szProto, proto);
-}
-
-STDMETHODIMP_(LONG) CDbxKV::GetContactCount(void)
-{
- mir_cslock lck(m_csDbAccess);
- return m_contactCount;
-}
-
-STDMETHODIMP_(LONG) CDbxKV::GetContactSize(void)
-{
- return sizeof(DBCachedContact);
-}
-
-STDMETHODIMP_(MCONTACT) CDbxKV::FindFirstContact(const char *szProto)
-{
- mir_cslock lck(m_csDbAccess);
- DBCachedContact *cc = m_cache->GetFirstContact();
- if (cc == NULL)
- return NULL;
-
- if (cc->contactID == 0)
- if ((cc = m_cache->GetNextContact(0)) == NULL)
- return NULL;
-
- if (!szProto || CheckProto(cc, szProto))
- return cc->contactID;
-
- return FindNextContact(cc->contactID, szProto);
-}
-
-STDMETHODIMP_(MCONTACT) CDbxKV::FindNextContact(MCONTACT contactID, const char *szProto)
-{
- mir_cslock lck(m_csDbAccess);
- while (contactID) {
- DBCachedContact *cc = m_cache->GetNextContact(contactID);
- if (cc == NULL)
- break;
-
- if (!szProto || CheckProto(cc, szProto))
- return cc->contactID;
-
- contactID = cc->contactID;
- }
-
- return NULL;
-}
-
-STDMETHODIMP_(LONG) CDbxKV::DeleteContact(MCONTACT contactID)
-{
- if (contactID == 0) // global contact cannot be removed
- return 1;
-
- // call notifier while outside mutex
- NotifyEventHooks(hContactDeletedEvent, contactID, 0);
-
- // delete
- mir_cslock lck(m_csDbAccess);
-
- ham_key_t key = { sizeof(MCONTACT), &contactID };
- ham_db_erase(m_dbContacts, NULL, &key, 0);
- return 0;
-}
-
-STDMETHODIMP_(MCONTACT) CDbxKV::AddContact()
-{
- DWORD dwContactId;
- {
- mir_cslock lck(m_csDbAccess);
- dwContactId = m_dwMaxContactId++;
-
- DBCachedContact *cc = m_cache->AddContactToCache(dwContactId);
- cc->dbc.dwSignature = DBCONTACT_SIGNATURE;
-
- ham_key_t key = { sizeof(MCONTACT), &dwContactId };
- ham_record_t data = { sizeof(cc->dbc), &cc->dbc };
- ham_db_insert(m_dbContacts, NULL, &key, &data, HAM_OVERWRITE);
- }
-
- NotifyEventHooks(hContactAddedEvent, dwContactId, 0);
- return dwContactId;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::IsDbContact(MCONTACT contactID)
-{
- DBCachedContact *cc = m_cache->GetCachedContact(contactID);
- return (cc != NULL);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// metacontacts support
-
-BOOL CDbxKV::MetaDetouchSub(DBCachedContact *cc, int nSub)
-{
- CallService(MS_DB_MODULE_DELETE, cc->pSubs[nSub], (LPARAM)META_PROTO);
- return 0;
-}
-
-BOOL CDbxKV::MetaSetDefault(DBCachedContact *cc)
-{
- return db_set_dw(cc->contactID, META_PROTO, "Default", cc->nDefault);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-BOOL CDbxKV::MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub)
-{
- DBEventSortingKey keyVal = { ccSub->contactID, 0, 0 }, insVal = { ccMeta->contactID, 0, 0 };
- ham_key_t key = { sizeof(keyVal), &keyVal }, key2 = { sizeof(insVal), &insVal };
- ham_record_t data = { 0 };
-
- cursor_ptr cursor(m_dbEventsSort);
- if (ham_cursor_find(cursor, &key, &data, HAM_FIND_GT_MATCH) != HAM_SUCCESS)
- return 0;
-
- do {
- DBEventSortingKey *pKey = (DBEventSortingKey*)key.data;
- if (pKey->dwContactId != ccSub->contactID)
- break;
-
- insVal.ts = pKey->ts;
- insVal.dwEventId = pKey->dwEventId;
- ham_db_insert(m_dbEventsSort, NULL, &key2, &data, HAM_OVERWRITE);
-
- ccMeta->dbc.dwEventCount++;
- } while (ham_cursor_move(cursor, &key, &data, HAM_CURSOR_NEXT) == HAM_SUCCESS);
-
- // now update the number of events in a metacontact
- ham_key_t keyc = { sizeof(int), &ccMeta->contactID };
- ham_record_t datac = { sizeof(ccMeta->dbc), &ccMeta->dbc };
- ham_db_insert(m_dbContacts, NULL, &keyc, &datac, HAM_OVERWRITE);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-BOOL CDbxKV::MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub)
-{
- DBEventSortingKey keyVal = { ccSub->contactID, 0, 0 }, delVal = { ccMeta->contactID, 0, 0 };
- ham_key_t key = { sizeof(keyVal), &keyVal }, key2 = { sizeof(delVal), &delVal };
- ham_record_t data = { 0 };
-
- cursor_ptr cursor(m_dbEventsSort);
- if (ham_cursor_find(cursor, &key, &data, HAM_FIND_GT_MATCH) != HAM_SUCCESS)
- return 0;
-
- do {
- DBEventSortingKey *pKey = (DBEventSortingKey*)key.data;
- if (pKey->dwContactId != ccSub->contactID)
- break;
-
- delVal.ts = pKey->ts;
- delVal.dwEventId = pKey->dwEventId;
- ham_db_erase(m_dbEventsSort, NULL, &key2, 0);
-
- ccMeta->dbc.dwEventCount--;
- } while (ham_cursor_move(cursor, &key, &data, HAM_CURSOR_NEXT) == HAM_SUCCESS);
-
- // now update the number of events in a metacontact
- ham_key_t keyc = { sizeof(int), &ccMeta->contactID };
- ham_record_t datac = { sizeof(ccMeta->dbc), &ccMeta->dbc };
- ham_db_insert(m_dbContacts, NULL, &keyc, &datac, HAM_OVERWRITE);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void DBCachedContact::Advance(DWORD id, DBEvent &dbe)
-{
- dbc.dwEventCount++;
-
- if (dbe.flags & (DBEF_READ | DBEF_SENT))
- return;
-
- if (dbe.timestamp < dbc.tsFirstUnread || dbc.tsFirstUnread == 0) {
- dbc.tsFirstUnread = dbe.timestamp;
- dbc.dwFirstUnread = id;
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// initial cycle to fill the contacts' cache
-
-void CDbxKV::FillContacts()
-{
- m_contactCount = 0;
-
- ham_key_t key = { 0 };
- ham_record_t rec = { 0 };
- cursor_ptr cursor(m_dbContacts);
- if (ham_cursor_move(cursor, &key, &rec, HAM_CURSOR_FIRST) != HAM_SUCCESS) // empty table?
- return;
-
- do {
- DBContact *dbc = (DBContact*)rec.data;
- if (dbc->dwSignature != DBCONTACT_SIGNATURE)
- DatabaseCorruption(NULL);
-
- DBCachedContact *cc = m_cache->AddContactToCache(*(DWORD*)key.data);
- cc->dbc.dwSignature = DBCONTACT_SIGNATURE;
- cc->dbc.dwEventCount = dbc->dwEventCount;
- cc->dbc.dwFirstUnread = dbc->dwFirstUnread;
- cc->dbc.tsFirstUnread = dbc->tsFirstUnread;
-
- CheckProto(cc, "");
-
- m_dwMaxContactId = cc->contactID+1;
- m_contactCount++;
-
- DBVARIANT dbv; dbv.type = DBVT_DWORD;
- cc->nSubs = (0 != GetContactSetting(cc->contactID, META_PROTO, "NumContacts", &dbv)) ? -1 : dbv.dVal;
- if (cc->nSubs != -1) {
- cc->pSubs = (MCONTACT*)mir_alloc(cc->nSubs*sizeof(MCONTACT));
- for (int i = 0; i < cc->nSubs; i++) {
- char setting[100];
- mir_snprintf(setting, SIZEOF(setting), "Handle%d", i);
- cc->pSubs[i] = (0 != GetContactSetting(cc->contactID, META_PROTO, setting, &dbv)) ? NULL : dbv.dVal;
- }
- }
- cc->nDefault = (0 != GetContactSetting(cc->contactID, META_PROTO, "Default", &dbv)) ? -1 : dbv.dVal;
- cc->parentID = (0 != GetContactSetting(cc->contactID, META_PROTO, "ParentMeta", &dbv)) ? NULL : dbv.dVal;
- } while (ham_cursor_move(cursor, &key, &rec, HAM_CURSOR_NEXT) == HAM_SUCCESS);
-}
diff --git a/plugins/Dbx_kv/src/dbcrypt.cpp b/plugins/Dbx_kv/src/dbcrypt.cpp
deleted file mode 100644
index dc4f57703c..0000000000
--- a/plugins/Dbx_kv/src/dbcrypt.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "commonheaders.h"
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-//VERY VERY VERY BASIC ENCRYPTION FUNCTION
-
-static void Encrypt(char *msg, BOOL up)
-{
- int jump = (up) ? 5 : -5;
- for (int i = 0; msg[i]; i++)
- msg[i] = msg[i] + jump;
-}
-
-__forceinline void DecodeString(LPSTR buf)
-{
- Encrypt(buf, FALSE);
-}
-
-struct VarDescr
-{
- VarDescr(LPCSTR var, LPCSTR value) :
- szVar(mir_strdup(var)),
- szValue(mir_strdup(value))
- {}
-
- VarDescr(LPCSTR var, LPSTR value) :
- szVar(mir_strdup(var)),
- szValue(value)
- {}
-
- VarDescr(LPCSTR var, PBYTE value, int len) :
- szVar(mir_strdup(var)),
- szValue((char*)memcpy(mir_alloc(len), value, len)),
- iLen(len)
- {}
-
- ptrA szVar, szValue;
- int iLen;
-};
-
-struct SettingUgraderParam
-{
- CDbxKV *db;
- LPCSTR szModule;
- MCONTACT contactID;
- OBJLIST<VarDescr>* pList;
-};
-
-int sttSettingUgrader(const char *szSetting, LPARAM lParam)
-{
- SettingUgraderParam *param = (SettingUgraderParam*)lParam;
- if (param->db->IsSettingEncrypted(param->szModule, szSetting)) {
- DBVARIANT dbv = { DBVT_UTF8 };
- if (!param->db->GetContactSettingStr(param->contactID, param->szModule, szSetting, &dbv)) {
- if (dbv.type == DBVT_UTF8) {
- DecodeString(dbv.pszVal);
- param->pList->insert(new VarDescr(szSetting, (LPCSTR)dbv.pszVal));
- }
- param->db->FreeVariant(&dbv);
- }
- }
- return 0;
-}
-
-void sttContactEnum(MCONTACT contactID, const char *szModule, CDbxKV *db)
-{
- OBJLIST<VarDescr> arSettings(1);
- SettingUgraderParam param = { db, szModule, contactID, &arSettings };
-
- DBCONTACTENUMSETTINGS dbces = { 0 };
- dbces.pfnEnumProc = sttSettingUgrader;
- dbces.szModule = szModule;
- dbces.lParam = (LPARAM)&param;
- db->EnumContactSettings(NULL, &dbces);
-
- for (int i = 0; i < arSettings.getCount(); i++) {
- VarDescr &p = arSettings[i];
-
- size_t len;
- BYTE *pResult = db->m_crypto->encodeString(p.szValue, &len);
- if (pResult != NULL) {
- DBCONTACTWRITESETTING dbcws = { szModule, p.szVar };
- dbcws.value.type = DBVT_ENCRYPTED;
- dbcws.value.pbVal = pResult;
- dbcws.value.cpbVal = (WORD)len;
- db->WriteContactSetting(contactID, &dbcws);
-
- mir_free(pResult);
- }
- }
-}
-
-int sttModuleEnum(const char *szModule, DWORD, LPARAM lParam)
-{
- CDbxKV *db = (CDbxKV*)lParam;
- sttContactEnum(NULL, szModule, db);
-
- for (MCONTACT contactID = db->FindFirstContact(); contactID; contactID = db->FindNextContact(contactID))
- sttContactEnum(contactID, szModule, db);
-
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-int CDbxKV::InitCrypt()
-{
- CRYPTO_PROVIDER *pProvider;
- bool bMissingKey = false;
-
- DBVARIANT dbv = { 0 };
- dbv.type = DBVT_BLOB;
- if (GetContactSetting(NULL, "CryptoEngine", "Provider", &dbv)) {
- LBL_CreateProvider:
- CRYPTO_PROVIDER **ppProvs;
- int iNumProvs;
- Crypto_EnumProviders(&iNumProvs, &ppProvs);
- if (iNumProvs == 0)
- return 1;
-
- pProvider = ppProvs[0]; //!!!!!!!!!!!!!!!!!!
-
- DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "Provider" };
- dbcws.value.type = DBVT_BLOB;
- dbcws.value.pbVal = (PBYTE)pProvider->pszName;
- dbcws.value.cpbVal = (int)strlen(pProvider->pszName) + 1;
- WriteContactSetting(NULL, &dbcws);
- }
- else {
- if (dbv.type != DBVT_BLOB) { // old version, clean it up
- bMissingKey = true;
- goto LBL_CreateProvider;
- }
-
- pProvider = Crypto_GetProvider(LPCSTR(dbv.pbVal));
- FreeVariant(&dbv);
- if (pProvider == NULL)
- goto LBL_CreateProvider;
- }
-
- if ((m_crypto = pProvider->pFactory()) == NULL)
- return 3;
-
- dbv.type = DBVT_BLOB;
- if (GetContactSetting(NULL, "CryptoEngine", "StoredKey", &dbv)) {
- bMissingKey = true;
-
- LBL_SetNewKey:
- m_crypto->generateKey(); // unencrypted key
- StoreKey();
- }
- else {
- size_t iKeyLength = m_crypto->getKeyLength();
- if (dbv.cpbVal != (WORD)iKeyLength)
- goto LBL_SetNewKey;
-
- if (!m_crypto->setKey(dbv.pbVal, iKeyLength))
- if (!EnterPassword(dbv.pbVal, iKeyLength)) // password protected?
- return 4;
-
- FreeVariant(&dbv);
- }
-
- if (bMissingKey)
- EnumModuleNames(sttModuleEnum, this);
-
- dbv.type = DBVT_BYTE;
- if (!GetContactSetting(NULL, "CryptoEngine", "DatabaseEncryption", &dbv))
- m_bEncrypted = dbv.bVal != 0;
-
- InitDialogs();
- return 0;
-}
-
-void CDbxKV::StoreKey()
-{
- size_t iKeyLength = m_crypto->getKeyLength();
- BYTE *pKey = (BYTE*)_alloca(iKeyLength);
- m_crypto->getKey(pKey, iKeyLength);
-
- DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "StoredKey" };
- dbcws.value.type = DBVT_BLOB;
- dbcws.value.cpbVal = (WORD)iKeyLength;
- dbcws.value.pbVal = pKey;
- WriteContactSetting(NULL, &dbcws);
-
- SecureZeroMemory(pKey, iKeyLength);
-}
-
-void CDbxKV::SetPassword(LPCTSTR ptszPassword)
-{
- if (ptszPassword == NULL || *ptszPassword == 0) {
- m_bUsesPassword = false;
- m_crypto->setPassword(NULL);
- }
- else {
- m_bUsesPassword = true;
- m_crypto->setPassword(ptrA(mir_utf8encodeT(ptszPassword)));
- }
- UpdateMenuItem();
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CDbxKV::ToggleEncryption()
-{
- HANDLE hSave1 = hSettingChangeEvent; hSettingChangeEvent = NULL;
- HANDLE hSave2 = hEventAddedEvent; hEventAddedEvent = NULL;
- HANDLE hSave3 = hEventDeletedEvent; hEventDeletedEvent = NULL;
- HANDLE hSave4 = hEventFilterAddedEvent; hEventFilterAddedEvent = NULL;
-
- mir_cslock lck(m_csDbAccess);
- ToggleSettingsEncryption(NULL);
- ToggleEventsEncryption(NULL);
-
- for (MCONTACT contactID = FindFirstContact(); contactID; contactID = FindNextContact(contactID)) {
- ToggleSettingsEncryption(contactID);
- ToggleEventsEncryption(contactID);
- }
-
- m_bEncrypted = !m_bEncrypted;
-
- DBCONTACTWRITESETTING dbcws = { "CryptoEngine", "DatabaseEncryption" };
- dbcws.value.type = DBVT_BYTE;
- dbcws.value.bVal = m_bEncrypted;
- WriteContactSetting(NULL, &dbcws);
-
- hSettingChangeEvent = hSave1;
- hEventAddedEvent = hSave2;
- hEventDeletedEvent = hSave3;
- hEventFilterAddedEvent = hSave4;
-}
-
-void CDbxKV::ToggleSettingsEncryption(MCONTACT contactID)
-{
-}
-
-void CDbxKV::ToggleEventsEncryption(MCONTACT contactID)
-{
-}
diff --git a/plugins/Dbx_kv/src/dbevents.cpp b/plugins/Dbx_kv/src/dbevents.cpp
deleted file mode 100644
index e545bcc4b4..0000000000
--- a/plugins/Dbx_kv/src/dbevents.cpp
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "commonheaders.h"
-
-STDMETHODIMP_(LONG) CDbxKV::GetEventCount(MCONTACT contactID)
-{
- DBCachedContact *cc = m_cache->GetCachedContact(contactID);
- return (cc == NULL) ? 0 : cc->dbc.dwEventCount;
-}
-
-STDMETHODIMP_(MEVENT) CDbxKV::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei)
-{
- if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 0;
- if (dbei->timestamp == 0) return 0;
-
- DBEvent dbe;
- dbe.dwSignature = DBEVENT_SIGNATURE;
- dbe.contactID = contactID; // store native or subcontact's id
- dbe.ofsModuleName = GetModuleNameOfs(dbei->szModule);
- dbe.timestamp = dbei->timestamp;
- dbe.flags = dbei->flags;
- dbe.wEventType = dbei->eventType;
- dbe.cbBlob = dbei->cbBlob;
- BYTE *pBlob = dbei->pBlob;
-
- MCONTACT contactNotifyID = contactID;
- DBCachedContact *cc, *ccSub = NULL;
- if ((cc = m_cache->GetCachedContact(contactID)) == NULL)
- return 0;
-
- if (cc->IsSub()) {
- ccSub = cc;
- if ((cc = m_cache->GetCachedContact(cc->parentID)) == NULL)
- return 0;
-
- // set default sub to the event's source
- if (!(dbei->flags & DBEF_SENT))
- db_mc_setDefault(cc->contactID, contactID, false);
- contactID = cc->contactID; // and add an event to a metahistory
- if (db_mc_isEnabled())
- contactNotifyID = contactID;
- }
-
- if (m_safetyMode)
- if (NotifyEventHooks(hEventFilterAddedEvent, contactNotifyID, (LPARAM)dbei))
- return NULL;
-
- mir_ptr<BYTE> pCryptBlob;
- if (m_bEncrypted) {
- size_t len;
- BYTE *pResult = m_crypto->encodeBuffer(pBlob, dbe.cbBlob, &len);
- if (pResult != NULL) {
- pCryptBlob = pBlob = pResult;
- dbe.cbBlob = (DWORD)len;
- dbe.flags |= DBEF_ENCRYPTED;
- }
- }
-
- DWORD dwEventId = ++m_dwMaxEventId;
-
- BYTE *pDest = (BYTE*)_alloca(sizeof(DBEvent) + dbe.cbBlob);
- memcpy(pDest, &dbe, sizeof(DBEvent));
- memcpy(pDest + sizeof(DBEvent), pBlob, dbe.cbBlob);
-
- ham_key_t key = { sizeof(int), &dwEventId };
- ham_record_t rec = { sizeof(DBEvent) + dbe.cbBlob, pDest };
- ham_db_insert(m_dbEvents, NULL, &key, &rec, HAM_OVERWRITE);
-
- // add a sorting key
- DBEventSortingKey key2 = { contactID, dbe.timestamp, dwEventId };
- key.size = sizeof(key2); key.data = &key2;
- rec.size = 1; rec.data = "";
- ham_db_insert(m_dbEventsSort, NULL, &key, &rec, HAM_OVERWRITE);
-
- cc->Advance(dwEventId, dbe);
- ham_key_t keyc = { sizeof(int), &contactID };
- ham_record_t datac = { sizeof(DBContact), &cc->dbc };
- ham_db_insert(m_dbContacts, NULL, &keyc, &datac, HAM_OVERWRITE);
-
- // insert an event into a sub's history too
- if (ccSub != NULL) {
- key2.dwContactId = ccSub->contactID;
- ham_db_insert(m_dbEventsSort, NULL, &key, &rec, HAM_OVERWRITE);
-
- ccSub->Advance(dwEventId, dbe);
- datac.data = &ccSub->dbc;
- keyc.data = &ccSub->contactID;
- ham_db_insert(m_dbContacts, NULL, &keyc, &datac, HAM_OVERWRITE);
- }
-
- // Notify only in safe mode or on really new events
- if (m_safetyMode)
- NotifyEventHooks(hEventAddedEvent, contactNotifyID, dwEventId);
-
- return dwEventId;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::DeleteEvent(MCONTACT contactID, MEVENT hDbEvent)
-{
- if (hDbEvent == 0) return INVALID_CONTACT_ID;
-
- DBCachedContact *cc = m_cache->GetCachedContact(contactID);
- if (cc == NULL || cc->dbc.dwEventCount == 0)
- return 1;
-
- ham_key_t key = { sizeof(MEVENT), &hDbEvent };
- ham_record_t rec = { 0 };
- if (ham_db_find(m_dbEvents, NULL, &key, &rec, HAM_FIND_EXACT_MATCH) != HAM_SUCCESS)
- return 1;
-
- DBEvent *dbe = (DBEvent*)rec.data;
- DWORD dwSavedContact = dbe->contactID;
- DBEventSortingKey key2 = { contactID, dbe->timestamp, hDbEvent };
- ham_db_erase(m_dbEvents, NULL, &key, 0);
-
- // remove a sorting key
- key.size = sizeof(key2); key.data = &key2;
- ham_db_erase(m_dbEventsSort, NULL, &key, 0);
-
- // remove a sub's history entry too
- if (contactID != dwSavedContact) {
- key2.dwContactId = dwSavedContact;
- ham_db_erase(m_dbEventsSort, NULL, &key, 0);
- }
-
- // update a contact
- key.size = sizeof(int); key.data = &contactID;
- cc->dbc.dwEventCount--;
- if (cc->dbc.dwFirstUnread == hDbEvent)
- FindNextUnread(cc, key2);
-
- // call notifier while outside mutex
- NotifyEventHooks(hEventDeletedEvent, contactID, hDbEvent);
- return 0;
-}
-
-STDMETHODIMP_(LONG) CDbxKV::GetBlobSize(MEVENT hDbEvent)
-{
- ham_key_t key = { sizeof(MEVENT), &hDbEvent };
- ham_record_t rec = { 0 };
- if (ham_db_find(m_dbEvents, NULL, &key, &rec, HAM_FIND_EXACT_MATCH) != HAM_SUCCESS)
- return -1;
-
- DBEvent *dbe = (DBEvent*)rec.data;
- return (dbe->dwSignature == DBEVENT_SIGNATURE) ? dbe->cbBlob : 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbei)
-{
- if (hDbEvent == 0 || dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 1;
- if (dbei->cbBlob > 0 && dbei->pBlob == NULL) {
- dbei->cbBlob = 0;
- return 1;
- }
-
- ham_record_t rec = { 0 };
- ham_key_t key = { sizeof(MEVENT), &hDbEvent };
- if (ham_db_find(m_dbEvents, NULL, &key, &rec, HAM_FIND_EXACT_MATCH) != HAM_SUCCESS)
- return 1;
-
- DBEvent *dbe = (DBEvent*)rec.data;
- if (dbe->dwSignature != DBEVENT_SIGNATURE)
- return 1;
-
- dbei->szModule = GetModuleNameByOfs(dbe->ofsModuleName);
- dbei->timestamp = dbe->timestamp;
- dbei->flags = dbe->flags;
- dbei->eventType = dbe->wEventType;
- int bytesToCopy = (dbei->cbBlob < dbe->cbBlob) ? dbei->cbBlob : dbe->cbBlob;
- dbei->cbBlob = dbe->cbBlob;
- if (bytesToCopy && dbei->pBlob) {
- BYTE *pSrc = (BYTE*)rec.data + sizeof(DBEvent);
- if (dbe->flags & DBEF_ENCRYPTED) {
- dbei->flags &= ~DBEF_ENCRYPTED;
- size_t len;
- BYTE* pBlob = (BYTE*)m_crypto->decodeBuffer(pSrc, dbe->cbBlob, &len);
- if (pBlob == NULL)
- return 1;
-
- memcpy(dbei->pBlob, pBlob, bytesToCopy);
- if (bytesToCopy > (int)len)
- memset(dbei->pBlob + len, 0, bytesToCopy - len);
- mir_free(pBlob);
- }
- else memcpy(dbei->pBlob, pSrc, bytesToCopy);
- }
- return 0;
-}
-
-void CDbxKV::FindNextUnread(DBCachedContact *cc, DBEventSortingKey &key2)
-{
- ham_record_t rec = { 0 };
- ham_key_t key = { sizeof(key2), &key2 };
- key2.dwEventId++;
-
- cursor_ptr cursor(m_dbEventsSort);
- if (ham_cursor_find(cursor, &key, &rec, HAM_FIND_GEQ_MATCH) != HAM_SUCCESS)
- return;
-
- do {
- DBEvent *dbe = (DBEvent*)rec.data;
- if (!dbe->markedRead()) {
- cc->dbc.dwFirstUnread = key2.dwEventId;
- cc->dbc.tsFirstUnread = key2.ts;
- return;
- }
- } while (ham_cursor_move(cursor, &key, &rec, HAM_CURSOR_NEXT) == 0);
-
- cc->dbc.dwFirstUnread = cc->dbc.tsFirstUnread = 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::MarkEventRead(MCONTACT contactID, MEVENT hDbEvent)
-{
- if (hDbEvent == 0) return -1;
-
- DBCachedContact *cc = m_cache->GetCachedContact(contactID);
- if (cc == NULL)
- return -1;
-
- ham_record_t rec = { 0 };
- ham_key_t key = { sizeof(MEVENT), &hDbEvent };
- if (ham_db_find(m_dbEvents, NULL, &key, &rec, HAM_FIND_EXACT_MATCH) != HAM_SUCCESS)
- return -1;
-
- DBEvent *dbe = (DBEvent*)rec.data;
- if (dbe->dwSignature != DBEVENT_SIGNATURE)
- return -1;
-
- if (dbe->markedRead())
- return dbe->flags;
-
- DBEventSortingKey key2 = { contactID, dbe->timestamp, hDbEvent };
-
- dbe->flags |= DBEF_READ;
- ham_db_insert(m_dbEvents, NULL, &key, &rec, HAM_OVERWRITE);
-
- FindNextUnread(cc, key2);
- key.data = &contactID;
- rec.data = &cc->dbc; rec.size = sizeof(cc->dbc);
- ham_db_insert(m_dbContacts, NULL, &key, &rec, HAM_OVERWRITE);
-
- NotifyEventHooks(hEventMarkedRead, contactID, (LPARAM)hDbEvent);
- return dbe->flags;
-}
-
-STDMETHODIMP_(MCONTACT) CDbxKV::GetEventContact(MEVENT hDbEvent)
-{
- if (hDbEvent == 0) return INVALID_CONTACT_ID;
-
- ham_record_t rec = { 0 };
- ham_key_t key = { sizeof(MEVENT), &hDbEvent };
- if (ham_db_find(m_dbEvents, NULL, &key, &rec, HAM_FIND_EXACT_MATCH) != HAM_SUCCESS)
- return INVALID_CONTACT_ID;
-
- DBEvent *dbe = (DBEvent*)rec.data;
- return (dbe->dwSignature == DBEVENT_SIGNATURE) ? dbe->contactID : INVALID_CONTACT_ID;
-}
-
-STDMETHODIMP_(MEVENT) CDbxKV::FindFirstEvent(MCONTACT contactID)
-{
- DBEventSortingKey keyVal = { contactID, 0, 0 };
- ham_key_t key = { sizeof(keyVal), &keyVal };
- ham_record_t rec = { 0 };
-
- if (ham_db_find(m_dbEventsSort, NULL, &key, &rec, HAM_FIND_GT_MATCH) != HAM_SUCCESS)
- return m_evLast = 0;
-
- DBEventSortingKey *pKey = (DBEventSortingKey*)key.data;
- m_tsLast = pKey->ts;
- return m_evLast = (pKey->dwContactId == contactID) ? pKey->dwEventId : 0;
-}
-
-STDMETHODIMP_(MEVENT) CDbxKV::FindFirstUnreadEvent(MCONTACT contactID)
-{
- DBCachedContact *cc = m_cache->GetCachedContact(contactID);
- return (cc == NULL) ? 0 : cc->dbc.dwFirstUnread;
-}
-
-STDMETHODIMP_(MEVENT) CDbxKV::FindLastEvent(MCONTACT contactID)
-{
- DBEventSortingKey keyVal = { contactID, 0xFFFFFFFF, 0xFFFFFFFF };
- ham_key_t key = { sizeof(keyVal), &keyVal };
- ham_record_t rec = { 0 };
-
- if (ham_db_find(m_dbEventsSort, NULL, &key, &rec, HAM_FIND_LT_MATCH) != HAM_SUCCESS)
- return m_evLast = 0;
-
- DBEventSortingKey *pKey = (DBEventSortingKey*)key.data;
- m_tsLast = pKey->ts;
- return m_evLast = (pKey->dwContactId == contactID) ? pKey->dwEventId : 0;
-}
-
-STDMETHODIMP_(MEVENT) CDbxKV::FindNextEvent(MCONTACT contactID, MEVENT hDbEvent)
-{
- if (hDbEvent == 0) return m_evLast = 0;
-
- DWORD ts;
- ham_record_t rec = { 0 };
-
- if (m_evLast != hDbEvent) {
- ham_key_t key = { sizeof(MEVENT), &hDbEvent };
- if (ham_db_find(m_dbEvents, NULL, &key, &rec, HAM_FIND_EXACT_MATCH) != HAM_SUCCESS)
- return 0;
- m_tsLast = ts = ((DBEvent*)rec.data)->timestamp;
- }
- else ts = m_tsLast;
-
- DBEventSortingKey keyVal = { contactID, ts, hDbEvent };
- ham_key_t key = { sizeof(keyVal), &keyVal };
- if (ham_db_find(m_dbEventsSort, NULL, &key, &rec, HAM_FIND_GT_MATCH) != HAM_SUCCESS)
- return m_evLast = 0;
-
- DBEventSortingKey *pKey = (DBEventSortingKey*)key.data;
- m_tsLast = pKey->ts;
- return m_evLast = (pKey->dwContactId == contactID) ? pKey->dwEventId : 0;
-}
-
-STDMETHODIMP_(MEVENT) CDbxKV::FindPrevEvent(MCONTACT contactID, MEVENT hDbEvent)
-{
- if (hDbEvent == 0) return m_evLast = 0;
-
- DWORD ts;
- ham_record_t rec = { 0 };
-
- if (m_evLast != hDbEvent) {
- ham_key_t key = { sizeof(MEVENT), &hDbEvent };
- if (ham_db_find(m_dbEvents, NULL, &key, &rec, HAM_FIND_EXACT_MATCH) != HAM_SUCCESS)
- return 0;
- m_tsLast = ts = ((DBEvent*)rec.data)->timestamp;
- }
- else ts = m_tsLast;
-
- DBEventSortingKey keyVal = { contactID, ts, hDbEvent };
- ham_key_t key = { sizeof(keyVal), &keyVal };
- if (ham_db_find(m_dbEventsSort, NULL, &key, &rec, HAM_FIND_LT_MATCH) != HAM_SUCCESS)
- return m_evLast = 0;
-
- DBEventSortingKey *pKey = (DBEventSortingKey*)key.data;
- m_tsLast = pKey->ts;
- return m_evLast = (pKey->dwContactId == contactID) ? pKey->dwEventId : 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-// low-level history cleaner
-
-int CDbxKV::WipeContactHistory(DBContact*)
-{
- // drop subContact's history if any
- return 0;
-}
diff --git a/plugins/Dbx_kv/src/dbintf.cpp b/plugins/Dbx_kv/src/dbintf.cpp
deleted file mode 100644
index 3c69388176..0000000000
--- a/plugins/Dbx_kv/src/dbintf.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "commonheaders.h"
-
-static int compareSettings(ham_db_t*, const uint8_t *p1, uint32_t, const uint8_t *p2, uint32_t)
-{
- DBSettingSortingKey *k1 = (DBSettingSortingKey*)p1, *k2 = (DBSettingSortingKey*)p2;
- if (k1->dwContactID < k2->dwContactID) return -1;
- if (k1->dwContactID > k2->dwContactID) return 1;
-
- if (k1->dwOfsModule < k2->dwOfsModule) return -1;
- if (k1->dwOfsModule > k2->dwOfsModule) return 1;
-
- return strcmp(k1->szSettingName, k2->szSettingName);
-}
-
-static int compareEvents(ham_db_t*, const uint8_t *p1, uint32_t, const uint8_t *p2, uint32_t)
-{
- DBEventSortingKey *k1 = (DBEventSortingKey*)p1, *k2 = (DBEventSortingKey*)p2;
- if (k1->dwContactId < k2->dwContactId) return -1;
- if (k1->dwContactId > k2->dwContactId) return 1;
-
- if (k1->ts < k2->ts) return -1;
- if (k1->ts > k2->ts) return 1;
-
- if (k1->dwEventId < k2->dwEventId) return -1;
- if (k1->dwEventId > k2->dwEventId) return 1;
-
- return 0;
-}
-
-static int ModCompare(const ModuleName *mn1, const ModuleName *mn2)
-{
- return strcmp(mn1->name, mn2->name);
-}
-
-static int OfsCompare(const ModuleName *mn1, const ModuleName *mn2)
-{
- return (mn1->ofs - mn2->ofs);
-}
-
-static int stringCompare2(const char *p1, const char *p2)
-{
- return strcmp(p1, p2);
-}
-
-CDbxKV::CDbxKV(const TCHAR *tszFileName, int iMode) :
- m_safetyMode(true),
- m_bReadOnly((iMode & DBMODE_READONLY) != 0),
- m_bShared((iMode & DBMODE_SHARED) != 0),
- m_dwMaxContactId(1),
- m_lMods(50, ModCompare),
- m_lOfs(50, OfsCompare),
- m_lResidentSettings(50, stringCompare2)
-{
- m_tszProfileName = mir_tstrdup(tszFileName);
- InitDbInstance(this);
-
- m_codePage = CallService(MS_LANGPACK_GETCODEPAGE, 0, 0);
- m_hModHeap = HeapCreate(0, 0, 0);
-}
-
-CDbxKV::~CDbxKV()
-{
- // destroy modules
- HeapDestroy(m_hModHeap);
-
- // automatically closes all tables
- ham_env_close(m_pMdbEnv, HAM_AUTO_CLEANUP);
-
- DestroyServiceFunction(hService);
- UnhookEvent(hHook);
-
- if (m_crypto)
- m_crypto->destroy();
-
- DestroyHookableEvent(hContactDeletedEvent);
- DestroyHookableEvent(hContactAddedEvent);
- DestroyHookableEvent(hSettingChangeEvent);
- DestroyHookableEvent(hEventMarkedRead);
-
- DestroyHookableEvent(hEventAddedEvent);
- DestroyHookableEvent(hEventDeletedEvent);
- DestroyHookableEvent(hEventFilterAddedEvent);
-
- DestroyDbInstance(this);
- mir_free(m_tszProfileName);
-}
-
-int CDbxKV::Load(bool bSkipInit)
-{
- int mode = HAM_ENABLE_FSYNC | HAM_DISABLE_RECOVERY;
- if (m_bReadOnly)
- mode += HAM_READ_ONLY;
-
- if (ham_env_open(&m_pMdbEnv, _T2A(m_tszProfileName), mode, NULL) != HAM_SUCCESS)
- return EGROKPRF_CANTREAD;
-
- if (!bSkipInit) {
- int iFlags = (m_bReadOnly) ? HAM_READ_ONLY : 0;
- if (ham_env_open_db(m_pMdbEnv, &m_dbGlobal, 1, iFlags, 0)) return EGROKPRF_DAMAGED;
- if (ham_env_open_db(m_pMdbEnv, &m_dbContacts, 2, iFlags, 0)) return EGROKPRF_DAMAGED;
- if (ham_env_open_db(m_pMdbEnv, &m_dbModules, 3, iFlags, 0)) return EGROKPRF_DAMAGED;
- if (ham_env_open_db(m_pMdbEnv, &m_dbEvents, 4, iFlags, 0)) return EGROKPRF_DAMAGED;
- if (ham_env_open_db(m_pMdbEnv, &m_dbEventsSort, 5, iFlags, 0)) return EGROKPRF_DAMAGED;
- if (ham_env_open_db(m_pMdbEnv, &m_dbSettings, 6, iFlags, 0)) return EGROKPRF_DAMAGED;
-
- ham_db_set_compare_func(m_dbEventsSort, compareEvents);
- ham_db_set_compare_func(m_dbSettings, compareSettings);
-
- DWORD keyVal = 1;
- ham_key_t key = { sizeof(DWORD), &keyVal };
- ham_record_t rec = { 0 };
- if (ham_db_find(m_dbGlobal, NULL, &key, &rec, HAM_FIND_EXACT_MATCH) == HAM_SUCCESS) {
- DBHeader *hdr = (DBHeader*)rec.data;
- if (hdr->dwSignature != DBHEADER_SIGNATURE)
- DatabaseCorruption(NULL);
-
- memcpy(&m_header, rec.data, sizeof(m_header));
- }
- else {
- m_header.dwSignature = DBHEADER_SIGNATURE;
- m_header.dwVersion = 1;
- rec.data = &m_header; rec.size = sizeof(m_header);
- ham_db_insert(m_dbGlobal, NULL, &key, &rec, HAM_OVERWRITE);
-
- keyVal = 0;
- DBContact dbc = { DBCONTACT_SIGNATURE, 0, 0, 0 };
- rec.data = &dbc; rec.size = sizeof(dbc);
- ham_db_insert(m_dbContacts, NULL, &key, &rec, HAM_OVERWRITE);
- }
-
- if (InitModuleNames()) return EGROKPRF_CANTREAD;
- if (InitCrypt()) return EGROKPRF_CANTREAD;
-
- // everything is ok, go on
- if (!m_bReadOnly) {
- // we don't need events in the service mode
- if (ServiceExists(MS_DB_SETSAFETYMODE)) {
- hContactDeletedEvent = CreateHookableEvent(ME_DB_CONTACT_DELETED);
- hContactAddedEvent = CreateHookableEvent(ME_DB_CONTACT_ADDED);
- hSettingChangeEvent = CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED);
- hEventMarkedRead = CreateHookableEvent(ME_DB_EVENT_MARKED_READ);
-
- hEventAddedEvent = CreateHookableEvent(ME_DB_EVENT_ADDED);
- hEventDeletedEvent = CreateHookableEvent(ME_DB_EVENT_DELETED);
- hEventFilterAddedEvent = CreateHookableEvent(ME_DB_EVENT_FILTER_ADD);
- }
- }
-
- FillContacts();
- }
-
- return ERROR_SUCCESS;
-}
-
-int CDbxKV::Create(void)
-{
- int flags = HAM_ENABLE_FSYNC | HAM_DISABLE_RECOVERY;
- if (ham_env_create(&m_pMdbEnv, _T2A(m_tszProfileName), flags, 0664, NULL) != HAM_SUCCESS)
- return EGROKPRF_CANTREAD;
-
- ham_parameter_t paramPrimKey32[] = { { HAM_PARAM_KEY_TYPE, HAM_TYPE_UINT32 }, { 0, 0 } };
- if (ham_env_create_db(m_pMdbEnv, &m_dbGlobal, 1, 0, paramPrimKey32)) return EGROKPRF_DAMAGED;
- if (ham_env_create_db(m_pMdbEnv, &m_dbContacts, 2, 0, paramPrimKey32)) return EGROKPRF_DAMAGED;
- if (ham_env_create_db(m_pMdbEnv, &m_dbModules, 3, 0, paramPrimKey32)) return EGROKPRF_DAMAGED;
- if (ham_env_create_db(m_pMdbEnv, &m_dbEvents, 4, 0, paramPrimKey32)) return EGROKPRF_DAMAGED;
-
- ham_parameter_t paramEventsPrimKey[] = {
- { HAM_PARAM_KEY_TYPE, HAM_TYPE_CUSTOM },
- { HAM_PARAM_KEY_SIZE, sizeof(DBEventSortingKey) },
- { 0, 0 } };
- if (ham_env_create_db(m_pMdbEnv, &m_dbEventsSort, 5, 0, paramEventsPrimKey)) return EGROKPRF_DAMAGED;
- ham_db_set_compare_func(m_dbEventsSort, compareEvents);
-
- ham_parameter_t paramSettingsPrimKey[] = {
- { HAM_PARAM_KEY_TYPE, HAM_TYPE_CUSTOM },
- { 0, 0 } };
- if (ham_env_create_db(m_pMdbEnv, &m_dbSettings, 6, 0, paramSettingsPrimKey)) return EGROKPRF_DAMAGED;
- ham_db_set_compare_func(m_dbSettings, compareSettings);
-
- return 0;
-}
-
-int CDbxKV::Check(void)
-{
- HANDLE hFile = CreateFile(m_tszProfileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- return EGROKPRF_CANTREAD;
-
- DWORD dummy = 0;
- char buf[32];
- if (!ReadFile(hFile, buf, sizeof(buf), &dummy, NULL)) {
- CloseHandle(hFile);
- return EGROKPRF_CANTREAD;
- }
-
- CloseHandle(hFile);
- return (memcmp(buf + 16, "HAM\x00", 4)) ? EGROKPRF_UNKHEADER : 0;
-}
-
-int CDbxKV::PrepareCheck(int*)
-{
- InitModuleNames();
- return InitCrypt();
-}
-
-STDMETHODIMP_(void) CDbxKV::SetCacheSafetyMode(BOOL bIsSet)
-{
- mir_cslock lck(m_csDbAccess);
- m_safetyMode = bIsSet != 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static DWORD DatabaseCorrupted = 0;
-static const TCHAR *msg = NULL;
-static DWORD dwErr = 0;
-static TCHAR tszPanic[] = LPGENT("Miranda has detected corruption in your database. This corruption may be fixed by DbChecker plugin. Please download it from https://miranda-ng.org/p/DbChecker/. Miranda will now shut down.");
-
-void __cdecl dbpanic(void *)
-{
- if (msg) {
- if (dwErr == ERROR_DISK_FULL)
- msg = TranslateT("Disk is full. Miranda will now shut down.");
-
- TCHAR err[256];
- mir_sntprintf(err, SIZEOF(err), msg, TranslateT("Database failure. Miranda will now shut down."), dwErr);
-
- MessageBox(0, err, TranslateT("Database Error"), MB_SETFOREGROUND | MB_TOPMOST | MB_APPLMODAL | MB_ICONWARNING | MB_OK);
- }
- else MessageBox(0, TranslateTS(tszPanic), TranslateT("Database Panic"), MB_SETFOREGROUND | MB_TOPMOST | MB_APPLMODAL | MB_ICONWARNING | MB_OK);
- TerminateProcess(GetCurrentProcess(), 255);
-}
-
-void CDbxKV::DatabaseCorruption(const TCHAR *text)
-{
- int kill = 0;
-
- mir_cslockfull lck(m_csDbAccess);
- if (DatabaseCorrupted == 0) {
- DatabaseCorrupted++;
- kill++;
- msg = text;
- dwErr = GetLastError();
- }
- else {
- /* db is already corrupted, someone else is dealing with it, wait here
- so that we don't do any more damage */
- Sleep(INFINITE);
- return;
- }
- lck.unlock();
-
- if (kill) {
- _beginthread(dbpanic, 0, NULL);
- Sleep(INFINITE);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// MIDatabaseChecker
-
-typedef int (CDbxKV::*CheckWorker)(int);
-
-int CDbxKV::Start(DBCHeckCallback *callback)
-{
- cb = callback;
- return ERROR_SUCCESS;
-}
-
-int CDbxKV::CheckDb(int, int)
-{
- return ERROR_OUT_OF_PAPER;
-
- // return (this->*Workers[phase])(firstTime);
-}
-
-void CDbxKV::Destroy()
-{
- delete this;
-}
diff --git a/plugins/Dbx_kv/src/dbintf.h b/plugins/Dbx_kv/src/dbintf.h
deleted file mode 100644
index 96f85b50d7..0000000000
--- a/plugins/Dbx_kv/src/dbintf.h
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#define OWN_CACHED_CONTACT
-
-#include <m_db_int.h>
-
-/* tree diagram
-
-DBHeader
-|-->end of file (plain offset)
-|-->first contact (DBContact)
-| |-->next contact (DBContact)
-| | \--> ...
-| |-->first settings (DBContactSettings)
-| | |-->next settings (DBContactSettings)
-| | | \--> ...
-| | \-->module name (DBModuleName)
-| \-->first/last/firstunread event
-|-->user contact (DBContact)
-| |-->next contact = NULL
-| |-->first settings as above
-| \-->first/last/firstunread event as above
-\-->first module name (DBModuleName)
-\-->next module name (DBModuleName)
-\--> ...
-*/
-
-#define DBMODE_SHARED 0x0001
-#define DBMODE_READONLY 0x0002
-
-#define DBVT_ENCRYPTED 250
-#define DBVT_UNENCRYPTED 251
-
-#define MARKED_READ (DBEF_READ | DBEF_SENT)
-
-struct ModuleName
-{
- char *name;
- DWORD ofs;
-};
-
-#include <pshpack1.h>
-
-#define DBHEADER_SIGNATURE 0x40DECADEu
-struct DBHeader
-{
- DWORD dwSignature;
- DWORD dwVersion; // database format version
-};
-
-#define DBCONTACT_SIGNATURE 0x43DECADEu
-struct DBContact
-{
- DWORD dwSignature;
- DWORD dwEventCount; // number of events in the chain for this contact
- DWORD tsFirstUnread;
- DWORD dwFirstUnread;
-};
-
-#define DBMODULENAME_SIGNATURE 0x4DDECADEu
-struct DBModuleName
-{
- DWORD dwSignature;
- BYTE cbName; // number of characters in this module name
- char name[1]; // name, no nul terminator
-};
-
-#define DBEVENT_SIGNATURE 0x45DECADEu
-struct DBEvent
-{
- DWORD dwSignature;
- MCONTACT contactID; // a contact this event belongs to
- DWORD ofsModuleName; // offset to a DBModuleName struct of the name of
- DWORD timestamp; // seconds since 00:00:00 01/01/1970
- DWORD flags; // see m_database.h, db/event/add
- WORD wEventType; // module-defined event type
- WORD cbBlob; // number of bytes in the blob
-
- bool __forceinline markedRead() const
- {
- return (flags & MARKED_READ) != 0;
- }
-};
-
-#include <poppack.h>
-
-struct DBEventSortingKey
-{
- DWORD dwContactId, ts, dwEventId;
-};
-
-struct DBSettingSortingKey
-{
- DWORD dwContactID;
- DWORD dwOfsModule;
- char szSettingName[100];
-};
-
-struct DBCachedContact : public DBCachedContactBase
-{
- void Advance(DWORD id, DBEvent &dbe);
-
- DBContact dbc;
-};
-
-struct CDbxKV : public MIDatabase, public MIDatabaseChecker, public MZeroedObject
-{
- CDbxKV(const TCHAR *tszFileName, int mode);
- ~CDbxKV();
-
- int Load(bool bSkipInit);
- int Create(void);
- int Check(void);
-
- void DatabaseCorruption(const TCHAR *ptszText);
-
- void ToggleEncryption(void);
- void StoreKey(void);
- void SetPassword(const TCHAR *ptszPassword);
- void UpdateMenuItem(void);
-
- int PrepareCheck(int*);
-
- __forceinline LPSTR GetMenuTitle() const { return m_bUsesPassword ? LPGEN("Change/remove password") : LPGEN("Set password"); }
-
- __forceinline bool isEncrypted() const { return m_bEncrypted; }
- __forceinline bool usesPassword() const { return m_bUsesPassword; }
-
-public:
- STDMETHODIMP_(BOOL) IsRelational(void) { return TRUE; }
- STDMETHODIMP_(void) SetCacheSafetyMode(BOOL);
-
- STDMETHODIMP_(LONG) GetContactCount(void);
- STDMETHODIMP_(MCONTACT) FindFirstContact(const char *szProto = NULL);
- STDMETHODIMP_(MCONTACT) FindNextContact(MCONTACT contactID, const char *szProto = NULL);
- STDMETHODIMP_(LONG) DeleteContact(MCONTACT contactID);
- STDMETHODIMP_(MCONTACT) AddContact(void);
- STDMETHODIMP_(BOOL) IsDbContact(MCONTACT contactID);
- STDMETHODIMP_(LONG) GetContactSize(void);
-
- STDMETHODIMP_(LONG) GetEventCount(MCONTACT contactID);
- STDMETHODIMP_(MEVENT) AddEvent(MCONTACT contactID, DBEVENTINFO *dbe);
- STDMETHODIMP_(BOOL) DeleteEvent(MCONTACT contactID, MEVENT hDbEvent);
- STDMETHODIMP_(LONG) GetBlobSize(MEVENT hDbEvent);
- STDMETHODIMP_(BOOL) GetEvent(MEVENT hDbEvent, DBEVENTINFO *dbe);
- STDMETHODIMP_(BOOL) MarkEventRead(MCONTACT contactID, MEVENT hDbEvent);
- STDMETHODIMP_(MCONTACT) GetEventContact(MEVENT hDbEvent);
- STDMETHODIMP_(MEVENT) FindFirstEvent(MCONTACT contactID);
- STDMETHODIMP_(MEVENT) FindFirstUnreadEvent(MCONTACT contactID);
- STDMETHODIMP_(MEVENT) FindLastEvent(MCONTACT contactID);
- STDMETHODIMP_(MEVENT) FindNextEvent(MCONTACT contactID, MEVENT hDbEvent);
- STDMETHODIMP_(MEVENT) FindPrevEvent(MCONTACT contactID, MEVENT hDbEvent);
-
- STDMETHODIMP_(BOOL) EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam);
-
- STDMETHODIMP_(BOOL) GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) FreeVariant(DBVARIANT *dbv);
- STDMETHODIMP_(BOOL) WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws);
- STDMETHODIMP_(BOOL) DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting);
- STDMETHODIMP_(BOOL) EnumContactSettings(MCONTACT contactID, DBCONTACTENUMSETTINGS *dbces);
- STDMETHODIMP_(BOOL) SetSettingResident(BOOL bIsResident, const char *pszSettingName);
- STDMETHODIMP_(BOOL) EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam);
- STDMETHODIMP_(BOOL) IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting);
-
- STDMETHODIMP_(BOOL) MetaDetouchSub(DBCachedContact *cc, int nSub);
- STDMETHODIMP_(BOOL) MetaSetDefault(DBCachedContact *cc);
- STDMETHODIMP_(BOOL) MetaMergeHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub);
- STDMETHODIMP_(BOOL) MetaSplitHistory(DBCachedContact *ccMeta, DBCachedContact *ccSub);
-
-protected:
- STDMETHODIMP_(BOOL) Start(DBCHeckCallback *callback);
- STDMETHODIMP_(BOOL) CheckDb(int phase, int firstTime);
- STDMETHODIMP_(VOID) Destroy();
-
-protected:
- void InvalidateSettingsGroupOfsCacheEntry(DWORD) {}
- int WorkInitialCheckHeaders(void);
-
- void FillContacts(void);
-
-public: // Check functions
- int WorkInitialChecks(int);
- int WorkModuleChain(int);
- int WorkUser(int);
- int WorkContactChain(int);
- int WorkAggressive(int);
- int WorkFinalTasks(int);
-
-protected:
- TCHAR* m_tszProfileName;
- bool m_safetyMode, m_bReadOnly, m_bShared, m_bEncrypted, m_bUsesPassword;
-
- ////////////////////////////////////////////////////////////////////////////
- // database stuff
-public:
- MICryptoEngine *m_crypto;
-
-protected:
- ham_env_t *m_pMdbEnv;
- ham_db_t *m_dbGlobal;
- DBHeader m_header;
-
- HANDLE hSettingChangeEvent, hContactDeletedEvent, hContactAddedEvent, hEventMarkedRead;
-
- mir_cs m_csDbAccess;
-
- int CheckProto(DBCachedContact *cc, const char *proto);
-
- ////////////////////////////////////////////////////////////////////////////
- // settings
-
- ham_db_t *m_dbSettings;
- int m_codePage;
- HANDLE hService, hHook;
-
- ////////////////////////////////////////////////////////////////////////////
- // contacts
-
- ham_db_t *m_dbContacts;
- int m_contactCount, m_dwMaxContactId;
-
- int WipeContactHistory(DBContact *dbc);
-
- ////////////////////////////////////////////////////////////////////////////
- // events
-
- ham_db_t *m_dbEvents, *m_dbEventsSort;
- DWORD m_dwMaxEventId, m_tsLast;
- MEVENT m_evLast;
-
- void FindNextUnread(DBCachedContact *cc, DBEventSortingKey &key2);
-
- ////////////////////////////////////////////////////////////////////////////
- // modules
-
- ham_db_t *m_dbModules;
- HANDLE m_hModHeap;
- LIST<ModuleName> m_lMods, m_lOfs;
- LIST<char> m_lResidentSettings;
- HANDLE hEventAddedEvent, hEventDeletedEvent, hEventFilterAddedEvent;
- MCONTACT m_hLastCachedContact;
- int m_maxModuleID;
- ModuleName *m_lastmn;
-
- void AddToList(char *name, DWORD ofs);
- DWORD FindExistingModuleNameOfs(const char *szName);
- int InitModuleNames(void);
- DWORD GetModuleNameOfs(const char *szName);
- char* GetModuleNameByOfs(DWORD ofs);
-
- ////////////////////////////////////////////////////////////////////////////
- // checker
-
- int PeekSegment(DWORD ofs, PVOID buf, int cbBytes);
- int ReadSegment(DWORD ofs, PVOID buf, int cbBytes);
- int ReadWrittenSegment(DWORD ofs, PVOID buf, int cbBytes);
- int SignatureValid(DWORD ofs, DWORD dwSignature);
- void FreeModuleChain();
-
- DWORD ConvertModuleNameOfs(DWORD ofsOld);
- void ConvertOldEvent(DBEvent*& dbei);
-
- int GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic);
- int WorkSettingsChain(DBContact *dbc, int firstTime);
- int WorkEventChain(DWORD ofsContact, DBContact *dbc, int firstTime);
-
- DWORD WriteSegment(DWORD ofs, PVOID buf, int cbBytes);
- DWORD WriteEvent(DBEvent *dbe);
- DWORD PeekEvent(DWORD ofs, DWORD dwContactID, DBEvent &dbe);
- void WriteOfsNextToPrevious(DWORD ofsPrev, DBContact *dbc, DWORD ofsNext);
- void FinishUp(DWORD ofsLast, DBContact *dbc);
-
- DBCHeckCallback *cb;
- DWORD sourceFileSize, ofsAggrCur;
-
- ////////////////////////////////////////////////////////////////////////////
- // encryption
-
- int InitCrypt(void);
- void ToggleEventsEncryption(MCONTACT contactID);
- void ToggleSettingsEncryption(MCONTACT contactID);
-
- void InitDialogs();
- bool EnterPassword(const BYTE *pKey, const size_t keyLen);
-};
diff --git a/plugins/Dbx_kv/src/dbmodulechain.cpp b/plugins/Dbx_kv/src/dbmodulechain.cpp
deleted file mode 100644
index b1fc59890d..0000000000
--- a/plugins/Dbx_kv/src/dbmodulechain.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "commonheaders.h"
-
-void CDbxKV::AddToList(char *name, DWORD ofs)
-{
- ModuleName *mn = (ModuleName*)HeapAlloc(m_hModHeap, 0, sizeof(ModuleName));
- mn->name = name;
- mn->ofs = ofs;
-
- if (m_lMods.getIndex(mn) != -1)
- DatabaseCorruption(L"%s (Module Name not unique)");
- m_lMods.insert(mn);
-
- if (m_lOfs.getIndex(mn) != -1)
- DatabaseCorruption(L"%s (Module Offset not unique)");
- m_lOfs.insert(mn);
-}
-
-int CDbxKV::InitModuleNames(void)
-{
- m_maxModuleID = 0;
-
- ham_key_t key = { 0 };
- ham_record_t rec = { 0 };
- cursor_ptr cursor(m_dbModules);
- if (ham_cursor_move(cursor, &key, &rec, HAM_CURSOR_FIRST) != HAM_SUCCESS)
- return 0;
-
- do {
- DBModuleName *pmod = (DBModuleName*)rec.data;
- if (pmod->dwSignature != DBMODULENAME_SIGNATURE)
- DatabaseCorruption(NULL);
-
- char *pVal = (char*)HeapAlloc(m_hModHeap, 0, pmod->cbName+1);
- memcpy(pVal, pmod->name, pmod->cbName);
- pVal[pmod->cbName] = 0;
-
- int moduleId = *(int*)key.data;
- AddToList(pVal, moduleId);
-
- if (moduleId > m_maxModuleID)
- m_maxModuleID = moduleId;
- } while (ham_cursor_move(cursor, &key, &rec, HAM_CURSOR_NEXT) == 0);
-
- return 0;
-}
-
-DWORD CDbxKV::FindExistingModuleNameOfs(const char *szName)
-{
- ModuleName mn = { (char*)szName, 0 };
- if (m_lastmn && !strcmp(mn.name, m_lastmn->name))
- return m_lastmn->ofs;
-
- int index = m_lMods.getIndex(&mn);
- if (index != -1) {
- ModuleName *pmn = m_lMods[index];
- m_lastmn = pmn;
- return pmn->ofs;
- }
-
- return 0;
-}
-
-// will create the offset if it needs to
-DWORD CDbxKV::GetModuleNameOfs(const char *szName)
-{
- DWORD ofsExisting = FindExistingModuleNameOfs(szName);
- if (ofsExisting)
- return ofsExisting;
-
- if (m_bReadOnly)
- return 0;
-
- int nameLen = (int)strlen(szName);
-
- // need to create the module name
- int newIdx = ++m_maxModuleID;
- DBModuleName *pmod = (DBModuleName*)_alloca(sizeof(DBModuleName) + nameLen);
- pmod->dwSignature = DBMODULENAME_SIGNATURE;
- pmod->cbName = (char)nameLen;
- strcpy(pmod->name, szName);
-
- ham_key_t key = { sizeof(int), &newIdx };
- ham_record_t rec = { sizeof(DBModuleName) + nameLen, pmod };
- ham_db_insert(m_dbModules, NULL, &key, &rec, HAM_OVERWRITE);
-
- // add to cache
- char *mod = (char*)HeapAlloc(m_hModHeap, 0, nameLen + 1);
- strcpy(mod, szName);
- AddToList(mod, newIdx);
-
- // quit
- return -1;
-}
-
-char* CDbxKV::GetModuleNameByOfs(DWORD ofs)
-{
- if (m_lastmn && m_lastmn->ofs == ofs)
- return m_lastmn->name;
-
- ModuleName mn = { NULL, ofs };
- int index = m_lOfs.getIndex(&mn);
- if (index != -1) {
- ModuleName *pmn = m_lOfs[index];
- m_lastmn = pmn;
- return pmn->name;
- }
-
- return NULL;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::EnumModuleNames(DBMODULEENUMPROC pFunc, void *pParam)
-{
- for (int i = 0; i < m_lMods.getCount(); i++) {
- ModuleName *pmn = m_lMods[i];
- int ret = pFunc(pmn->name, pmn->ofs, (LPARAM)pParam);
- if (ret)
- return ret;
- }
- return 0;
-}
diff --git a/plugins/Dbx_kv/src/dbsettings.cpp b/plugins/Dbx_kv/src/dbsettings.cpp
deleted file mode 100644
index 63b9f51c9e..0000000000
--- a/plugins/Dbx_kv/src/dbsettings.cpp
+++ /dev/null
@@ -1,605 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "commonheaders.h"
-
-#define VLT(n) ((n == DBVT_UTF8 || n == DBVT_ENCRYPTED)?DBVT_ASCIIZ:n)
-
-BOOL CDbxKV::IsSettingEncrypted(LPCSTR szModule, LPCSTR szSetting)
-{
- if (!_strnicmp(szSetting, "password", 8)) return true;
- if (!strcmp(szSetting, "NLProxyAuthPassword")) return true;
- if (!strcmp(szSetting, "LNPassword")) return true;
- if (!strcmp(szSetting, "FileProxyPassword")) return true;
- if (!strcmp(szSetting, "TokenSecret")) return true;
-
- if (!strcmp(szModule, "SecureIM")) {
- if (!strcmp(szSetting, "pgp")) return true;
- if (!strcmp(szSetting, "pgpPrivKey")) return true;
- }
- return false;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static bool ValidLookupName(LPCSTR szModule, LPCSTR szSetting)
-{
- if (!strcmp(szModule, META_PROTO))
- return strcmp(szSetting, "IsSubcontact") && strcmp(szSetting, "ParentMetaID");
-
- if (!strcmp(szModule, "Ignore"))
- return false;
-
- return true;
-}
-
-int CDbxKV::GetContactSettingWorker(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, int isStatic)
-{
- if (szSetting == NULL || szModule == NULL)
- return 1;
-
- // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name
- int settingNameLen = (int)strlen(szSetting);
- int moduleNameLen = (int)strlen(szModule);
- if (settingNameLen > 0xFE) {
-#ifdef _DEBUG
- OutputDebugStringA("GetContactSettingWorker() got a > 255 setting name length. \n");
-#endif
- return 1;
- }
- if (moduleNameLen > 0xFE) {
-#ifdef _DEBUG
- OutputDebugStringA("GetContactSettingWorker() got a > 255 module name length. \n");
-#endif
- return 1;
- }
-
- mir_cslock lck(m_csDbAccess);
-
-LBL_Seek:
- char *szCachedSettingName = m_cache->GetCachedSetting(szModule, szSetting, moduleNameLen, settingNameLen);
-
- DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 0);
- if (pCachedValue != NULL) {
- if (pCachedValue->type == DBVT_ASCIIZ || pCachedValue->type == DBVT_UTF8) {
- int cbOrigLen = dbv->cchVal;
- char *cbOrigPtr = dbv->pszVal;
- memcpy(dbv, pCachedValue, sizeof(DBVARIANT));
- if (isStatic) {
- int cbLen = 0;
- if (pCachedValue->pszVal != NULL)
- cbLen = (int)strlen(pCachedValue->pszVal);
-
- cbOrigLen--;
- dbv->pszVal = cbOrigPtr;
- if (cbLen < cbOrigLen)
- cbOrigLen = cbLen;
- memcpy(dbv->pszVal, pCachedValue->pszVal, cbOrigLen);
- dbv->pszVal[cbOrigLen] = 0;
- dbv->cchVal = cbLen;
- }
- else {
- dbv->pszVal = (char*)mir_alloc(strlen(pCachedValue->pszVal) + 1);
- strcpy(dbv->pszVal, pCachedValue->pszVal);
- }
- }
- else memcpy(dbv, pCachedValue, sizeof(DBVARIANT));
-
- return (pCachedValue->type == DBVT_DELETED) ? 1 : 0;
- }
-
- // never look db for the resident variable
- if (szCachedSettingName[-1] != 0)
- return 1;
-
- DBCachedContact *cc = (contactID) ? m_cache->GetCachedContact(contactID) : NULL;
-
- DBSettingSortingKey keySearch;
- keySearch.dwContactID = contactID;
- keySearch.dwOfsModule = GetModuleNameOfs(szModule);
- strncpy_s(keySearch.szSettingName, szSetting, _TRUNCATE);
-
- ham_key_t key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch };
- ham_record_t rec = { 0 };
- if (ham_db_find(m_dbSettings, NULL, &key, &rec, 0)) {
- // try to get the missing mc setting from the active sub
- if (cc && cc->IsMeta() && ValidLookupName(szModule, szSetting)) {
- if (contactID = db_mc_getDefault(contactID)) {
- if (szModule = GetContactProto(contactID)) {
- moduleNameLen = (int)strlen(szModule);
- goto LBL_Seek;
- }
- }
- }
- return 1;
- }
-
- BYTE *pBlob = (BYTE*)rec.data;
- if (isStatic && (pBlob[0] & DBVTF_VARIABLELENGTH) && VLT(dbv->type) != VLT(pBlob[0]))
- return 1;
-
- int varLen;
- BYTE iType = dbv->type = pBlob[0]; pBlob++;
- switch (iType) {
- case DBVT_DELETED: /* this setting is deleted */
- dbv->type = DBVT_DELETED;
- return 2;
-
- case DBVT_BYTE: dbv->bVal = *pBlob; break;
- case DBVT_WORD: dbv->wVal = *(WORD*)pBlob; break;
- case DBVT_DWORD: dbv->dVal = *(DWORD*)pBlob; break;
-
- case DBVT_UTF8:
- case DBVT_ASCIIZ:
- varLen = *(WORD*)pBlob;
- pBlob += 2;
- if (isStatic) {
- dbv->cchVal--;
- if (varLen < dbv->cchVal)
- dbv->cchVal = varLen;
- memmove(dbv->pszVal, pBlob, dbv->cchVal); // decode
- dbv->pszVal[dbv->cchVal] = 0;
- dbv->cchVal = varLen;
- }
- else {
- dbv->pszVal = (char*)mir_alloc(1 + varLen);
- memmove(dbv->pszVal, pBlob, varLen);
- dbv->pszVal[varLen] = 0;
- }
- break;
-
- case DBVT_BLOB:
- varLen = *(WORD*)pBlob;
- pBlob += 2;
- if (isStatic) {
- if (varLen < dbv->cpbVal)
- dbv->cpbVal = varLen;
- memmove(dbv->pbVal, pBlob, dbv->cpbVal);
- }
- else {
- dbv->pbVal = (BYTE *)mir_alloc(varLen);
- memmove(dbv->pbVal, pBlob, varLen);
- }
- dbv->cpbVal = varLen;
- break;
-
- case DBVT_ENCRYPTED:
- if (m_crypto == NULL)
- return 1;
-
- varLen = *(WORD*)pBlob;
- pBlob += 2;
-
- size_t realLen;
- ptrA decoded(m_crypto->decodeString(pBlob, varLen, &realLen));
- if (decoded == NULL)
- return 1;
-
- varLen = (WORD)realLen;
- dbv->type = DBVT_UTF8;
- if (isStatic) {
- dbv->cchVal--;
- if (varLen < dbv->cchVal)
- dbv->cchVal = varLen;
- memmove(dbv->pszVal, decoded, dbv->cchVal);
- dbv->pszVal[dbv->cchVal] = 0;
- dbv->cchVal = varLen;
- }
- else {
- dbv->pszVal = (char*)mir_alloc(1 + varLen);
- memmove(dbv->pszVal, decoded, varLen);
- dbv->pszVal[varLen] = 0;
- }
- break;
- }
-
- /**** add to cache **********************/
- if (iType != DBVT_BLOB && iType != DBVT_ENCRYPTED) {
- DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1);
- if (pCachedValue != NULL)
- m_cache->SetCachedVariant(dbv, pCachedValue);
- }
-
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::GetContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- dbv->type = 0;
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
- return 1;
-
- if (dbv->type == DBVT_UTF8) {
- WCHAR *tmp = NULL;
- char *p = NEWSTR_ALLOCA(dbv->pszVal);
- if (mir_utf8decode(p, &tmp) != NULL) {
- BOOL bUsed = FALSE;
- int result = WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, NULL, 0, NULL, &bUsed);
-
- mir_free(dbv->pszVal);
-
- if (bUsed || result == 0) {
- dbv->type = DBVT_WCHAR;
- dbv->pwszVal = tmp;
- }
- else {
- dbv->type = DBVT_ASCIIZ;
- dbv->pszVal = (char *)mir_alloc(result);
- WideCharToMultiByte(m_codePage, WC_NO_BEST_FIT_CHARS, tmp, -1, dbv->pszVal, result, NULL, NULL);
- mir_free(tmp);
- }
- }
- else {
- dbv->type = DBVT_ASCIIZ;
- mir_free(tmp);
- }
- }
-
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::GetContactSettingStr(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- int iSaveType = dbv->type;
-
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 0))
- return 1;
-
- if (iSaveType == 0 || iSaveType == dbv->type)
- return 0;
-
- if (dbv->type != DBVT_ASCIIZ && dbv->type != DBVT_UTF8)
- return 1;
-
- if (iSaveType == DBVT_WCHAR) {
- if (dbv->type != DBVT_UTF8) {
- int len = MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, NULL, 0);
- wchar_t *wszResult = (wchar_t*)mir_alloc((len + 1)*sizeof(wchar_t));
- if (wszResult == NULL)
- return 1;
-
- MultiByteToWideChar(CP_ACP, 0, dbv->pszVal, -1, wszResult, len);
- wszResult[len] = 0;
- mir_free(dbv->pszVal);
- dbv->pwszVal = wszResult;
- }
- else {
- char* savePtr = NEWSTR_ALLOCA(dbv->pszVal);
- mir_free(dbv->pszVal);
- if (!mir_utf8decode(savePtr, &dbv->pwszVal))
- return 1;
- }
- }
- else if (iSaveType == DBVT_UTF8) {
- char* tmpBuf = mir_utf8encode(dbv->pszVal);
- if (tmpBuf == NULL)
- return 1;
-
- mir_free(dbv->pszVal);
- dbv->pszVal = tmpBuf;
- }
- else if (iSaveType == DBVT_ASCIIZ)
- mir_utf8decode(dbv->pszVal, NULL);
-
- dbv->type = iSaveType;
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::GetContactSettingStatic(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv)
-{
- if (GetContactSettingWorker(contactID, szModule, szSetting, dbv, 1))
- return 1;
-
- if (dbv->type == DBVT_UTF8) {
- mir_utf8decode(dbv->pszVal, NULL);
- dbv->type = DBVT_ASCIIZ;
- }
-
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::FreeVariant(DBVARIANT *dbv)
-{
- if (dbv == 0) return 1;
-
- switch (dbv->type) {
- case DBVT_ASCIIZ:
- case DBVT_UTF8:
- case DBVT_WCHAR:
- if (dbv->pszVal) mir_free(dbv->pszVal);
- dbv->pszVal = 0;
- break;
- case DBVT_BLOB:
- if (dbv->pbVal) mir_free(dbv->pbVal);
- dbv->pbVal = 0;
- break;
- }
- dbv->type = 0;
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::SetSettingResident(BOOL bIsResident, const char *pszSettingName)
-{
- char *szSetting = m_cache->GetCachedSetting(NULL, pszSettingName, 0, (int)strlen(pszSettingName));
- szSetting[-1] = (char)bIsResident;
-
- mir_cslock lck(m_csDbAccess);
- int idx = m_lResidentSettings.getIndex(szSetting);
- if (idx == -1) {
- if (bIsResident)
- m_lResidentSettings.insert(szSetting);
- }
- else if (!bIsResident)
- m_lResidentSettings.remove(idx);
-
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws)
-{
- if (dbcws == NULL || dbcws->szSetting == NULL || dbcws->szModule == NULL || m_bReadOnly)
- return 1;
-
- // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name
- int settingNameLen = (int)strlen(dbcws->szSetting);
- int moduleNameLen = (int)strlen(dbcws->szModule);
- if (settingNameLen > 0xFE) {
-#ifdef _DEBUG
- OutputDebugStringA("WriteContactSetting() got a > 255 setting name length. \n");
-#endif
- return 1;
- }
- if (moduleNameLen > 0xFE) {
-#ifdef _DEBUG
- OutputDebugStringA("WriteContactSetting() got a > 255 module name length. \n");
-#endif
- return 1;
- }
-
- // used for notifications
- DBCONTACTWRITESETTING dbcwNotif = *dbcws;
- if (dbcwNotif.value.type == DBVT_WCHAR) {
- if (dbcwNotif.value.pszVal != NULL) {
- char* val = mir_utf8encodeW(dbcwNotif.value.pwszVal);
- if (val == NULL)
- return 1;
-
- dbcwNotif.value.pszVal = (char*)alloca(strlen(val) + 1);
- strcpy(dbcwNotif.value.pszVal, val);
- mir_free(val);
- dbcwNotif.value.type = DBVT_UTF8;
- }
- else return 1;
- }
-
- if (dbcwNotif.szModule == NULL || dbcwNotif.szSetting == NULL)
- return 1;
-
- DBCONTACTWRITESETTING dbcwWork = dbcwNotif;
-
- mir_ptr<BYTE> pEncoded(NULL);
- bool bIsEncrypted = false;
- switch (dbcwWork.value.type) {
- case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD:
- break;
-
- case DBVT_ASCIIZ: case DBVT_UTF8:
- bIsEncrypted = m_bEncrypted || IsSettingEncrypted(dbcws->szModule, dbcws->szSetting);
- LBL_WriteString:
- if (dbcwWork.value.pszVal == NULL)
- return 1;
- dbcwWork.value.cchVal = (WORD)strlen(dbcwWork.value.pszVal);
- if (bIsEncrypted) {
- size_t len;
- BYTE *pResult = m_crypto->encodeString(dbcwWork.value.pszVal, &len);
- if (pResult != NULL) {
- pEncoded = dbcwWork.value.pbVal = pResult;
- dbcwWork.value.cpbVal = (WORD)len;
- dbcwWork.value.type = DBVT_ENCRYPTED;
- }
- }
- break;
-
- case DBVT_UNENCRYPTED:
- dbcwNotif.value.type = dbcwWork.value.type = DBVT_UTF8;
- goto LBL_WriteString;
-
- case DBVT_BLOB: case DBVT_ENCRYPTED:
- if (dbcwWork.value.pbVal == NULL)
- return 1;
- break;
- default:
- return 1;
- }
-
- mir_cslockfull lck(m_csDbAccess);
-
- char *szCachedSettingName = m_cache->GetCachedSetting(dbcwWork.szModule, dbcwWork.szSetting, moduleNameLen, settingNameLen);
-
- // we don't cache blobs and passwords
- if (dbcwWork.value.type != DBVT_BLOB && dbcwWork.value.type != DBVT_ENCRYPTED && !bIsEncrypted) {
- DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1);
- if (pCachedValue != NULL) {
- bool bIsIdentical = false;
- if (pCachedValue->type == dbcwWork.value.type) {
- switch (dbcwWork.value.type) {
- case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == dbcwWork.value.bVal; break;
- case DBVT_WORD: bIsIdentical = pCachedValue->wVal == dbcwWork.value.wVal; break;
- case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == dbcwWork.value.dVal; break;
- case DBVT_UTF8:
- case DBVT_ASCIIZ: bIsIdentical = strcmp(pCachedValue->pszVal, dbcwWork.value.pszVal) == 0; break;
- }
- if (bIsIdentical)
- return 0;
- }
- m_cache->SetCachedVariant(&dbcwWork.value, pCachedValue);
- }
- if (szCachedSettingName[-1] != 0) {
- lck.unlock();
- NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwWork);
- return 0;
- }
- }
- else m_cache->GetCachedValuePtr(contactID, szCachedSettingName, -1);
-
- DBSettingSortingKey keySearch;
- keySearch.dwContactID = contactID;
- keySearch.dwOfsModule = GetModuleNameOfs(dbcws->szModule);
- strncpy_s(keySearch.szSettingName, dbcws->szSetting, _TRUNCATE);
-
- ham_key_t key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch };
- ham_record_t rec = { 0 };
-
- switch (dbcwWork.value.type) {
- case DBVT_BYTE: rec.size = 2; break;
- case DBVT_WORD: rec.size = 3; break;
- case DBVT_DWORD: rec.size = 5; break;
-
- case DBVT_ASCIIZ:
- case DBVT_UTF8:
- rec.size = 3 + dbcwWork.value.cchVal; break;
-
- case DBVT_BLOB:
- case DBVT_ENCRYPTED:
- rec.size = 3 + dbcwWork.value.cpbVal; break;
-
- default:
- return 1;
- }
-
- rec.data = _alloca(rec.size);
- BYTE *pBlob = (BYTE*)rec.data;
- *pBlob++ = dbcwWork.value.type;
- switch (dbcwWork.value.type) {
- case DBVT_BYTE: *pBlob = dbcwWork.value.bVal; break;
- case DBVT_WORD: *(WORD*)pBlob = dbcwWork.value.wVal; break;
- case DBVT_DWORD: *(DWORD*)pBlob = dbcwWork.value.dVal; break;
-
- case DBVT_ASCIIZ:
- case DBVT_UTF8:
- *(WORD*)pBlob = dbcwWork.value.cchVal;
- memcpy(pBlob+2, dbcwWork.value.pszVal, dbcwWork.value.cchVal);
- break;
-
- case DBVT_BLOB:
- case DBVT_ENCRYPTED:
- *(WORD*)pBlob = dbcwWork.value.cpbVal;
- memcpy(pBlob+2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal);
- }
- ham_db_insert(m_dbSettings, NULL, &key, &rec, HAM_OVERWRITE);
- lck.unlock();
-
- // notify
- NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwNotif);
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::DeleteContactSetting(MCONTACT contactID, LPCSTR szModule, LPCSTR szSetting)
-{
- if (!szModule || !szSetting)
- return 1;
-
- // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name
- int settingNameLen = (int)strlen(szSetting);
- int moduleNameLen = (int)strlen(szModule);
- if (settingNameLen > 0xFE) {
-#ifdef _DEBUG
- OutputDebugStringA("DeleteContactSetting() got a > 255 setting name length. \n");
-#endif
- return 1;
- }
- if (moduleNameLen > 0xFE) {
-#ifdef _DEBUG
- OutputDebugStringA("DeleteContactSetting() got a > 255 module name length. \n");
-#endif
- return 1;
- }
-
- MCONTACT saveContact = contactID;
- {
- mir_cslock lck(m_csDbAccess);
- char *szCachedSettingName = m_cache->GetCachedSetting(szModule, szSetting, moduleNameLen, settingNameLen);
- if (szCachedSettingName[-1] == 0) { // it's not a resident variable
- DBSettingSortingKey keySearch;
- keySearch.dwContactID = contactID;
- keySearch.dwOfsModule = GetModuleNameOfs(szModule);
- strncpy_s(keySearch.szSettingName, szSetting, _TRUNCATE);
-
- ham_key_t key = { 2 * sizeof(DWORD) + settingNameLen, &keySearch };
- if (ham_db_erase(m_dbSettings, NULL, &key, 0) != HAM_SUCCESS)
- return 1;
- }
-
- m_cache->GetCachedValuePtr(saveContact, szCachedSettingName, -1);
- }
-
- // notify
- DBCONTACTWRITESETTING dbcws = { 0 };
- dbcws.szModule = szModule;
- dbcws.szSetting = szSetting;
- dbcws.value.type = DBVT_DELETED;
- NotifyEventHooks(hSettingChangeEvent, saveContact, (LPARAM)&dbcws);
- return 0;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::EnumContactSettings(MCONTACT contactID, DBCONTACTENUMSETTINGS* dbces)
-{
- if (!dbces->szModule)
- return -1;
-
- mir_cslock lck(m_csDbAccess);
-
- DBSettingSortingKey keySearch;
- keySearch.dwContactID = contactID;
- keySearch.dwOfsModule = GetModuleNameOfs(dbces->szModule);
- memset(keySearch.szSettingName, 0, SIZEOF(keySearch.szSettingName));
-
- int result = -1;
-
- ham_record_t rec = { 0 };
- ham_key_t key = { sizeof(keySearch), &keySearch };
-
- cursor_ptr cursor(m_dbSettings);
- if (ham_cursor_find(cursor, &key, &rec, HAM_FIND_GEQ_MATCH) == HAM_SUCCESS) {
- do {
- DBSettingSortingKey *pKey = (DBSettingSortingKey*)key.data;
- if (pKey->dwContactID != contactID || pKey->dwOfsModule != keySearch.dwOfsModule)
- break;
-
- char szSetting[256];
- strncpy_s(szSetting, pKey->szSettingName, key.size - sizeof(DWORD) * 2);
- result = (dbces->pfnEnumProc)(szSetting, dbces->lParam);
- } while (ham_cursor_move(cursor, &key, &rec, HAM_CURSOR_NEXT) == HAM_SUCCESS);
- }
-
- return result;
-}
-
-STDMETHODIMP_(BOOL) CDbxKV::EnumResidentSettings(DBMODULEENUMPROC pFunc, void *pParam)
-{
- for (int i = 0; i < m_lResidentSettings.getCount(); i++) {
- int ret = pFunc(m_lResidentSettings[i], 0, (LPARAM)pParam);
- if (ret) return ret;
- }
- return 0;
-}
diff --git a/plugins/Dbx_kv/src/hamsterdb/AUTHORS b/plugins/Dbx_kv/src/hamsterdb/AUTHORS
deleted file mode 100644
index 6b0d2a235f..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/AUTHORS
+++ /dev/null
@@ -1,6 +0,0 @@
-
-Ger Hobbelt (http://www.hobbelt.com, http://www.hebbut.net - THANKS!)
- ham_env_get_parameters, ham_db_get_parameters and functions for approximate
- matching, minor bugfixes and performance improvements plus documentation
- fixes/improvements; a complete rewrite of the freelist code with HUGE
- performance gains - THANKS!
diff --git a/plugins/Dbx_kv/src/hamsterdb/COPYING b/plugins/Dbx_kv/src/hamsterdb/COPYING
deleted file mode 100644
index d645695673..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/plugins/Dbx_kv/src/hamsterdb/CREDITS b/plugins/Dbx_kv/src/hamsterdb/CREDITS
deleted file mode 100644
index d2571aeebd..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/CREDITS
+++ /dev/null
@@ -1,6 +0,0 @@
-
-Jul 20, 2009
-ham_env_get_parameters, ham_db_get_parameters and functions for approximate
-matching, minor bugfixes and performance improvements plus documentation
-improvements were written by Ger Hobbelt, http://www.hobbelt.com,
-http://www.hebbut.net - THANKS!
diff --git a/plugins/Dbx_kv/src/hamsterdb/NEWS b/plugins/Dbx_kv/src/hamsterdb/NEWS
deleted file mode 100644
index da7acb2eb3..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/NEWS
+++ /dev/null
@@ -1 +0,0 @@
-See http://hamsterdb.com for up-to-date news about the project.
diff --git a/plugins/Dbx_kv/src/hamsterdb/README b/plugins/Dbx_kv/src/hamsterdb/README
deleted file mode 100644
index 66fba73f22..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/README
+++ /dev/null
@@ -1,261 +0,0 @@
-hamsterdb 2.1.10 Mo 23. Feb 23:07:52 CET 2015
-(C) Christoph Rupp, chris@crupp.de; http://www.hamsterdb.com
-
-This is the README file of hamsterdb.
-
-Contents:
-
-1. About
-
-hamsterdb is a database engine written in C/C++. It is fast, production-proven
-and easy to use.
-
-This release has several bug fixes (see below for a list). Thanks to those who
-reported them and invested lots of time to come up with samples to reproduce
-the bugs.
-
-The flag HAM_RECORD_NUMBER is deprecated. It is replaced with
-HAM_RECORD_NUMBER64 for 64bit record numbers, and HAM_RECORD_NUMBER32 for
-32bit record numbers.
-
-A major change under the hood: dirty pages are now flushed asynchronously.
-Expect performance improvements in this release, and more to come in the
-next releases.
-
-2. Changes
-
-New Features
-* Added Cursor.TryFind to hamsterdb-dotnet
- (thanks, mjmckp <matthew.j.m.peacock@gmail.com>)
-* The page cache eviction was moved to a background thread
-* When reading records from mmapped storage, a pointer into the storage
- is returned and the record data is no longer copied
-
-Bugfixes
-* Fixed FreeBSD compilation errors (thanks, Heping Wen)
-* issue #46: fixed segfault in approx. matching (thanks, Joel
- Jacobson)
-* issue #45: fixed segfault in Journal recovery (thanks, Michael
- Moellney)
-* issue #44: approx. matching returned the wrong key (thanks, Joel
- Jacobson)
-* issue #43: fixed segfault when flushing transactions (thanks, Joel
- Jacobson)
-* Fixed compilation error on debian Wheezy, gcc 4.7.2, 32bit (thanks,
- Thomas Fähnle)
-* Fixed compilation error on OSX (thanks, Daniel Lemire)
-* issue #42: ham_cursor_find returned wrong key w/ approx. matching and
- transactions
-* Fixed large file support on linux (thanks, Thomas Fähnle)
-
-Other Changes
-* Default compilation flag is now -O3
-* Added a new parameter HAM_PARAM_POSIX_FADVISE (thanks, Thomas Fähnle)
-* Removed dependency to malloc.h
-* The github wiki is now linked into documentation/wiki
-* The macro HAM_API_REVISION is now deprecated; use HAM_VERSION_* instead
-* Deprecated HAM_RECORD_NUMBER (use HAM_RECORD_NUMBER64 instead);
- introduced a new flag HAM_RECORD_NUMBER32 for 32bit record numbers
-* Implemented ham_cursor_get_record_size() for remote access
-
-To see a list of all changes, look in the file ChangeLog.
-
-3. Roadmap
-- See https://github.com/cruppstahl/hamsterdb/wiki/Roadmap
-
-4. Features
-
-- PRO: SIMD instructions for lookups
-- PRO: transparent AES encryption
-- PRO: transparent CRC32 verification
-- PRO: transparent compression for journal, keys and records using
- zlib, snappy, lzf or lzo
-- PRO: compression for uint32 keys
-
-- Very fast sorted B+Tree with variable length keys
-- Basic schema support for POD types (i.e. uint32, uint64, real32 etc)
-- Very fast analytical functions
-- Can run as an in-memory database
-- Multiple databases in one file
-- Record number databases ("auto-increment")
-- Duplicate keys
-- Logging and recovery
-- Unlimited number of parallel Transactions
-- Partial reading/writing of records
-- Network access (remote databases) via TCP/Protocol Buffers
-- Very fast database cursors
-- Configurable page size, cache size, key size etc
-- Runs on Linux, Unices, Microsoft Windows and other architectures
-- Uses memory mapped I/O for fast disk access (but falls back to read/write if
- mmap is not available)
-- Uses 64bit file pointers and supports huge files (>2 GB)
-- Easy to use and well-documented
-- Open source and released under APL 2.0 license
-- Wrappers for C++, Java, .NET, Erlang, Python, Ada and others
-
-5. Known Issues/Bugs
-
-None.
-
-6. Compiling
-
-6.1 Linux, MacOS and other Unix systems
-
-To compile hamsterdb, run ./configure, make, make install.
-
-Run `./configure --help' for more options (i.e. static/dynamic library,
-build with debugging symbols etc).
-
-6.2 Microsoft Visual Studio 8
-
-A Solution file is provided for Microsoft Visual C++ in the "win32" folder
-for MSVC 2008 and MSVC 2010.
-All libraries can be downloaded precompiled from the hamsterdb webpage.
-
-To download Microsoft Visual Studio Express Edition for free, go to
-http://msdn.microsoft.com/vstudio/express/visualc/default.aspx.
-
-6.3 Dependencies
-
-On Ubuntu, the following packages are required:
- - libdb-dev (optional)
- - protobuf-compiler
- - libprotobuf-dev
- - libgoogle-perftools-dev
- - libboost-system-dev
- - libboost-thread-dev
- - libboost-dev
- - (libuv needs to be installed from sources - see
- https://github.com/joyent/libuv)
-
-For Windows, precompiled dependencies are available here:
-https://github.com/cruppstahl/hamsterdb-alien
-
-7. Testing and Example Code
-
-Make automatically compiles several example programs in the directory
-'samples'. To see hamsterdb in action, just run 'samples/db1'
-or any other sample. (or 'win32/out/samples/db1/db1.exe' on Windows platforms).
-
-8. API Documentation
-
-The header files in 'include/ham' have extensive comments. Also, a doxygen
-script is available; run 'make doc' to start doxygen. The generated
-documentation is also available on the hamsterdb web page.
-
-9. Other Ways to Compile hamsterdb
-
-If you want to compile hamsterdb without using the provided ./configure
-environment, you have to set some preprocessor macros:
-
-DEBUG enable debugging output and diagnostic checks (slow!)
-HAM_32BIT compile for 32bit (alias: WIN32)
-HAM_64BIT compile for 64bit (alias: WIN64, also needs WIN32)
-
-Also, if you compile for windows, you have to compile the file
-'src/os_win32.cc' and ignore the file 'src/os_posix.cc'. Vice versa on
-non-Windows platforms.
-
-10. Porting hamsterdb
-
-Porting hamsterdb shouldn't be too difficult. All operating
-system dependend functions are declared in 'src/os.h' and defined
-in 'src/os_win32.cc' or 'src/os_posix.cc'.
-Other compiler- and OS-specific macros are in 'include/ham/types.h'.
-Most likely, these are the only files which have to be touched. Also see item
-9) for important macros.
-
-11. Migrating files from older versions
-
-Usually, hamsterdb releases are backwards compatible. There are some exceptions,
-though. In this case tools are provided to migrate the database. First, export
-your existing database with ham_export linked against the old version.
-(ham_export links statically and will NOT be confused if your system has a
-newer version of hamsterdb installed). Then use the newest version of
-ham_import to import the data into a new database. You can find ham_export
-and ham_import in the "tools" subdirectory.
-
- Example (ham_export of 2.1.2 was renamed to ham_export-2.1.2 to document
- that it's an older version):
-
- ham_export-2.1.2 input.db | ham_import --stdin output.db
-
-12. Licensing
-
-hamsterdb is released under the APL 2.0 license, which allows
-unrestricted use for commercial and non-commercial applications. See the
-file COPYING for more information.
-
-A commercial, closed source version hamsterdb pro with additional functionality
-is available on request. See http://hamsterdb.com for more information.
-
-13. Contact
-
-Author of hamsterdb is
- Christoph Rupp
- Paul-Preuss-Str. 63
- 80995 Muenchen/Germany
- email: chris@crupp.de
- web: http://www.hamsterdb.com
-
-14. Other Copyrights
-
-The Google Protocol Buffers ("protobuf") library is Copyright 2008, Google Inc.
-It has the following license:
-
- Copyright 2008, Google Inc.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Code generated by the Protocol Buffer compiler is owned by the owner
- of the input file used when generating it. This code is not
- standalone and requires a support library to be linked with it. This
- support library is itself covered by the above license.
-
-The libuv library is part of the Node project: http://nodejs.org/
-libuv may be distributed alone under Node's license:
-
- Copyright Joyent, Inc. and other Node contributors. All rights reserved.
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to
- deal in the Software without restriction, including without limitation the
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- sell copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- IN THE SOFTWARE.
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/config.h b/plugins/Dbx_kv/src/hamsterdb/config.h
deleted file mode 100644
index d1fbc4d2f5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/config.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#define _CRT_SECURE_NO_WARNINGS
-
-#define HAM_EXPORT
-
-#define BOOST_SYSTEM_NO_DEPRECATED
-
-#define HAVE_MMAP 1
-#define HAVE_UNMMAP 1
-
-#pragma warning(disable:4100 4127 4512) \ No newline at end of file
diff --git a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb.h b/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb.h
deleted file mode 100644
index 668cfc7cde..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb.h
+++ /dev/null
@@ -1,2535 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file hamsterdb.h
- * @brief Include file for hamsterdb Embedded Storage
- * @author Christoph Rupp, chris@crupp.de
- * @version 2.1.10
- *
- * @mainpage
- *
- * This manual documents the hamsterdb C API. hamsterdb is a key/value database
- * that is linked directly into your application, avoiding all the overhead
- * that is related to external databases and RDBMS systems.
- *
- * This header file declares all functions and macros that are needed to use
- * hamsterdb. The comments are formatted in Doxygen style and can be extracted
- * to automagically generate documentation. The documentation is also available
- * online here: <a href="http://hamsterdb.com/public/scripts/html_www">
- http://hamsterdb.com/public/scripts/html_www</a>.
- *
- * In addition, there's a tutorial book hosted on github:
- * <a href="http://github.com/cruppstahl/hamsterdb/wiki/Tutorial">
- http://github.com/cruppstahl/hamsterdb/wiki/Tutorial</a>.
- *
- * If you want to create or open Databases or Environments (a collection of
- * multiple Databases), the following functions will be interesting for you:
- * <table>
- * <tr><td>@ref ham_env_create</td><td>Creates an Environment</td></tr>
- * <tr><td>@ref ham_env_open</td><td>Opens an Environment</td></tr>
- * <tr><td>@ref ham_env_close</td><td>Closes an Environment</td></tr>
- * <tr><td>@ref ham_env_create_db</td><td>Creates a Database in an
- Environment</td></tr>
- * <tr><td>@ref ham_env_open_db</td><td>Opens a Database from an
- Environment</td></tr>
- * <tr><td>@ref ham_db_close</td><td>Closes a Database</td></tr>
- * </table>
- *
- * To insert, lookup or delete key/value pairs, the following functions are
- * used:
- * <table>
- * <tr><td>@ref ham_db_insert</td><td>Inserts a key/value pair into a
- Database</td></tr>
- * <tr><td>@ref ham_db_find</td><td>Lookup of a key/value pair in a
- Database</td></tr>
- * <tr><td>@ref ham_db_erase</td><td>Erases a key/value pair from a
- Database</td></tr>
- * </table>
- *
- * Alternatively, you can use Cursors to iterate over a Database:
- * <table>
- * <tr><td>@ref ham_cursor_create</td><td>Creates a new Cursor</td></tr>
- * <tr><td>@ref ham_cursor_find</td><td>Positions the Cursor on a key</td></tr>
- * <tr><td>@ref ham_cursor_insert</td><td>Inserts a new key/value pair with a
- Cursor</td></tr>
- * <tr><td>@ref ham_cursor_erase</td><td>Deletes the key/value pair that
- the Cursor points to</td></tr>
- * <tr><td>@ref ham_cursor_overwrite</td><td>Overwrites the value of the current key</td></tr>
- * <tr><td>@ref ham_cursor_move</td><td>Moves the Cursor to the first, next,
- previous or last key in the Database</td></tr>
- * <tr><td>@ref ham_cursor_close</td><td>Closes the Cursor</td></tr>
- * </table>
- *
- * If you want to use Transactions, then the following functions are required:
- * <table>
- * <tr><td>@ref ham_txn_begin</td><td>Begins a new Transaction</td></tr>
- * <tr><td>@ref ham_txn_commit</td><td>Commits the current
- Transaction</td></tr>
- * <tr><td>@ref ham_txn_abort</td><td>Aborts the current Transaction</td></tr>
- * </table>
- *
- * hamsterdb supports remote Databases. The server can be embedded
- * into your application or run standalone (see tools/hamzilla for a Unix
- * daemon or Win32 service which hosts Databases). If you want to embed the
- * server then the following functions have to be used:
- * <table>
- * <tr><td>@ref ham_srv_init</td><td>Initializes the server</td></tr>
- * <tr><td>@ref ham_srv_add_env</td><td>Adds an Environment to the
- server. The Environment with all its Databases will then be available
- remotely.</td></tr>
- * <tr><td>@ref ham_srv_close</td><td>Closes the server and frees all allocated
- resources</td></tr>
- * </table>
- *
- * If you need help then you're always welcome to use the <a
- href="https://groups.google.com/forum/?fromgroups#!forum/hamsterdb-user">
- mailing list</a>,
- * drop a message (chris at crupp dot de) or use the <a
- href="http://hamsterdb.com/index/contact">contact form</a>.
- *
- * Have fun!
- */
-
-#ifndef HAM_HAMSTERDB_H
-#define HAM_HAMSTERDB_H
-
-#include <ham/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* deprecated */
-#define HAM_API_REVISION 3
-
-/**
- * The version numbers
- *
- * @remark A change of the major revision means a significant update
- * with a lot of new features and API changes.
- *
- * The minor version means a significant update without API changes, and the
- * revision is incremented for each release with minor improvements only.
- *
- * The file version describes the version of the binary database format.
- * hamsterdb is neither backwards- nor forwards-compatible regarding file
- * format changes.
- *
- * If a file was created with hamsterdb pro then the msb of the file version
- * is set. hamsterdb pro is able to open files created with hamsterdb (APL
- * version), but not vice versa.
- *
- * History of file versions:
- * 2.1.0: introduced the file version; version is 0
- * 2.1.3: new btree format, file format cleanups; version is 1
- * 2.1.4: new btree format for duplicate keys/var. length keys; version is 2
- * 2.1.5: new freelist; version is 3
- * 2.1.10: changes in btree node format; version is 4
- */
-#define HAM_VERSION_MAJ 2
-#define HAM_VERSION_MIN 1
-#define HAM_VERSION_REV 10
-#define HAM_FILE_VERSION 4
-
-/**
- * The hamsterdb Database structure
- *
- * This structure is allocated in @ref ham_env_create_db and
- * @ref ham_env_open_db. It is deleted in @a ham_db_close.
- */
-struct ham_db_t;
-typedef struct ham_db_t ham_db_t;
-
-/**
- * The hamsterdb Environment structure
- *
- * This structure is allocated with @ref ham_env_create and @ref ham_env_open
- * and is deleted in @ref ham_env_close.
- */
-struct ham_env_t;
-typedef struct ham_env_t ham_env_t;
-
-/**
- * A Database Cursor
- *
- * A Cursor is used for bi-directionally traversing the Database and
- * for inserting/deleting/searching Database items.
- *
- * This structure is allocated with @ref ham_cursor_create and deleted with
- * @ref ham_cursor_close.
- */
-struct ham_cursor_t;
-typedef struct ham_cursor_t ham_cursor_t;
-
-/**
- * A generic record.
- *
- * A record represents data items in hamsterdb. Before using a record, it
- * is important to initialize all record fields with zeroes, i.e. with
- * the C library routines memset(3) or bzero(2).
- *
- * When hamsterdb returns a record structure, the pointer to the record
- * data is provided in @a data. This pointer is only temporary and will be
- * overwritten by subsequent hamsterdb API calls using the same Transaction
- * (or, if Transactions are disabled, using the same Database). The pointer
- * will also be invalidated after the Transaction is aborted or committed.
- *
- * To avoid this, the calling application can allocate the @a data pointer.
- * In this case, you have to set the flag @ref HAM_RECORD_USER_ALLOC. The
- * @a size parameter will then return the size of the record. It's the
- * responsibility of the caller to make sure that the @a data parameter is
- * large enough for the record.
- *
- * The record->data pointer is not threadsafe. For threadsafe access it is
- * recommended to use @a HAM_RECORD_USER_ALLOC or have each thread manage its
- * own Transaction.
- */
-typedef struct {
- /** The size of the record data, in bytes */
- uint32_t size;
-
- /** Pointer to the record data */
- void *data;
-
- /** The record flags; see @ref HAM_RECORD_USER_ALLOC */
- uint32_t flags;
-
- /** Offset for partial reading/writing; see @ref HAM_PARTIAL */
- uint32_t partial_offset;
-
- /** Size for partial reading/writing; see @ref HAM_PARTIAL */
- uint32_t partial_size;
-
-} ham_record_t;
-
-/** Flag for @ref ham_record_t (only really useful in combination with
- * @ref ham_cursor_move, @ref ham_cursor_find and @ref ham_db_find)
- */
-#define HAM_RECORD_USER_ALLOC 1
-
-/**
- * A macro to statically initialize a @ref ham_record_t structure.
- *
- * Usage:
- * ham_record_t rec = ham_make_record(ptr, size);
- */
-#define ham_make_record(PTR, SIZE) { SIZE, PTR, 0 }
-
-/**
- * A generic key.
- *
- * A key represents key items in hamsterdb. Before using a key, it
- * is important to initialize all key fields with zeroes, i.e. with
- * the C library routines memset(3) or bzero(2).
- *
- * hamsterdb usually uses keys to insert, delete or search for items.
- * However, when using Database Cursors and the function @ref ham_cursor_move,
- * hamsterdb also returns keys. In this case, the pointer to the key
- * data is provided in @a data. This pointer is only temporary and will be
- * overwritten by subsequent calls to @ref ham_cursor_move using the
- * same Transaction (or, if Transactions are disabled, using the same Database).
- * The pointer will also be invalidated after the Transaction is aborted
- * or committed.
- *
- * To avoid this, the calling application can allocate the @a data pointer.
- * In this case, you have to set the flag @ref HAM_KEY_USER_ALLOC. The
- * @a size parameter will then return the size of the key. It's the
- * responsibility of the caller to make sure that the @a data parameter is
- * large enough for the key.
- *
- * The key->data pointer is not threadsafe. For threadsafe access it is
- * recommended to use @a HAM_KEY_USER_ALLOC or have each thread manage its
- * own Transaction.
- */
-typedef struct {
- /** The size of the key, in bytes */
- uint16_t size;
-
- /** The data of the key */
- void *data;
-
- /** The key flags; see @ref HAM_KEY_USER_ALLOC */
- uint32_t flags;
-
- /** For internal use */
- uint32_t _flags;
-
-} ham_key_t;
-
-/**
- * A macro to statically initialize a @ref ham_key_t structure.
- *
- * Usage:
- * ham_key_t key = ham_make_key(ptr, size);
- */
-#define ham_make_key(PTR, SIZE) { SIZE, PTR, 0 }
-
-/** Flag for @ref ham_key_t (only really useful in combination with
- * @ref ham_cursor_move, @ref ham_cursor_find and @ref ham_db_find)
- */
-#define HAM_KEY_USER_ALLOC 1
-
-/**
- * A named parameter.
- *
- * These parameter structures are used for functions like @ref ham_env_open,
- * @ref ham_env_create, etc. to pass variable length parameter lists.
- *
- * The lists are always arrays of type ham_parameter_t, with a terminating
- * element of { 0, NULL}, e.g.
- *
- * <pre>
- * ham_parameter_t parameters[] = {
- * { HAM_PARAM_CACHE_SIZE, 2 * 1024 * 1024 }, // set cache size to 2 mb
- * { HAM_PARAM_PAGE_SIZE, 4096 }, // set page size to 4 kb
- * { 0, NULL }
- * };
- * </pre>
- */
-typedef struct {
- /** The name of the parameter; all HAM_PARAM_*-constants */
- uint32_t name;
-
- /** The value of the parameter. */
- uint64_t value;
-
-} ham_parameter_t;
-
-
-/**
- * @defgroup ham_key_types hamsterdb Key Types
- * @{
- */
-
-/** A binary blob without type; sorted by memcmp */
-#define HAM_TYPE_BINARY 0
-/** A binary blob without type; sorted by callback function */
-#define HAM_TYPE_CUSTOM 1
-/** An unsigned 8-bit integer */
-#define HAM_TYPE_UINT8 3
-/** An unsigned 16-bit integer */
-#define HAM_TYPE_UINT16 5
-/** An unsigned 32-bit integer */
-#define HAM_TYPE_UINT32 7
-/** An unsigned 64-bit integer */
-#define HAM_TYPE_UINT64 9
-/** An 32-bit float */
-#define HAM_TYPE_REAL32 11
-/** An 64-bit double */
-#define HAM_TYPE_REAL64 12
-
-/**
- * @}
- */
-
-
-/**
- * @defgroup ham_status_codes hamsterdb Status Codes
- * @{
- */
-
-/** Operation completed successfully */
-#define HAM_SUCCESS ( 0)
-/** Invalid record size */
-#define HAM_INV_RECORD_SIZE ( -2)
-/** Invalid key size */
-#define HAM_INV_KEY_SIZE ( -3)
-/* deprecated */
-#define HAM_INV_KEYSIZE HAM_INV_KEY_SIZE
-/** Invalid page size (must be 1024 or a multiple of 2048) */
-#define HAM_INV_PAGE_SIZE ( -4)
-/* deprecated */
-#define HAM_INV_PAGESIZE HAM_INV_PAGE_SIZE
-/** Memory allocation failed - out of memory */
-#define HAM_OUT_OF_MEMORY ( -6)
-/** Invalid function parameter */
-#define HAM_INV_PARAMETER ( -8)
-/** Invalid file header */
-#define HAM_INV_FILE_HEADER ( -9)
-/** Invalid file version */
-#define HAM_INV_FILE_VERSION (-10)
-/** Key was not found */
-#define HAM_KEY_NOT_FOUND (-11)
-/** Tried to insert a key which already exists */
-#define HAM_DUPLICATE_KEY (-12)
-/** Internal Database integrity violated */
-#define HAM_INTEGRITY_VIOLATED (-13)
-/** Internal hamsterdb error */
-#define HAM_INTERNAL_ERROR (-14)
-/** Tried to modify the Database, but the file was opened as read-only */
-#define HAM_WRITE_PROTECTED (-15)
-/** Database record not found */
-#define HAM_BLOB_NOT_FOUND (-16)
-/** Generic file I/O error */
-#define HAM_IO_ERROR (-18)
-/** Function is not yet implemented */
-#define HAM_NOT_IMPLEMENTED (-20)
-/** File not found */
-#define HAM_FILE_NOT_FOUND (-21)
-/** Operation would block */
-#define HAM_WOULD_BLOCK (-22)
-/** Object was not initialized correctly */
-#define HAM_NOT_READY (-23)
-/** Database limits reached */
-#define HAM_LIMITS_REACHED (-24)
-/** Object was already initialized */
-#define HAM_ALREADY_INITIALIZED (-27)
-/** Database needs recovery */
-#define HAM_NEED_RECOVERY (-28)
-/** Cursor must be closed prior to Transaction abort/commit */
-#define HAM_CURSOR_STILL_OPEN (-29)
-/** Record filter or file filter not found */
-#define HAM_FILTER_NOT_FOUND (-30)
-/** Operation conflicts with another Transaction */
-#define HAM_TXN_CONFLICT (-31)
-/* internal use: key was erased in a Transaction */
-#define HAM_KEY_ERASED_IN_TXN (-32)
-/** Database cannot be closed because it is modified in a Transaction */
-#define HAM_TXN_STILL_OPEN (-33)
-/** Cursor does not point to a valid item */
-#define HAM_CURSOR_IS_NIL (-100)
-/** Database not found */
-#define HAM_DATABASE_NOT_FOUND (-200)
-/** Database name already exists */
-#define HAM_DATABASE_ALREADY_EXISTS (-201)
-/** Database already open, or: Database handle is already initialized */
-#define HAM_DATABASE_ALREADY_OPEN (-202)
-/** Environment already open, or: Environment handle is already initialized */
-#define HAM_ENVIRONMENT_ALREADY_OPEN (-203)
-/** Invalid log file header */
-#define HAM_LOG_INV_FILE_HEADER (-300)
-/** Remote I/O error/Network error */
-#define HAM_NETWORK_ERROR (-400)
-
-/**
- * @}
- */
-
-
-/**
- * @defgroup ham_static hamsterdb Static Functions
- * @{
- */
-
-/**
- * A typedef for a custom error handler function
- *
- * This error handler can be used in combination with
- * @ref ham_set_errhandler().
- *
- * @param message The error message
- * @param level The error level:
- * <ul>
- * <li>@ref HAM_DEBUG_LEVEL_DEBUG (0) </li> a debug message
- * <li>@ref HAM_DEBUG_LEVEL_NORMAL (1) </li> a normal error message
- * <li>2</li> reserved
- * <li>@ref HAM_DEBUG_LEVEL_FATAL (3) </li> a fatal error message
- * </ul>
- *
- * @sa error_levels
- */
-typedef void HAM_CALLCONV (*ham_errhandler_fun)(int level, const char *message);
-
-/** A debug message */
-#define HAM_DEBUG_LEVEL_DEBUG 0
-
-/** A normal error message */
-#define HAM_DEBUG_LEVEL_NORMAL 1
-
-/** A fatal error message */
-#define HAM_DEBUG_LEVEL_FATAL 3
-
-/**
- * Sets the global error handler
- *
- * This handler will receive all debug messages that are emitted
- * by hamsterdb. You can install the default handler by setting @a f to 0.
- *
- * The default error handler prints all messages to stderr. To install a
- * different logging facility, you can provide your own error handler.
- *
- * Note that the callback function must have the same calling convention
- * as the hamsterdb library.
- *
- * @param f A pointer to the error handler function, or NULL to restore
- * the default handler
- */
-HAM_EXPORT void HAM_CALLCONV
-ham_set_errhandler(ham_errhandler_fun f);
-
-/**
- * Translates a hamsterdb status code to a descriptive error string
- *
- * @param status The hamsterdb status code
- *
- * @return A pointer to a descriptive error string
- */
-HAM_EXPORT const char * HAM_CALLCONV
-ham_strerror(ham_status_t status);
-
-/**
- * Returns the version of the hamsterdb library
- *
- * @param major If not NULL, will return the major version number
- * @param minor If not NULL, will return the minor version number
- * @param revision If not NULL, will return the revision version number
- */
-HAM_EXPORT void HAM_CALLCONV
-ham_get_version(uint32_t *major, uint32_t *minor,
- uint32_t *revision);
-
-/**
- * @}
- */
-
-
-/**
- * @defgroup ham_env hamsterdb Environment Functions
- * @{
- */
-
-/**
- * Creates a Database Environment
- *
- * A Database Environment is a collection of Databases, which are all stored
- * in one physical file (or in-memory). The maximum number of Databases
- * depends on the page size; the default is above 600.
- *
- * Each Database in an Environment is identified by a positive 16bit
- * value (except 0 and values at or above 0xf000).
- * Databases in an Environment can be created with @ref ham_env_create_db
- * or opened with @ref ham_env_open_db.
- *
- * Specify a URL instead of a filename (i.e.
- * "ham://localhost:8080/customers.db") to access a remote hamsterdb Server.
- *
- * To enable ACID Transactions, supply the flag @ref HAM_ENABLE_TRANSACTIONS.
- * By default, hamsterdb will use a Journal for recovering the Environment
- * and its data in case of a crash, and also to re-apply committed Transactions
- * which were not yet flushed to disk. This Journalling can be disabled
- * with the flag @ref HAM_DISABLE_RECOVERY. (It is disabled if the Environment
- * is in-memory.)
- *
- * If Transactions are not required, but hamsterdb should still be able to
- * recover in case of a crash or power outage, then the flag
- * @ref HAM_ENABLE_RECOVERY will enable the Journal (without allowing
- * Transactions.)
- *
- * For performance reasons the Journal does not use fsync(2) (or
- * FlushFileBuffers on Win32) to flush modified buffers to disk. Use the flag
- * @ref HAM_ENABLE_FSYNC to force the use of fsync.
- *
- * @param env A pointer to an Environment handle
- * @param filename The filename of the Environment file. If the file already
- * exists, it is overwritten. Can be NULL for an In-Memory
- * Environment. Can be a URL ("ham://<hostname>:<port>/<environment>")
- * for remote access.
- * @param flags Optional flags for opening the Environment, combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_ENABLE_FSYNC</li> Flushes all file handles after
- * committing or aborting a Transaction using fsync(), fdatasync()
- * or FlushFileBuffers(). This file has no effect
- * if Transactions are disabled. Slows down performance but makes
- * sure that all file handles and operating system caches are
- * transferred to disk, thus providing a stronger durability.
- * <li>@ref HAM_IN_MEMORY</li> Creates an In-Memory Environment. No
- * file will be created, and the Database contents are lost after
- * the Environment is closed. The @a filename parameter can
- * be NULL. Do <b>NOT</b> specify @a cache_size other than 0.
- * <li>@ref HAM_DISABLE_MMAP</li> Do not use memory mapped files for I/O.
- * By default, hamsterdb checks if it can use mmap,
- * since mmap is faster than read/write. For performance
- * reasons, this flag should not be used.
- * <li>@ref HAM_CACHE_UNLIMITED</li> Do not limit the cache. Nearly as
- * fast as an In-Memory Database. Not allowed in combination
- * with a limited cache size.
- * <li>@ref HAM_ENABLE_TRANSACTIONS</li> Enables Transactions for this
- * Environment. This flag implies @ref HAM_ENABLE_RECOVERY.
- * <li>@ref HAM_ENABLE_RECOVERY</li> Enables logging/recovery for this
- * Environment. Not allowed in combination with @ref HAM_IN_MEMORY.
- * <li>@ref HAM_DISABLE_RECOVERY</li> Disables logging/recovery for this
- * Environment.
- * <li>@ref HAM_FLUSH_WHEN_COMMITTED</li> Immediately flushes committed
- * Transactions and writes them to the Btree. Disabled by default. If
- * disabled then hamsterdb buffers committed Transactions and only starts
- * flushing when too many Transactions were committed.
- * </ul>
- *
- * @param mode File access rights for the new file. This is the @a mode
- * parameter for creat(2). Ignored on Microsoft Windows. Default
- * is 0644.
- * @param param An array of ham_parameter_t structures. The following
- * parameters are available:
- * <ul>
- * <li>@ref HAM_PARAM_CACHE_SIZE</li> The size of the Database cache,
- * in bytes. The default size is defined in src/config.h
- * as @a HAM_DEFAULT_CACHE_SIZE - usually 2MB
- * <li>@ref HAM_PARAM_POSIX_FADVISE</li> Sets the "advice" for
- * posix_fadvise(). Only on supported platforms. Allowed values are
- * @ref HAM_POSIX_FADVICE_NORMAL (which is the default) or
- * @ref HAM_POSIX_FADVICE_RANDOM.
- * <li>@ref HAM_PARAM_PAGE_SIZE</li> The size of a file page, in
- * bytes. It is recommended not to change the default size. The
- * default size depends on hardware and operating system.
- * Page sizes must be 1024 or a multiple of 2048.
- * <li>@ref HAM_PARAM_FILE_SIZE_LIMIT</li> Sets a file size limit (in bytes).
- * Disabled by default. Not allowed in combination with @ref HAM_IN_MEMORY.
- * If the limit is exceeded, API functions return @ref HAM_LIMITS_REACHED.
- * <li>@ref HAM_PARAM_LOG_DIRECTORY</li> The path of the log file
- * and the journal files; default is the same path as the database
- * file. Ignored for remote Environments.
- * <li>@ref HAM_PARAM_NETWORK_TIMEOUT_SEC</li> Timeout (in seconds) when
- * waiting for data from a remote server. By default, no timeout is set.
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if the @a env pointer is NULL or an
- * invalid combination of flags or parameters was specified
- * @return @ref HAM_IO_ERROR if the file could not be opened or
- * reading/writing failed
- * @return @ref HAM_INV_FILE_VERSION if the Environment version is not
- * compatible with the library version
- * @return @ref HAM_OUT_OF_MEMORY if memory could not be allocated
- * @return @ref HAM_INV_PAGE_SIZE if @a page_size is not 1024 or
- * a multiple of 2048
- * @return @ref HAM_INV_KEY_SIZE if @a key_size is too large (at least 4
- * keys must fit in a page)
- * @return @ref HAM_WOULD_BLOCK if another process has locked the file
- * @return @ref HAM_ENVIRONMENT_ALREADY_OPEN if @a env is already in use
- *
- * @sa ham_env_create
- * @sa ham_env_close
- * @sa ham_env_open
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_create(ham_env_t **env, const char *filename,
- uint32_t flags, uint32_t mode, const ham_parameter_t *param);
-
-/**
- * Opens an existing Database Environment
- *
- * This function opens an existing Database Environment.
- *
- * A Database Environment is a collection of Databases, which are all stored
- * in one physical file (or in-memory).
- *
- * Each Database in an Environment is identified by a positive 16bit
- * value (except 0 and values at or above 0xf000).
- * Databases in an Environment can be created with @ref ham_env_create_db
- * or opened with @ref ham_env_open_db.
- *
- * Specify a URL instead of a filename (i.e.
- * "ham://localhost:8080/customers.db") to access a remote hamsterdb Server.
- *
- * Also see the documentation @ref ham_env_create about Transactions, Recovery
- * and the use of fsync.
- *
- * @param env A valid Environment handle
- * @param filename The filename of the Environment file, or URL of a hamsterdb
- * Server
- * @param flags Optional flags for opening the Environment, combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_READ_ONLY </li> Opens the file for reading only.
- * Operations that need write access (i.e. @ref ham_db_insert) will
- * return @ref HAM_WRITE_PROTECTED.
- * <li>@ref HAM_ENABLE_FSYNC</li> Flushes all file handles after
- * committing or aborting a Transaction using fsync(), fdatasync()
- * or FlushFileBuffers(). This file has no effect
- * if Transactions are disabled. Slows down performance but makes
- * sure that all file handles and operating system caches are
- * transferred to disk, thus providing a stronger durability.
- * <li>@ref HAM_DISABLE_MMAP </li> Do not use memory mapped files for I/O.
- * By default, hamsterdb checks if it can use mmap,
- * since mmap is faster than read/write. For performance
- * reasons, this flag should not be used.
- * <li>@ref HAM_CACHE_UNLIMITED </li> Do not limit the cache. Nearly as
- * fast as an In-Memory Database. Not allowed in combination
- * with a limited cache size.
- * <li>@ref HAM_ENABLE_TRANSACTIONS </li> Enables Transactions for this
- * Environment. This flag imples @ref HAM_ENABLE_RECOVERY.
- * <li>@ref HAM_ENABLE_RECOVERY </li> Enables logging/recovery for this
- * Environment. Will return @ref HAM_NEED_RECOVERY, if the Environment
- * is in an inconsistent state. Not allowed in combination
- * with @ref HAM_IN_MEMORY.
- * <li>@ref HAM_DISABLE_RECOVERY</li> Disables logging/recovery for this
- * Environment.
- * <li>@ref HAM_AUTO_RECOVERY </li> Automatically recover the Environment,
- * if necessary. This flag implies @ref HAM_ENABLE_RECOVERY.
- * <li>@ref HAM_FLUSH_WHEN_COMMITTED</li> Immediately flushes committed
- * Transactions and writes them to the Btree. Disabled by default. If
- * disabled then hamsterdb buffers committed Transactions and only starts
- * flushing when too many Transactions were committed.
- * </ul>
- * @param param An array of ham_parameter_t structures. The following
- * parameters are available:
- * <ul>
- * <li>@ref HAM_PARAM_CACHE_SIZE </li> The size of the Database cache,
- * in bytes. The default size is defined in src/config.h
- * as @a HAM_DEFAULT_CACHE_SIZE - usually 2MB
- * <li>@ref HAM_PARAM_POSIX_FADVISE</li> Sets the "advice" for
- * posix_fadvise(). Only on supported platforms. Allowed values are
- * @ref HAM_POSIX_FADVICE_NORMAL (which is the default) or
- * @ref HAM_POSIX_FADVICE_RANDOM.
- * <li>@ref HAM_PARAM_FILE_SIZE_LIMIT</li> Sets a file size limit (in bytes).
- * Disabled by default. If the limit is exceeded, API functions
- * return @ref HAM_LIMITS_REACHED.
- * <li>@ref HAM_PARAM_LOG_DIRECTORY</li> The path of the log file
- * and the journal files; default is the same path as the database
- * file. Ignored for remote Environments.
- * <li>@ref HAM_PARAM_NETWORK_TIMEOUT_SEC</li> Timeout (in seconds) when
- * waiting for data from a remote server. By default, no timeout is set.
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success.
- * @return @ref HAM_INV_PARAMETER if the @a env pointer is NULL, an
- * invalid combination of flags was specified
- * @return @ref HAM_FILE_NOT_FOUND if the file does not exist
- * @return @ref HAM_IO_ERROR if the file could not be opened or reading failed
- * @return @ref HAM_INV_FILE_VERSION if the Environment version is not
- * compatible with the library version.
- * @return @ref HAM_OUT_OF_MEMORY if memory could not be allocated
- * @return @ref HAM_WOULD_BLOCK if another process has locked the file
- * @return @ref HAM_NEED_RECOVERY if the Database is in an inconsistent state
- * @return @ref HAM_LOG_INV_FILE_HEADER if the logfile is corrupt
- * @return @ref HAM_ENVIRONMENT_ALREADY_OPEN if @a env is already in use
- * @return @ref HAM_NETWORK_ERROR if a remote server is not reachable
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_open(ham_env_t **env, const char *filename,
- uint32_t flags, const ham_parameter_t *param);
-
-/**
- * Retrieve the current value for a given Environment setting
- *
- * Only those values requested by the parameter array will be stored.
- *
- * The following parameters are supported:
- * <ul>
- * <li>HAM_PARAM_CACHE_SIZE</li> returns the cache size
- * <li>HAM_PARAM_PAGE_SIZE</li> returns the page size
- * <li>HAM_PARAM_MAX_DATABASES</li> returns the max. number of
- * Databases of this Database's Environment
- * <li>HAM_PARAM_FLAGS</li> returns the flags which were used to
- * open or create this Database
- * <li>HAM_PARAM_FILEMODE</li> returns the @a mode parameter which
- * was specified when creating this Database
- * <li>HAM_PARAM_FILENAME</li> returns the filename (the @a value
- * of this parameter is a const char * pointer casted to a
- * uint64_t variable)
- * <li>@ref HAM_PARAM_LOG_DIRECTORY</li> The path of the log file
- * and the journal files. Ignored for remote Environments.
- * <li>@ref HAM_PARAM_JOURNAL_COMPRESSION</li> Returns the
- * selected algorithm for journal compression, or 0 if compression
- * is disabled
- * </ul>
- *
- * @param env A valid Environment handle
- * @param param An array of ham_parameter_t structures
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if the @a env pointer is NULL or
- * @a param is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_get_parameters(ham_env_t *env, ham_parameter_t *param);
-
-/**
- * Creates a new Database in a Database Environment
- *
- * An Environment can contain a (limited) amount of Databases; the exact
- * limit depends on the page size and is above 600.
- *
- * Each Database in an Environment is identified by a positive 16bit
- * value. 0 and values at or above 0xf000 are reserved.
- *
- * This function initializes the ham_db_t handle (the second parameter).
- * When the handle is no longer in use, it should be closed with
- * @ref ham_db_close. Alternatively, the Database handle is closed
- * automatically if @ref ham_env_close is called with the flag
- * @ref HAM_AUTO_CLEANUP.
- *
- * A Database can (and should) be configured and optimized for the data that
- * is inserted. The data is described through flags and parameters. hamsterdb
- * differentiates between several data characteristics, and offers predefined
- * "types" to describe the keys. In general, the default key type
- * (@ref HAM_TYPE_BINARY) is slower than the other types, and
- * fixed-length binary keys (@ref HAM_TYPE_BINARY in combination with
- * @ref HAM_PARAM_KEY_SIZE) is faster than variable-length binary
- * keys. It is therefore recommended to always set the key size and record size,
- * although it is not required.
- *
- * Internally, hamsterdb uses two different layouts ("default" and "pax)
- * depending on the settings specified by the user. The "default" layout
- * is enabled for variable-length keys or if duplicate keys are enabled.
- * For fixed-length keys (without duplicates) the "pax" layout is chosen.
- * The "pax" layout is more compact and usually faster.
- *
- * A word of warning regarding the use of fixed length binary keys
- * (@ref HAM_TYPE_CUSTOM or @ref HAM_TYPE_BINARY in combination with
- * @ref HAM_PARAM_KEY_SIZE): if your key size is too large, only few keys
- * will fit in a Btree node. The Btree fanout will be very high, which will
- * decrease performance. In such cases it might be better to NOT specify
- * the key size; then hamsterdb will store keys as blobs if they are too large.
- *
- * See the Wiki documentation for <a href=
- "https://github.com/cruppstahl/hamsterdb/wiki/Evaluating-and-Benchmarking">
- * Evaluating and Benchmarking</a> on how to test different configurations and
- * optimize for performance.
- *
- * The key type is set with @ref HAM_PARAM_KEY_TYPE and can have either
- * of the following values:
- *
- * <ul>
- * <li>HAM_TYPE_BINARY</li> This is the default key type: a binary blob.
- * Internally, hamsterdb uses memcmp(3) for the sort order. Key size depends
- * on @ref HAM_PARAM_KEY_SIZE and is unlimited (@ref HAM_KEY_SIZE_UNLIMITED)
- * by default.
- * <li>HAM_TYPE_CUSTOM</li> Similar to @ref HAM_TYPE_BINARY, but
- * uses a callback function for the sort order. This function is supplied
- * by the application with @sa ham_db_set_compare_func.
- * <li>HAM_TYPE_UINT8</li> Key is a 8bit (1 byte) unsigned integer
- * <li>HAM_TYPE_UINT16</li> Key is a 16bit (2 byte) unsigned integer
- * <li>HAM_TYPE_UINT32</li> Key is a 32bit (4 byte) unsigned integer
- * <li>HAM_TYPE_UINT64</li> Key is a 64bit (8 byte) unsigned integer
- * <li>HAM_TYPE_REAL32</li> Key is a 32bit (4 byte) float
- * <li>HAM_TYPE_REAL64</li> Key is a 64bit (8 byte) double
- * </ul>
- *
- * If the key type is ommitted then @ref HAM_TYPE_BINARY is the default.
- *
- * If binary/custom keys are so big that they cannot be stored in the Btree,
- * then the full key will be stored in an overflow area, which has
- * performance implications when accessing such keys.
- *
- * In addition to the flags above, you can specify @a HAM_ENABLE_DUPLICATE_KEYS
- * to insert duplicate keys, i.e. to model 1:n or n:m relationships.
- *
- * If the size of the records is always constant, then
- * @ref HAM_PARAM_RECORD_SIZE should be used to specify this size. This allows
- * hamsterdb to optimize the record storage, and small records will
- * automatically be stored in the Btree's leaf nodes instead of a separately
- * allocated blob, allowing faster access.
- * A record size of 0 is valid and suited for boolean values ("key exists"
- * vs "key doesn't exist"). The default record size is
- * @ref HAM_RECORD_SIZE_UNLIMITED.
- *
- * @param env A valid Environment handle.
- * @param db A valid Database handle, which will point to the created
- * Database. To close the handle, use @ref ham_db_close.
- * @param name The name of the Database. If a Database with this name
- * already exists, the function will fail with
- * @ref HAM_DATABASE_ALREADY_EXISTS. Database names from 0xf000 to
- * 0xffff and 0 are reserved.
- * @param flags Optional flags for creating the Database, combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_ENABLE_DUPLICATE_KEYS </li> Enable duplicate keys for this
- * Database. By default, duplicate keys are disabled.
- * <li>@ref HAM_RECORD_NUMBER32 </li> Creates an "auto-increment" Database.
- * Keys in Record Number Databases are automatically assigned an
- * incrementing 32bit value. If key->data is not NULL
- * (and key->flags is @ref HAM_KEY_USER_ALLOC), the value of the current
- * key is returned in @a key. If key-data is NULL and key->size is 0,
- * key->data is temporarily allocated by hamsterdb.
- * <li>@ref HAM_RECORD_NUMBER64 </li> Creates an "auto-increment" Database.
- * Keys in Record Number Databases are automatically assigned an
- * incrementing 64bit value. If key->data is not NULL
- * (and key->flags is @ref HAM_KEY_USER_ALLOC), the value of the current
- * key is returned in @a key. If key-data is NULL and key->size is 0,
- * key->data is temporarily allocated by hamsterdb.
- * </ul>
- *
- * @param params An array of ham_parameter_t structures. The following
- * parameters are available:
- * <ul>
- * <li>@ref HAM_PARAM_KEY_TYPE </li> The type of the keys in the B+Tree
- * index. The default is @ref HAM_TYPE_BINARY. See above for more
- * information.
- * <li>@ref HAM_PARAM_KEY_SIZE </li> The (fixed) size of the keys in
- * the B+Tree index; or @ref HAM_KEY_SIZE_UNLIMITED for unlimited and
- * variable keys (this is the default).
- * <li>@ref HAM_PARAM_RECORD_SIZE </li> The (fixed) size of the records;
- * or @ref HAM_RECORD_SIZE_UNLIMITED if there was no fixed record size
- * specified (this is the default).
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if the @a env pointer is NULL or an
- * invalid combination of flags was specified
- * @return @ref HAM_DATABASE_ALREADY_EXISTS if a Database with this @a name
- * already exists in this Environment
- * @return @ref HAM_OUT_OF_MEMORY if memory could not be allocated
- * @return @ref HAM_LIMITS_REACHED if the maximum number of Databases per
- * Environment was already created
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_create_db(ham_env_t *env, ham_db_t **db,
- uint16_t name, uint32_t flags, const ham_parameter_t *params);
-
-/**
- * Opens a Database in a Database Environment
- *
- * Each Database in an Environment is identified by a positive 16bit
- * value (except 0 and values at or above 0xf000).
- *
- * This function initializes the ham_db_t handle (the second parameter).
- * When the handle is no longer in use, it should be closed with
- * @ref ham_db_close. Alternatively, the Database handle is closed
- * automatically if @ref ham_env_close is called with the flag
- * @ref HAM_AUTO_CLEANUP.
- *
- * @param env A valid Environment handle
- * @param db A valid Database handle, which will point to the opened
- * Database. To close the handle, use @see ham_db_close.
- * @param name The name of the Database. If a Database with this name
- * does not exist, the function will fail with
- * @ref HAM_DATABASE_NOT_FOUND.
- * @param flags Optional flags for opening the Database, combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_READ_ONLY </li> Opens the Database for reading only.
- * Operations that need write access (i.e. @ref ham_db_insert) will
- * return @ref HAM_WRITE_PROTECTED.
- * </ul>
- * @param params Reserved; set to NULL
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if the @a env pointer is NULL or an
- * invalid combination of flags was specified
- * @return @ref HAM_DATABASE_NOT_FOUND if a Database with this @a name
- * does not exist in this Environment.
- * @return @ref HAM_DATABASE_ALREADY_OPEN if this Database was already
- * opened
- * @return @ref HAM_OUT_OF_MEMORY if memory could not be allocated
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_open_db(ham_env_t *env, ham_db_t **db,
- uint16_t name, uint32_t flags, const ham_parameter_t *params);
-
-/**
- * Renames a Database in an Environment.
- *
- * @param env A valid Environment handle.
- * @param oldname The old name of the existing Database. If a Database
- * with this name does not exist, the function will fail with
- * @ref HAM_DATABASE_NOT_FOUND.
- * @param newname The new name of this Database. If a Database
- * with this name already exists, the function will fail with
- * @ref HAM_DATABASE_ALREADY_EXISTS.
- * @param flags Optional flags for renaming the Database, combined with
- * bitwise OR; unused, set to 0.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if the @a env pointer is NULL or if
- * the new Database name is reserved
- * @return @ref HAM_DATABASE_NOT_FOUND if a Database with this @a name
- * does not exist in this Environment
- * @return @ref HAM_DATABASE_ALREADY_EXISTS if a Database with the new name
- * already exists
- * @return @ref HAM_OUT_OF_MEMORY if memory could not be allocated
- * @return @ref HAM_NOT_READY if the Environment @a env was not initialized
- * correctly (i.e. not yet opened or created)
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_rename_db(ham_env_t *env, uint16_t oldname,
- uint16_t newname, uint32_t flags);
-
-/**
- * Deletes a Database from an Environment
- *
- * @param env A valid Environment handle
- * @param name The name of the Database to delete. If a Database
- * with this name does not exist, the function will fail with
- * @ref HAM_DATABASE_NOT_FOUND. If the Database was already opened,
- * the function will fail with @ref HAM_DATABASE_ALREADY_OPEN.
- * @param flags Optional flags for deleting the Database; unused, set to 0.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if the @a env pointer is NULL or if
- * the new Database name is reserved
- * @return @ref HAM_DATABASE_NOT_FOUND if a Database with this @a name
- * does not exist
- * @return @ref HAM_DATABASE_ALREADY_OPEN if a Database with this name is
- * still open
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_erase_db(ham_env_t *env, uint16_t name, uint32_t flags);
-
-/* internal flag - only flush committed transactions, not the btree pages */
-#define HAM_FLUSH_COMMITTED_TRANSACTIONS 1
-
-/**
- * Flushes the Environment
- *
- * This function flushes the Environment caches and writes the whole file
- * to disk. All Databases of this Environment are flushed as well.
- *
- * Since In-Memory Databases do not have a file on disk, the
- * function will have no effect and will return @ref HAM_SUCCESS.
- *
- * @param env A valid Environment handle
- * @param flags Optional flags for flushing; unused, set to 0
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a db is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_flush(ham_env_t *env, uint32_t flags);
-
-/* internal use only - don't lock mutex */
-#define HAM_DONT_LOCK 0xf0000000
-
-/**
- * Returns the names of all Databases in an Environment
- *
- * This function returns the names of all Databases and the number of
- * Databases in an Environment.
- *
- * The memory for @a names must be allocated by the user. @a count
- * must be the size of @a names when calling the function, and will be
- * the number of Databases when the function returns. The function returns
- * @ref HAM_LIMITS_REACHED if @a names is not big enough; in this case, the
- * caller should resize the array and call the function again.
- *
- * @param env A valid Environment handle
- * @param names Pointer to an array for the Database names
- * @param count Pointer to the size of the array; will be used to store the
- * number of Databases when the function returns.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a env, @a names or @a count is NULL
- * @return @ref HAM_LIMITS_REACHED if @a names is not large enough to hold
- * all Database names
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_get_database_names(ham_env_t *env, uint16_t *names,
- uint32_t *count);
-
-/**
- * Closes the Database Environment
- *
- * This function closes the Database Environment. It also frees the
- * memory resources allocated in the @a env handle, and tries to truncate
- * the file (see below).
- *
- * If the flag @ref HAM_AUTO_CLEANUP is specified, hamsterdb automatically
- * calls @ref ham_db_close with flag @ref HAM_AUTO_CLEANUP on all open
- * Databases (which closes all open Databases and their Cursors). This
- * invalidates the ham_db_t and ham_cursor_t handles!
- *
- * If the flag is not specified, the application must close all Database
- * handles with @ref ham_db_close to prevent memory leaks.
- *
- * This function also aborts all Transactions which were not yet committed,
- * and therefore renders all Transaction handles invalid. If the flag
- * @ref HAM_TXN_AUTO_COMMIT is specified, all Transactions will be committed.
- *
- * This function also tries to truncate the file and "cut off" unused space
- * at the end of the file to reduce the file size. This feature is disabled
- * on Win32 if memory mapped I/O is used (see @ref HAM_DISABLE_MMAP).
- *
- * @param env A valid Environment handle
- * @param flags Optional flags for closing the handle. Possible flags are:
- * <ul>
- * <li>@ref HAM_AUTO_CLEANUP. Calls @ref ham_db_close with the flag
- * @ref HAM_AUTO_CLEANUP on every open Database
- * <li>@ref HAM_TXN_AUTO_COMMIT. Automatically commit all open
- * Transactions
- * <li>@ref HAM_TXN_AUTO_ABORT. Automatically abort all open
- * Transactions; this is the default behaviour
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a env is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_close(ham_env_t *env, uint32_t flags);
-
-/**
- * @}
- */
-
-
-/**
- * @defgroup ham_txn hamsterdb Transaction Functions
- * @{
- */
-
-/**
- * The hamsterdb Transaction structure
- *
- * This structure is allocated with @ref ham_txn_begin and deleted with
- * @ref ham_txn_commit or @ref ham_txn_abort.
- */
-struct ham_txn_t;
-typedef struct ham_txn_t ham_txn_t;
-
-/**
- * Begins a new Transaction
- *
- * A Transaction is an atomic sequence of Database operations. With @ref
- * ham_txn_begin such a new sequence is started. To write all operations of this
- * sequence to the Database use @ref ham_txn_commit. To abort and cancel
- * this sequence use @ref ham_txn_abort.
- *
- * In order to use Transactions, the Environment has to be created or
- * opened with the flag @ref HAM_ENABLE_TRANSACTIONS.
- *
- * You can create as many Transactions as you want (older versions of
- * hamsterdb did not allow to create more than one Transaction in parallel).
- *
- * @param txn Pointer to a pointer of a Transaction structure
- * @param env A valid Environment handle
- * @param name An optional Transaction name
- * @param reserved A reserved pointer; always set to NULL
- * @param flags Optional flags for beginning the Transaction, combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_TXN_READ_ONLY </li> This Transaction is read-only and
- * will not modify the Database.
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_OUT_OF_MEMORY if memory allocation failed
- */
-HAM_EXPORT ham_status_t
-ham_txn_begin(ham_txn_t **txn, ham_env_t *env, const char *name,
- void *reserved, uint32_t flags);
-
-/** Flag for @ref ham_txn_begin */
-#define HAM_TXN_READ_ONLY 1
-
-/* Internal flag for @ref ham_txn_begin */
-#define HAM_TXN_TEMPORARY 2
-
-/**
- * Retrieves the Transaction name
- *
- * @returns NULL if the name was not assigned or if @a txn is invalid
- */
-HAM_EXPORT const char *
-ham_txn_get_name(ham_txn_t *txn);
-
-/**
- * Commits a Transaction
- *
- * This function applies the sequence of Database operations.
- *
- * Note that the function will fail with @ref HAM_CURSOR_STILL_OPEN if
- * a Cursor was attached to this Transaction (with @ref ham_cursor_create
- * or @ref ham_cursor_clone), and the Cursor was not closed.
- *
- * @param txn Pointer to a Transaction structure
- * @param flags Optional flags for committing the Transaction, combined with
- * bitwise OR. Unused, set to 0.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_IO_ERROR if writing to the file failed
- * @return @ref HAM_CURSOR_STILL_OPEN if there are Cursors attached to this
- * Transaction
- */
-HAM_EXPORT ham_status_t
-ham_txn_commit(ham_txn_t *txn, uint32_t flags);
-
-/**
- * Aborts a Transaction
- *
- * This function aborts (= cancels) the sequence of Database operations.
- *
- * Note that the function will fail with @ref HAM_CURSOR_STILL_OPEN if
- * a Cursor was attached to this Transaction (with @ref ham_cursor_create
- * or @ref ham_cursor_clone), and the Cursor was not closed.
- *
- * @param txn Pointer to a Transaction structure
- * @param flags Optional flags for aborting the Transaction, combined with
- * bitwise OR. Unused, set to 0.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_IO_ERROR if writing to the Database file or logfile failed
- * @return @ref HAM_CURSOR_STILL_OPEN if there are Cursors attached to this
- * Transaction
- */
-HAM_EXPORT ham_status_t
-ham_txn_abort(ham_txn_t *txn, uint32_t flags);
-
-/**
- * @}
- */
-
-
-/**
- * @defgroup ham_database hamsterdb Database Functions
- * @{
- */
-
-/** Flag for @ref ham_env_open, @ref ham_env_create.
- * This flag is non persistent. */
-#define HAM_ENABLE_FSYNC 0x00000001
-
-/* unused 0x00000002 */
-
-/** Flag for @ref ham_env_open, @ref ham_env_open_db.
- * This flag is non persistent. */
-#define HAM_READ_ONLY 0x00000004
-
-/* unused 0x00000008 */
-
-/* unused 0x00000010 */
-
-/* reserved 0x00000020 */
-
-/* unused 0x00000040 */
-
-/** Flag for @ref ham_env_create.
- * This flag is non persistent. */
-#define HAM_IN_MEMORY 0x00000080
-
-/* reserved: DB_USE_MMAP (not persistent) 0x00000100 */
-
-/** Flag for @ref ham_env_open, @ref ham_env_create.
- * This flag is non persistent. */
-#define HAM_DISABLE_MMAP 0x00000200
-
-/* deprecated */
-#define HAM_RECORD_NUMBER HAM_RECORD_NUMBER64
-
-/** Flag for @ref ham_env_create_db.
- * This flag is persisted in the Database. */
-#define HAM_RECORD_NUMBER32 0x00001000
-
-/** Flag for @ref ham_env_create_db.
- * This flag is persisted in the Database. */
-#define HAM_RECORD_NUMBER64 0x00002000
-
-/** Flag for @ref ham_env_create_db.
- * This flag is persisted in the Database. */
-#define HAM_ENABLE_DUPLICATE_KEYS 0x00004000
-/* deprecated */
-#define HAM_ENABLE_DUPLICATES HAM_ENABLE_DUPLICATE_KEYS
-
-/** Flag for @ref ham_env_create, @ref ham_env_open.
- * This flag is non persistent. */
-#define HAM_ENABLE_RECOVERY 0x00008000
-
-/** Flag for @ref ham_env_open.
- * This flag is non persistent. */
-#define HAM_AUTO_RECOVERY 0x00010000
-
-/** Flag for @ref ham_env_create, @ref ham_env_open.
- * This flag is non persistent. */
-#define HAM_ENABLE_TRANSACTIONS 0x00020000
-
-/** Flag for @ref ham_env_open, @ref ham_env_create.
- * This flag is non persistent. */
-#define HAM_CACHE_UNLIMITED 0x00040000
-
-/** Flag for @ref ham_env_create, @ref ham_env_open.
- * This flag is non persistent. */
-#define HAM_DISABLE_RECOVERY 0x00080000
-
-/* internal use only! (not persistent) */
-#define HAM_IS_REMOTE_INTERNAL 0x00200000
-
-/* internal use only! (not persistent) */
-#define HAM_DISABLE_RECLAIM_INTERNAL 0x00400000
-
-/* internal use only! (persistent) */
-#define HAM_FORCE_RECORDS_INLINE 0x00800000
-
-/** Flag for @ref ham_env_open, @ref ham_env_create.
- * This flag is non persistent. */
-#define HAM_FLUSH_WHEN_COMMITTED 0x01000000
-
-/** Pro: Flag for @ref ham_env_open, @ref ham_env_create.
- * This flag is non persistent. */
-#define HAM_ENABLE_CRC32 0x02000000
-
-/**
- * Returns the last error code
- *
- * @note This API is deprecated! It will be removed in one of the
- * next versions.
- *
- * @param db A valid Database handle
- *
- * @return The last error code which was returned by one of the
- * hamsterdb API functions. Use @ref ham_strerror to translate
- * this code to a descriptive string
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_get_error(ham_db_t *db);
-
-/**
- * Typedef for a key comparison function
- *
- * @remark This function compares two index keys. It returns -1, if @a lhs
- * ("left-hand side", the parameter on the left side) is smaller than
- * @a rhs ("right-hand side"), 0 if both keys are equal, and 1 if @a lhs
- * is larger than @a rhs.
- */
-typedef int HAM_CALLCONV (*ham_compare_func_t)(ham_db_t *db,
- const uint8_t *lhs, uint32_t lhs_length,
- const uint8_t *rhs, uint32_t rhs_length);
-
-/**
- * Sets the comparison function
- *
- * The comparison function compares two index keys. It returns -1 if the
- * first key is smaller, +1 if the second key is smaller or 0 if both
- * keys are equal.
- *
- * Supplying a comparison function is only allowed for the key type
- * @ref HAM_TYPE_CUSTOM; see the documentation of @sa ham_env_create_db
- * for more information.
- *
- * @param db A valid Database handle
- * @param foo A pointer to the compare function
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- * @return @ref HAM_INV_PARAMETER if the database's key type was not
- * specified as @ref HAM_TYPE_CUSTOM
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_set_compare_func(ham_db_t *db, ham_compare_func_t foo);
-
-/**
- * Searches an item in the Database
- *
- * This function searches the Database for @a key. If the key
- * is found, @a record will receive the record of this item and
- * @ref HAM_SUCCESS is returned. If the key is not found, the function
- * returns @ref HAM_KEY_NOT_FOUND.
- *
- * A ham_record_t structure should be initialized with
- * zeroes before it is being used. This can be done with the C library
- * routines memset(3) or bzero(2).
- *
- * If the function completes successfully, the @a record pointer is
- * initialized with the size of the record (in @a record.size) and the
- * actual record data (in @a record.data). If the record is empty,
- * @a size is 0 and @a data points to NULL.
- *
- * The @a data pointer is a temporary pointer and will be overwritten
- * by subsequent hamsterdb API calls using the same Transaction
- * (or, if Transactions are disabled, using the same Database).
- * You can alter this behaviour by allocating the @a data pointer in
- * the application and setting @a record.flags to @ref HAM_RECORD_USER_ALLOC.
- * Make sure that the allocated buffer is large enough.
- *
- * When specifying @ref HAM_DIRECT_ACCESS, the @a data pointer will point
- * directly to the record that is stored in hamsterdb; the data can be modified,
- * but the pointer must not be reallocated or freed. The flag @ref
- * HAM_DIRECT_ACCESS is only allowed in In-Memory Databases and not if
- * Transactions are enabled.
- *
- * @ref ham_db_find can not search for duplicate keys. If @a key has
- * multiple duplicates, only the first duplicate is returned.
- *
- * You can read only portions of the record by specifying the flag
- * @ref HAM_PARTIAL. In this case, hamsterdb will read
- * <b>record->partial_size</b> bytes of the record data at offset
- * <b>record->partial_offset</b>. If necessary, the record data will
- * be limited to the original record size. The number of actually read
- * bytes is returned in <b>record->partial_size</b>. The original size of
- * the record is stored in <b>record->size</b>.
- *
- * @ref HAM_PARTIAL is not allowed if record->size is <= 8 or if Transactions
- * are enabled. In such a case, @ref HAM_INV_PARAMETER is returned.
- *
- * If Transactions are enabled (see @ref HAM_ENABLE_TRANSACTIONS) and
- * @a txn is NULL then hamsterdb will create a temporary Transaction.
- * When moving the Cursor, and the new key is currently modified in an
- * active Transaction (one that is not yet committed or aborted) then
- * hamsterdb will skip this key and move to the next/previous one. However if
- * @a flags are 0 (and the Cursor is not moved), and @a key or @a rec
- * is NOT NULL, then hamsterdb will return error @ref HAM_TXN_CONFLICT.
- *
- * @param db A valid Database handle
- * @param txn A Transaction handle, or NULL
- * @param key The key of the item
- * @param record The record of the item
- * @param flags Optional flags for searching, which can be combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_FIND_LT_MATCH </li> Cursor 'find' flag 'Less Than': the
- * cursor is moved to point at the last record which' key
- * is less than the specified key. When such a record cannot
- * be located, an error is returned.
- * <li>@ref HAM_FIND_GT_MATCH </li> Cursor 'find' flag 'Greater Than':
- * the cursor is moved to point at the first record which' key is
- * larger than the specified key. When such a record cannot be
- * located, an error is returned.
- * <li>@ref HAM_FIND_LEQ_MATCH </li> Cursor 'find' flag 'Less or EQual':
- * the cursor is moved to point at the record which' key matches
- * the specified key and when such a record is not available
- * the cursor is moved to point at the last record which' key
- * is less than the specified key. When such a record cannot be
- * located, an error is returned.
- * <li>@ref HAM_FIND_GEQ_MATCH </li> Cursor 'find' flag 'Greater or
- * Equal': the cursor is moved to point at the record which' key
- * matches the specified key and when such a record
- * is not available the cursor is moved to point at the first
- * record which' key is larger than the specified key.
- * When such a record cannot be located, an error is returned.
- * <li>@ref HAM_FIND_NEAR_MATCH </li> Cursor 'find' flag 'Any Near Or
- * Equal': the cursor is moved to point at the record which'
- * key matches the specified key and when such a record is
- * not available the cursor is moved to point at either the
- * last record which' key is less than the specified key or
- * the first record which' key is larger than the specified
- * key, whichever of these records is located first.
- * When such records cannot be located, an error is returned.
- * <li>@ref HAM_DIRECT_ACCESS </li> Only for In-Memory Databases
- * and not if Transactions are enabled!
- * Returns a direct pointer to the data blob stored by the
- * hamsterdb engine. This pointer must not be resized or freed,
- * but the data in this memory can be modified.
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a db, @a key or @a record is NULL
- * @return @ref HAM_INV_PARAMETER if @a HAM_DIRECT_ACCESS is specified,
- * but the Database is not an In-Memory Database.
- * @return @ref HAM_INV_PARAMETER if @a HAM_DIRECT_ACCESS and
- * @a HAM_ENABLE_TRANSACTIONS were both specified.
- * @return @ref HAM_INV_PARAMETER if @ref HAM_PARTIAL is set but record
- * size is <= 8 or Transactions are enabled
- * @return @ref HAM_KEY_NOT_FOUND if the @a key does not exist
- * @return @ref HAM_TXN_CONFLICT if the same key was inserted in another
- * Transaction which was not yet committed or aborted
- *
- * @remark When either or both @ref HAM_FIND_LT_MATCH and/or @ref
- * HAM_FIND_GT_MATCH have been specified as flags, the @a key structure
- * will be overwritten when an approximate match was found: the
- * @a key and @a record structures will then point at the located
- * @a key and @a record. In this case the caller should ensure @a key
- * points at a structure which must adhere to the same restrictions
- * and conditions as specified for @ref ham_cursor_move(...,
- * HAM_CURSOR_NEXT).
- *
- * @sa HAM_RECORD_USER_ALLOC
- * @sa HAM_KEY_USER_ALLOC
- * @sa ham_record_t
- * @sa ham_key_t
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_find(ham_db_t *db, ham_txn_t *txn, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
-/**
- * Inserts a Database item
- *
- * This function inserts a key/record pair as a new Database item.
- *
- * If the key already exists in the Database, error @ref HAM_DUPLICATE_KEY
- * is returned.
- *
- * If you wish to overwrite an existing entry specify the
- * flag @ref HAM_OVERWRITE.
- *
- * You can write only portions of the record by specifying the flag
- * @ref HAM_PARTIAL. In this case, hamsterdb will write <b>partial_size</b>
- * bytes of the record data at offset <b>partial_offset</b>. The full record
- * size will always be given in <b>record->size</b>! If
- * partial_size+partial_offset exceed record->size then partial_size will
- * be limited. To shrink or grow the record, adjust record->size.
- * @ref HAM_PARTIAL automatically overwrites existing records.
- * Gaps will be filled with null-bytes if the record did not yet exist.
- *
- * @ref HAM_PARTIAL is not allowed if record->size is <= 8 or if Transactions
- * are enabled. In such a case, @ref HAM_INV_PARAMETER is returned.
- *
- * If you wish to insert a duplicate key specify the flag @ref HAM_DUPLICATE.
- * (Note that the Database has to be created with @ref HAM_ENABLE_DUPLICATE_KEYS
- * in order to use duplicate keys.)
- * The duplicate key is inserted after all other duplicate keys (see
- * @ref HAM_DUPLICATE_INSERT_LAST).
- *
- * Record Number Databases (created with @ref HAM_RECORD_NUMBER32 or
- * @ref HAM_RECORD_NUMBER64) expect either an empty @a key (with a size of
- * 0 and data pointing to NULL), or a user-supplied key (with key.flag
- * @ref HAM_KEY_USER_ALLOC and a valid data pointer).
- * If key.size is 0 and key.data is NULL, hamsterdb will temporarily
- * allocate memory for key->data, which will then point to an 4-byte (or 8-byte)
- * unsigned integer.
- *
- * For very fast sequential inserts please use @ref ham_cursor_insert in
- * combination with the flag @ref HAM_HINT_APPEND.
- *
- * @param db A valid Database handle
- * @param txn A Transaction handle, or NULL
- * @param key The key of the new item
- * @param record The record of the new item
- * @param flags Optional flags for inserting. Possible flags are:
- * <ul>
- * <li>@ref HAM_OVERWRITE. If the @a key already exists, the record is
- * overwritten. Otherwise, the key is inserted. Flag is not
- * allowed in combination with @ref HAM_DUPLICATE.
- * <li>@ref HAM_DUPLICATE. If the @a key already exists, a duplicate
- * key is inserted. The key is inserted before the already
- * existing key, or according to the sort order. Flag is not
- * allowed in combination with @ref HAM_OVERWRITE.
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a db, @a key or @a record is NULL
- * @return @ref HAM_INV_PARAMETER if the Database is a Record Number Database
- * and the key is invalid (see above)
- * @return @ref HAM_INV_PARAMETER if @ref HAM_PARTIAL is set but record
- * size is <= 8 or Transactions are enabled
- * @return @ref HAM_INV_PARAMETER if the flags @ref HAM_OVERWRITE <b>and</b>
- * @ref HAM_DUPLICATE were specified, or if @ref HAM_DUPLICATE
- * was specified, but the Database was not created with
- * flag @ref HAM_ENABLE_DUPLICATE_KEYS.
- * @return @ref HAM_INV_PARAMETER if @ref HAM_PARTIAL is specified and
- * record->partial_offset+record->partial_size exceeds the
- * record->size
- * @return @ref HAM_WRITE_PROTECTED if you tried to insert a key in a read-only
- * Database
- * @return @ref HAM_TXN_CONFLICT if the same key was inserted in another
- * Transaction which was not yet committed or aborted
- * @return @ref HAM_INV_KEY_SIZE if the key size is larger than the
- * @a HAM_PARAMETER_KEY_SIZE parameter specified for
- * @ref ham_env_create_db
- * OR if the key's size is greater than the Btree key size (see
- * @ref HAM_PARAM_KEY_SIZE).
- * @return @ref HAM_INV_RECORD_SIZE if the record size is different from
- * the one specified with @a HAM_PARAM_RECORD_SIZE
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_insert(ham_db_t *db, ham_txn_t *txn, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
-/**
- * Flag for @ref ham_db_insert and @ref ham_cursor_insert
- *
- * When specified with @ref ham_db_insert and in case a key
- * is specified which stores duplicates in the Database, the first
- * duplicate record will be overwritten.
- *
- * When used with @ref ham_cursor_insert and assuming the same
- * conditions, the duplicate currently referenced by the Cursor
- * will be overwritten.
-*/
-#define HAM_OVERWRITE 0x0001
-
-/** Flag for @ref ham_db_insert and @ref ham_cursor_insert */
-#define HAM_DUPLICATE 0x0002
-
-/** Flag for @ref ham_cursor_insert */
-#define HAM_DUPLICATE_INSERT_BEFORE 0x0004
-
-/** Flag for @ref ham_cursor_insert */
-#define HAM_DUPLICATE_INSERT_AFTER 0x0008
-
-/** Flag for @ref ham_cursor_insert */
-#define HAM_DUPLICATE_INSERT_FIRST 0x0010
-
-/** Flag for @ref ham_cursor_insert */
-#define HAM_DUPLICATE_INSERT_LAST 0x0020
-
-/** Flag for @ref ham_db_find, @ref ham_cursor_find, @ref ham_cursor_move */
-#define HAM_DIRECT_ACCESS 0x0040
-
-/** Flag for @ref ham_db_insert, @ref ham_cursor_insert, @ref ham_db_find,
- * @ref ham_cursor_find, @ref ham_cursor_move */
-#define HAM_PARTIAL 0x0080
-
-/* Internal flag for @ref ham_db_find, @ref ham_cursor_find,
- * @ref ham_cursor_move */
-#define HAM_FORCE_DEEP_COPY 0x0100
-
-/**
- * Flag for @ref ham_cursor_insert
- *
- * Mutually exclusive with flag @ref HAM_HINT_PREPEND.
- *
- * Hints the hamsterdb engine that the current key will
- * compare as @e larger than any key already existing in the Database.
- * The hamsterdb engine will verify this postulation and when found not
- * to be true, will revert to a regular insert operation
- * as if this flag was not specified. The incurred cost then is only one
- * additional key comparison.
- */
-#define HAM_HINT_APPEND 0x00080000
-
-/**
- * Flag for @ref ham_cursor_insert
- *
- * Mutually exclusive with flag @ref HAM_HINT_APPEND.
- *
- * Hints the hamsterdb engine that the current key will
- * compare as @e smaller than any key already existing in the Database.
- * The hamsterdb engine will verify this postulation and when found not
- * to be true, will revert to a regular insert operation
- * as if this flag was not specified. The incurred cost then is only one
- * additional key comparison.
- */
-#define HAM_HINT_PREPEND 0x00100000
-
-/**
- * Flag mask to extract the common hint flags from a find/move/insert/erase
- * flag value.
- */
-#define HAM_HINTS_MASK 0x001F0000
-
-/**
- * Erases a Database item
- *
- * This function erases a Database item. If the item @a key
- * does not exist, @ref HAM_KEY_NOT_FOUND is returned.
- *
- * Note that ham_db_erase can not erase a single duplicate key. If the key
- * has multiple duplicates, all duplicates of this key will be erased. Use
- * @ref ham_cursor_erase to erase a specific duplicate key.
- *
- * @param db A valid Database handle
- * @param txn A Transaction handle, or NULL
- * @param key The key to delete
- * @param flags Optional flags for erasing; unused, set to 0
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a db or @a key is NULL
- * @return @ref HAM_WRITE_PROTECTED if you tried to erase a key from a read-only
- * Database
- * @return @ref HAM_KEY_NOT_FOUND if @a key was not found
- * @return @ref HAM_TXN_CONFLICT if the same key was inserted in another
- * Transaction which was not yet committed or aborted
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_erase(ham_db_t *db, ham_txn_t *txn, ham_key_t *key, uint32_t flags);
-
-/* internal flag for ham_db_erase() - do not use */
-#define HAM_ERASE_ALL_DUPLICATES 1
-
-/**
- * Returns the number of keys stored in the Database
- *
- * You can specify the @ref HAM_SKIP_DUPLICATES if you do now want
- * to include any duplicates in the count. This will also speed up the
- * counting.
- *
- * @param db A valid Database handle
- * @param txn A Transaction handle, or NULL
- * @param flags Optional flags:
- * <ul>
- * <li>@ref HAM_SKIP_DUPLICATES. Excludes any duplicates from
- * the count
- * </ul>
- * @param keycount A reference to a variable which will receive
- * the calculated key count per page
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a db or @a keycount is NULL or when
- * @a flags contains an invalid flag set
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_get_key_count(ham_db_t *db, ham_txn_t *txn, uint32_t flags,
- uint64_t *keycount);
-
-/**
- * Retrieve the current value for a given Database setting
- *
- * Only those values requested by the parameter array will be stored.
- *
- * The following parameters are supported:
- * <ul>
- * <li>HAM_PARAM_FLAGS</li> returns the flags which were used to
- * open or create this Database
- * <li>HAM_PARAM_DATABASE_NAME</li> returns the Database name
- * <li>HAM_PARAM_KEY_TYPE</li> returns the Btree key type
- * <li>HAM_PARAM_KEY_SIZE</li> returns the Btree key size
- * or @ref HAM_KEY_SIZE_UNLIMITED if there was no fixed key size
- * specified.
- * <li>HAM_PARAM_RECORD_SIZE</li> returns the record size,
- * or @ref HAM_RECORD_SIZE_UNLIMITED if there was no fixed record size
- * specified.
- * <li>HAM_PARAM_MAX_KEYS_PER_PAGE</li> returns the maximum number
- * of keys per page. This number is precise if the key size is fixed
- * and duplicates are disabled; otherwise it's an estimate.
- * <li>@ref HAM_PARAM_RECORD_COMPRESSION</li> Returns the
- * selected algorithm for record compression, or 0 if compression
- * is disabled
- * <li>@ref HAM_PARAM_KEY_COMPRESSION</li> Returns the
- * selected algorithm for key compression, or 0 if compression
- * is disabled
- * </ul>
- *
- * @param db A valid Database handle
- * @param param An array of ham_parameter_t structures
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if the @a db pointer is NULL or
- * @a param is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_get_parameters(ham_db_t *db, ham_parameter_t *param);
-
-/** Parameter name for @ref ham_env_open, @ref ham_env_create;
- * Journal files are switched whenever the number of new Transactions exceeds
- * this threshold. */
-#define HAM_PARAM_JOURNAL_SWITCH_THRESHOLD 0x00001
-
-/** Parameter name for @ref ham_env_open, @ref ham_env_create;
- * sets the cache size */
-#define HAM_PARAM_CACHE_SIZE 0x00000100
-/* deprecated */
-#define HAM_PARAM_CACHESIZE HAM_PARAM_CACHE_SIZE
-
-/** Parameter name for @ref ham_env_create; sets the page size */
-#define HAM_PARAM_PAGE_SIZE 0x00000101
-/* deprecated */
-#define HAM_PARAM_PAGESIZE HAM_PARAM_PAGE_SIZE
-
-/** Parameter name for @ref ham_env_create_db; sets the key size */
-#define HAM_PARAM_KEY_SIZE 0x00000102
-/* deprecated */
-#define HAM_PARAM_KEYSIZE HAM_PARAM_KEY_SIZE
-
-/** Parameter name for @ref ham_env_get_parameters; retrieves the number
- * of maximum Databases */
-#define HAM_PARAM_MAX_DATABASES 0x00000103
-
-/** Parameter name for @ref ham_env_create_db; sets the key type */
-#define HAM_PARAM_KEY_TYPE 0x00000104
-
-/** Parameter name for @ref ham_env_open, @ref ham_env_create;
- * sets the path of the log files */
-#define HAM_PARAM_LOG_DIRECTORY 0x00000105
-
-/** hamsterdb pro: Parameter name for @ref ham_env_open, @ref ham_env_create;
- * sets the AES encryption key */
-#define HAM_PARAM_ENCRYPTION_KEY 0x00000106
-
-/** Parameter name for @ref ham_env_open, @ref ham_env_create;
- * sets the network timeout (in seconds) */
-#define HAM_PARAM_NETWORK_TIMEOUT_SEC 0x00000107
-
-/** Parameter name for @ref ham_env_create_db; sets the key size */
-#define HAM_PARAM_RECORD_SIZE 0x00000108
-
-/** Parameter name for @ref ham_env_create, @ref ham_env_open; sets a
- * limit for the file size (in bytes) */
-#define HAM_PARAM_FILE_SIZE_LIMIT 0x00000109
-
-/** Parameter name for @ref ham_env_create, @ref ham_env_open; sets the
- * parameter for posix_fadvise() */
-#define HAM_PARAM_POSIX_FADVISE 0x00000110
-
-/** Value for @ref HAM_PARAM_POSIX_FADVISE */
-#define HAM_POSIX_FADVICE_NORMAL 0
-
-/** Value for @ref HAM_PARAM_POSIX_FADVISE */
-#define HAM_POSIX_FADVICE_RANDOM 1
-
-/** Value for unlimited record sizes */
-#define HAM_RECORD_SIZE_UNLIMITED ((uint32_t)-1)
-
-/** Value for unlimited key sizes */
-#define HAM_KEY_SIZE_UNLIMITED ((uint16_t)-1)
-
-/** Retrieves the Database/Environment flags as were specified at the time of
- * @ref ham_env_create/@ref ham_env_open invocation. */
-#define HAM_PARAM_FLAGS 0x00000200
-
-/** Retrieves the filesystem file access mode as was specified at the time
- * of @ref ham_env_create/@ref ham_env_open invocation. */
-#define HAM_PARAM_FILEMODE 0x00000201
-
-/**
- * Return a <code>const char *</code> pointer to the current
- * Environment/Database file name in the @ref uint64_t value
- * member, when the Database is actually stored on disc.
- *
- * In-memory Databases will return a NULL (0) pointer instead.
- */
-#define HAM_PARAM_FILENAME 0x00000202
-
-/**
- * Retrieve the Database 'name' number of this @ref ham_db_t Database within
- * the current @ref ham_env_t Environment.
-*/
-#define HAM_PARAM_DATABASE_NAME 0x00000203
-
-/**
- * Retrieve the maximum number of keys per page; this number depends on the
- * currently active page and key sizes. Can be an estimate if keys do not
- * have constant sizes or if duplicate keys are used.
- */
-#define HAM_PARAM_MAX_KEYS_PER_PAGE 0x00000204
-
-/**
- * hamsterdb pro: Parameter name for @ref ham_env_create, @ref ham_env_open;
- * enables compression for the journal.
- */
-#define HAM_PARAM_JOURNAL_COMPRESSION 0x00001000
-
-/**
- * hamsterdb pro: Parameter name for @ref ham_env_create_db,
- * @ref ham_env_open_db; enables compression for the records of
- * a Database.
- */
-#define HAM_PARAM_RECORD_COMPRESSION 0x00001001
-
-/**
- * hamsterdb pro: Parameter name for @ref ham_env_create_db,
- * @ref ham_env_open_db; enables compression for the records of
- * a Database.
- */
-#define HAM_PARAM_KEY_COMPRESSION 0x00001002
-
-/** hamsterdb pro: helper macro for disabling compression */
-#define HAM_COMPRESSOR_NONE 0
-
-/**
- * hamsterdb pro: selects zlib compression
- * http://www.zlib.net/
- */
-#define HAM_COMPRESSOR_ZLIB 1
-
-/**
- * hamsterdb pro: selects google snappy compression
- * http://code.google.com/p/snappy
- */
-#define HAM_COMPRESSOR_SNAPPY 2
-
-/**
- * hamsterdb pro: selects lzf compression
- * http://oldhome.schmorp.de/marc/liblzf.html
- */
-#define HAM_COMPRESSOR_LZF 3
-
-/**
- * hamsterdb pro: selects lzo compression
- * http://www.oberhumer.com/opensource/lzo
- */
-#define HAM_COMPRESSOR_LZO 4
-
-/**
- * Retrieves the Environment handle of a Database
- *
- * @param db A valid Database handle
- *
- * @return The Environment handle
- */
-HAM_EXPORT ham_env_t *HAM_CALLCONV
-ham_db_get_env(ham_db_t *db);
-
-/**
- * Returns the kind of key match which produced this key as it was
- * returned by one of the @ref ham_db_find() and @ref ham_cursor_find().
- *
- * This routine assumes the key was passed back by one of the @ref ham_db_find
- * and @ref ham_cursor_find functions and not used by any other hamsterdb
- * functions after that.
- *
- * As such, this function produces an answer akin to the 'sign' of the
- * specified key as it was returned by the find operation.
- *
- * @param key A valid key
- *
- * @return 1 (greater than) or -1 (less than) when the given key is an
- * approximate result / zero (0) otherwise. Specifically:
- * <ul>
- * <li>+1 when the key is greater than the item searched for (key
- * was a GT match)
- * <li>-1 when the key is less than the item searched for (key was
- * a LT match)
- * <li>zero (0) otherwise (key was an EQ (EXACT) match)
- * </ul>
- */
-HAM_EXPORT int HAM_CALLCONV
-ham_key_get_approximate_match_type(ham_key_t *key);
-
-/**
- * Closes the Database
- *
- * This function flushes the Database and then closes the file handle.
- * It also free the memory resources allocated in the @a db handle.
- *
- * If the flag @ref HAM_AUTO_CLEANUP is specified, hamsterdb automatically
- * calls @ref ham_cursor_close on all open Cursors. This invalidates the
- * ham_cursor_t handle!
- *
- * If the flag is not specified, the application must close all Database
- * Cursors with @ref ham_cursor_close to prevent memory leaks.
- *
- * This function also aborts all Transactions which were not yet committed,
- * and therefore renders all Transaction handles invalid. If the flag
- * @ref HAM_TXN_AUTO_COMMIT is specified, all Transactions will be committed.
- *
- * @param db A valid Database handle
- * @param flags Optional flags for closing the Database. Possible values are:
- * <ul>
- * <li>@ref HAM_AUTO_CLEANUP. Automatically closes all open Cursors
- * <li>@ref HAM_TXN_AUTO_COMMIT. Automatically commit all open
- * Transactions
- * <li>@ref HAM_TXN_AUTO_ABORT. Automatically abort all open
- * Transactions; this is the default behaviour
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a db is NULL
- * @return @ref HAM_CURSOR_STILL_OPEN if not all Cursors of this Database
- * were closed, and @ref HAM_AUTO_CLEANUP was not specified
- * @return @ref HAM_TXN_STILL_OPEN if this Database is modified by a
- * currently active Transaction
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_close(ham_db_t *db, uint32_t flags);
-
-/** Flag for @ref ham_db_close, @ref ham_env_close */
-#define HAM_AUTO_CLEANUP 1
-
-/** @internal (Internal) flag for @ref ham_db_close, @ref ham_env_close */
-#define HAM_DONT_CLEAR_LOG 2
-
-/** Automatically abort all open Transactions (the default) */
-#define HAM_TXN_AUTO_ABORT 4
-
-/** Automatically commit all open Transactions */
-#define HAM_TXN_AUTO_COMMIT 8
-
-/**
- * @}
- */
-
-/**
- * @defgroup ham_cursor hamsterdb Cursor Functions
- * @{
- */
-
-/**
- * Creates a Database Cursor
- *
- * Creates a new Database Cursor. Cursors can be used to
- * traverse the Database from start to end or vice versa. Cursors
- * can also be used to insert, delete or search Database items.
- *
- * A newly created Cursor does not point to any item in the Database.
- *
- * The application should close all Cursors of a Database before closing
- * the Database.
- *
- * If Transactions are enabled (@ref HAM_ENABLE_TRANSACTIONS), but @a txn
- * is NULL, then each Cursor operation (i.e. @ref ham_cursor_insert,
- * @ref ham_cursor_find etc) will create its own, temporary Transaction
- * <b>only</b> for the lifetime of this operation and not for the lifetime
- * of the whole Cursor!
- *
- * @param db A valid Database handle
- * @param txn A Transaction handle, or NULL
- * @param flags Optional flags for creating the Cursor; unused, set to 0
- * @param cursor A pointer to a pointer which is allocated for the
- * new Cursor handle
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a db or @a cursor is NULL
- * @return @ref HAM_OUT_OF_MEMORY if the new structure could not be allocated
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_create(ham_cursor_t **cursor, ham_db_t *db, ham_txn_t *txn,
- uint32_t flags);
-
-/**
- * Clones a Database Cursor
- *
- * Clones an existing Cursor. The new Cursor will point to
- * exactly the same item as the old Cursor. If the old Cursor did not point
- * to any item, so will the new Cursor.
- *
- * If the old Cursor is bound to a Transaction, then the new Cursor will
- * also be bound to this Transaction.
- *
- * @param src The existing Cursor
- * @param dest A pointer to a pointer, which is allocated for the
- * cloned Cursor handle
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a src or @a dest is NULL
- * @return @ref HAM_OUT_OF_MEMORY if the new structure could not be allocated
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_clone(ham_cursor_t *src, ham_cursor_t **dest);
-
-/**
- * Moves the Cursor
- *
- * Moves the Cursor. Use the @a flags to specify the direction.
- * After the move, key and record of the item are returned, if @a key
- * and/or @a record are valid pointers.
- *
- * If the direction is not specified, the Cursor will not move. Do not
- * specify a direction if you want to fetch the key and/or record of
- * the current item.
- *
- * When specifying @ref HAM_DIRECT_ACCESS, the @a data pointer will point
- * directly to the record that is stored in hamsterdb; the data can be modified,
- * but the pointer must not be reallocated or freed. The flag @ref
- * HAM_DIRECT_ACCESS is only allowed in In-Memory Databases and not if
- * Transactions are enabled.
- *
- * You can read only portions of the record by specifying the flag
- * @ref HAM_PARTIAL. In this case, hamsterdb will read
- * <b>record->partial_size</b> bytes of the record data at offset
- * <b>record->partial_offset</b>. If necessary, the record data will
- * be limited to the original record size. The number of actually read
- * bytes is returned in <b>record->partial_size</b>. The original size of
- * the record is stored in <b>record->size</b>.
- *
- * @ref HAM_PARTIAL is not allowed if record->size is <= 8 or if Transactions
- * are enabled. In such a case, @ref HAM_INV_PARAMETER is returned.
- *
- * If Transactions are enabled (see @ref HAM_ENABLE_TRANSACTIONS), and
- * the Cursor moves next or previous to a key which is currently modified
- * in an active Transaction (one that is not yet committed or aborted), then
- * hamsterdb will skip the modified key. (This behavior is different from i.e.
- * @a ham_cursor_find, which would return the error @ref HAM_TXN_CONFLICT).
- *
- * If a key has duplicates and any of the duplicates is currently modified
- * in another active Transaction, then ALL duplicate keys are skipped when
- * moving to the next or previous key.
- *
- * If the first (@ref HAM_CURSOR_FIRST) or last (@ref HAM_CURSOR_LAST) key
- * is requested, and the current key (or any of its duplicates) is currently
- * modified in an active Transaction, then @ref HAM_TXN_CONFLICT is
- * returned.
- *
- * If this Cursor is nil (i.e. because it was not yet used or the Cursor's
- * item was erased) then the flag @a HAM_CURSOR_NEXT (or @a
- * HAM_CURSOR_PREVIOUS) will be identical to @a HAM_CURSOR_FIRST (or
- * @a HAM_CURSOR_LAST).
- *
- * @param cursor A valid Cursor handle
- * @param key An optional pointer to a @ref ham_key_t structure. If this
- * pointer is not NULL, the key of the new item is returned.
- * Note that key->data will point to temporary data. This pointer
- * will be invalidated by subsequent hamsterdb API calls. See
- * @ref HAM_KEY_USER_ALLOC on how to change this behaviour.
- * @param record An optional pointer to a @ref ham_record_t structure. If this
- * pointer is not NULL, the record of the new item is returned.
- * Note that record->data will point to temporary data. This pointer
- * will be invalidated by subsequent hamsterdb API calls. See
- * @ref HAM_RECORD_USER_ALLOC on how to change this behaviour.
- * @param flags The flags for this operation. They are used to specify
- * the direction for the "move". If you do not specify a direction,
- * the Cursor will remain on the current position.
- * <ul>
- * <li>@ref HAM_CURSOR_FIRST </li> positions the Cursor on the first
- * item in the Database
- * <li>@ref HAM_CURSOR_LAST </li> positions the Cursor on the last
- * item in the Database
- * <li>@ref HAM_CURSOR_NEXT </li> positions the Cursor on the next
- * item in the Database; if the Cursor does not point to any
- * item, the function behaves as if direction was
- * @ref HAM_CURSOR_FIRST.
- * <li>@ref HAM_CURSOR_PREVIOUS </li> positions the Cursor on the
- * previous item in the Database; if the Cursor does not point to
- * any item, the function behaves as if direction was
- * @ref HAM_CURSOR_LAST.
- * <li>@ref HAM_SKIP_DUPLICATES </li> skips duplicate keys of the
- * current key. Not allowed in combination with
- * @ref HAM_ONLY_DUPLICATES.
- * <li>@ref HAM_ONLY_DUPLICATES </li> only move through duplicate keys
- * of the current key. Not allowed in combination with
- * @ref HAM_SKIP_DUPLICATES.
- * <li>@ref HAM_DIRECT_ACCESS </li> Only for In-Memory Databases and
- * not if Transactions are enabled!
- * Returns a direct pointer to the data blob stored by the
- * hamsterdb engine. This pointer must not be resized or freed,
- * but the data in this memory can be modified.
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a cursor is NULL, or if an invalid
- * combination of flags was specified
- * @return @ref HAM_INV_PARAMETER if @ref HAM_PARTIAL is set but record
- * size is <= 8 or Transactions are enabled
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item, but
- * key and/or record were requested
- * @return @ref HAM_KEY_NOT_FOUND if @a cursor points to the first (or last)
- * item, and a move to the previous (or next) item was
- * requested
- * @return @ref HAM_INV_PARAMETER if @a HAM_DIRECT_ACCESS is specified,
- * but the Database is not an In-Memory Database.
- * @return @ref HAM_INV_PARAMETER if @a HAM_DIRECT_ACCESS and
- * @a HAM_ENABLE_TRANSACTIONS were both specified.
- * @return @ref HAM_INV_PARAMETER if @ref HAM_PARTIAL is specified and
- * record->partial_offset+record->partial_size exceeds the
- * record->size
- * @return @ref HAM_TXN_CONFLICT if @ref HAM_CURSOR_FIRST or @ref
- * HAM_CURSOR_LAST is specified but the first (or last) key or
- * any of its duplicates is currently modified in an active
- * Transaction
- *
- * @sa HAM_RECORD_USER_ALLOC
- * @sa HAM_KEY_USER_ALLOC
- * @sa ham_record_t
- * @sa ham_key_t
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_move(ham_cursor_t *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
-/** Flag for @ref ham_cursor_move */
-#define HAM_CURSOR_FIRST 0x0001
-
-/** Flag for @ref ham_cursor_move */
-#define HAM_CURSOR_LAST 0x0002
-
-/** Flag for @ref ham_cursor_move */
-#define HAM_CURSOR_NEXT 0x0004
-
-/** Flag for @ref ham_cursor_move */
-#define HAM_CURSOR_PREVIOUS 0x0008
-
-/** Flag for @ref ham_cursor_move and @ref ham_db_get_key_count */
-#define HAM_SKIP_DUPLICATES 0x0010
-
-/** Flag for @ref ham_cursor_move */
-#define HAM_ONLY_DUPLICATES 0x0020
-
-/**
- * Overwrites the current record
- *
- * This function overwrites the record of the current item.
- *
- * @param cursor A valid Cursor handle
- * @param record A valid record structure
- * @param flags Optional flags for overwriting the item; unused, set to 0
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a cursor or @a record is NULL
- * @return @ref HAM_INV_PARAMETER if @a cursor points to an item with
- * duplicates and duplicate sorting is enabled
- * @return @ref HAM_INV_PARAMETER if duplicate sorting is enabled
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
- * @return @ref HAM_TXN_CONFLICT if the same key was inserted in another
- * Transaction which was not yet committed or aborted
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_overwrite(ham_cursor_t *cursor, ham_record_t *record,
- uint32_t flags);
-
-/**
- * Searches with a key and points the Cursor to the key found, retrieves
- * the located record
- *
- * Searches for an item in the Database and points the Cursor to this item.
- * If the item could not be found, the Cursor is not modified.
- *
- * Note that @ref ham_cursor_find can not search for duplicate keys. If @a key
- * has multiple duplicates, only the first duplicate is returned.
- *
- * When specifying @ref HAM_DIRECT_ACCESS, the @a data pointer will point
- * directly to the record that is stored in hamsterdb; the data can be modified,
- * but the pointer must not be reallocated or freed. The flag @ref
- * HAM_DIRECT_ACCESS is only allowed in In-Memory Databases and not if
- * Transactions are enabled.
- *
- * You can read only portions of the record by specifying the flag
- * @ref HAM_PARTIAL. In this case, hamsterdb will read
- * <b>record->partial_size</b> bytes of the record data at offset
- * <b>record->partial_offset</b>. If necessary, the record data will
- * be limited to the original record size. The number of actually read
- * bytes is returned in <b>record->partial_size</b>. The original size of
- * the record is stored in <b>record->size</b>.
- *
- * @ref HAM_PARTIAL is not allowed if record->size is <= 8 or if Transactions
- * are enabled. In such a case, @ref HAM_INV_PARAMETER is returned.
- *
- * When either or both @ref HAM_FIND_LT_MATCH and/or @ref HAM_FIND_GT_MATCH
- * have been specified as flags, the @a key structure will be overwritten
- * when an approximate match was found: the @a key and @a record
- * structures will then point at the located @a key (and @a record).
- * In this case the caller should ensure @a key points at a structure
- * which must adhere to the same restrictions and conditions as specified
- * for @ref ham_cursor_move(...,HAM_CURSOR_*):
- * key->data will point to temporary data upon return. This pointer
- * will be invalidated by subsequent hamsterdb API calls using the same
- * Transaction (or the same Database, if Transactions are disabled). See
- * @ref HAM_KEY_USER_ALLOC on how to change this behaviour.
- *
- * Further note that the @a key structure must be non-const at all times as its
- * internal flag bits may be written to. This is done for your benefit, as
- * you may pass the returned @a key structure to
- * @ref ham_key_get_approximate_match_type() to retrieve additional info about
- * the precise nature of the returned key: the sign value produced
- * by @ref ham_key_get_approximate_match_type() tells you which kind of match
- * (equal, less than, greater than) occurred. This is very useful to
- * discern between the various possible successful answers produced by the
- * combinations of @ref HAM_FIND_LT_MATCH and @ref HAM_FIND_GT_MATCH.
- *
- * @param cursor A valid Cursor handle
- * @param key A pointer to a @ref ham_key_t structure. If this
- * pointer is not NULL, the key of the new item is returned.
- * Note that key->data will point to temporary data. This pointer
- * will be invalidated by subsequent hamsterdb API calls. See
- * @a HAM_KEY_USER_ALLOC on how to change this behaviour.
- * @param record Optional pointer to a @ref ham_record_t structure. If this
- * pointer is not NULL, the record of the new item is returned.
- * Note that record->data will point to temporary data. This pointer
- * will be invalidated by subsequent hamsterdb API calls. See
- * @ref HAM_RECORD_USER_ALLOC on how to change this behaviour.
- * @param flags Optional flags for searching, which can be combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_FIND_LT_MATCH </li> Cursor 'find' flag 'Less Than': the
- * cursor is moved to point at the last record which' key
- * is less than the specified key. When such a record cannot
- * be located, an error is returned.
- * <li>@ref HAM_FIND_GT_MATCH </li> Cursor 'find' flag 'Greater Than':
- * the cursor is moved to point at the first record which' key is
- * larger than the specified key. When such a record cannot be
- * located, an error is returned.
- * <li>@ref HAM_FIND_LEQ_MATCH </li> Cursor 'find' flag 'Less or EQual':
- * the cursor is moved to point at the record which' key matches
- * the specified key and when such a record is not available
- * the cursor is moved to point at the last record which' key
- * is less than the specified key. When such a record cannot be
- * located, an error is returned.
- * <li>@ref HAM_FIND_GEQ_MATCH </li> Cursor 'find' flag 'Greater or
- * Equal': the cursor is moved to point at the record which' key
- * matches the specified key and when such a record
- * is not available the cursor is moved to point at the first
- * record which' key is larger than the specified key.
- * When such a record cannot be located, an error is returned.
- * <li>@ref HAM_FIND_NEAR_MATCH </li> Cursor 'find' flag 'Any Near Or
- * Equal': the cursor is moved to point at the record which'
- * key matches the specified key and when such a record is
- * not available the cursor is moved to point at either the
- * last record which' key is less than the specified key or
- * the first record which' key is larger than the specified
- * key, whichever of these records is located first.
- * When such records cannot be located, an error is returned.
- * <li>@ref HAM_DIRECT_ACCESS </li> Only for In-Memory Databases and
- * not if Transactions are enabled!
- * Returns a direct pointer to the data blob stored by the
- * hamsterdb engine. This pointer must not be resized or freed,
- * but the data in this memory can be modified.
- * </ul>
- *
- * <b>Remark</b>
- * For Approximate Matching the returned match will either match the
- * key exactly or is either the first key available above or below the
- * given key when an exact match could not be found; 'find' does NOT
- * spend any effort, in the sense of determining which of both is the
- * 'nearest' to the given key, when both a key above and a key below the
- * one given exist; 'find' will simply return the first of both found.
- * As such, this flag is the simplest possible combination of the
- * combined @ref HAM_FIND_LEQ_MATCH and @ref HAM_FIND_GEQ_MATCH flags.
- *
- * Note that these flags may be bitwise OR-ed to form functional combinations.
- *
- * @ref HAM_FIND_LEQ_MATCH, @ref HAM_FIND_GEQ_MATCH and
- * @ref HAM_FIND_LT_MATCH, @ref HAM_FIND_GT_MATCH
- *
- * @return @ref HAM_SUCCESS upon success. Mind the remarks about the
- * @a key flags being adjusted and the useful invocation of
- * @ref ham_key_get_approximate_match_type() afterwards.
- * @return @ref HAM_INV_PARAMETER if @a db, @a key or @a record is NULL
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
- * @return @ref HAM_KEY_NOT_FOUND if no suitable @a key (record) exists
- * @return @ref HAM_INV_PARAMETER if @a HAM_DIRECT_ACCESS is specified,
- * but the Database is not an In-Memory Database.
- * @return @ref HAM_INV_PARAMETER if @a HAM_DIRECT_ACCESS and
- * @a HAM_ENABLE_TRANSACTIONS were both specified.
- * @return @ref HAM_INV_PARAMETER if @ref HAM_PARTIAL is set but record
- * size is <= 8 or Transactions are enabled
- * @return @ref HAM_TXN_CONFLICT if the same key was inserted in another
- * Transaction which was not yet committed or aborted
- *
- * @sa HAM_KEY_USER_ALLOC
- * @sa ham_key_t
- * @sa HAM_RECORD_USER_ALLOC
- * @sa ham_record_t
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_find(ham_cursor_t *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
-/* internal flag */
-#define HAM_FIND_EXACT_MATCH 0x4000
-
-/**
- * Cursor 'find' flag 'Less Than': return the nearest match below the
- * given key, whether an exact match exists or not.
- */
-#define HAM_FIND_LT_MATCH 0x1000
-
-/**
- * Cursor 'find' flag 'Greater Than': return the nearest match above the
- * given key, whether an exact match exists or not.
- */
-#define HAM_FIND_GT_MATCH 0x2000
-
-/**
- * Cursor 'find' flag 'Less or EQual': return the nearest match below the
- * given key, when an exact match does not exist.
- *
- * May be combined with @ref HAM_FIND_GEQ_MATCH to accept any 'near' key, or
- * you can use the @ref HAM_FIND_NEAR_MATCH constant as a shorthand for that.
- */
-#define HAM_FIND_LEQ_MATCH (HAM_FIND_LT_MATCH | HAM_FIND_EXACT_MATCH)
-
-/**
- * Cursor 'find' flag 'Greater or Equal': return the nearest match above
- * the given key, when an exact match does not exist.
- *
- * May be combined with @ref HAM_FIND_LEQ_MATCH to accept any 'near' key,
- * or you can use the @ref HAM_FIND_NEAR_MATCH constant as a shorthand for that.
- */
-#define HAM_FIND_GEQ_MATCH (HAM_FIND_GT_MATCH | HAM_FIND_EXACT_MATCH)
-
-/**
- * Cursor 'find' flag 'Any Near Or Equal': return a match directly below or
- * above the given key, when an exact match does not exist.
- *
- * Be aware that the returned match will either match the key exactly or
- * is either the first key available above or below the given key when an
- * exact match could not be found; 'find' does NOT spend any effort, in the
- * sense of determining which of both is the 'nearest' to the given key,
- * when both a key above and a key below the one given exist; 'find' will
- * simply return the first of both found. As such, this flag is the simplest
- * possible combination of the combined @ref HAM_FIND_LEQ_MATCH and
- * @ref HAM_FIND_GEQ_MATCH flags.
- */
-#define HAM_FIND_NEAR_MATCH (HAM_FIND_LT_MATCH | HAM_FIND_GT_MATCH \
- | HAM_FIND_EXACT_MATCH)
-
-/**
- * Inserts a Database item and points the Cursor to the inserted item
- *
- * This function inserts a key/record pair as a new Database item.
- * If the key already exists in the Database, error @ref HAM_DUPLICATE_KEY
- * is returned.
- *
- * If you wish to overwrite an existing entry specify the
- * flag @ref HAM_OVERWRITE. The use of this flag is not allowed in combination
- * with @ref HAM_DUPLICATE.
- *
- * If you wish to insert a duplicate key specify the flag @ref HAM_DUPLICATE.
- * (In order to use duplicate keys, the Database has to be created with
- * @ref HAM_ENABLE_DUPLICATE_KEYS.)
- * By default, the duplicate key is inserted after all other duplicate keys
- * (see @ref HAM_DUPLICATE_INSERT_LAST). This behaviour can be overwritten by
- * specifying @ref HAM_DUPLICATE_INSERT_FIRST, @ref HAM_DUPLICATE_INSERT_BEFORE
- * or @ref HAM_DUPLICATE_INSERT_AFTER.
- *
- * You can write only portions of the record by specifying the flag
- * @ref HAM_PARTIAL. In this case, hamsterdb will write <b>partial_size</b>
- * bytes of the record data at offset <b>partial_offset</b>. If necessary, the
- * record data will grow. Gaps will be filled with null-bytes, if the record
- * did not yet exist.
- *
- * @ref HAM_PARTIAL is not allowed if record->size is <= 8 or if Transactions
- * are enabled. In such a case, @ref HAM_INV_PARAMETER is returned.
- *
- * Specify the flag @ref HAM_HINT_APPEND if you insert sequential data
- * and the current @a key is greater than any other key in this Database.
- * In this case hamsterdb will optimize the insert algorithm. hamsterdb will
- * verify that this key is the greatest; if not, it will perform a normal
- * insert. This flag is the default for Record Number Databases.
- *
- * Specify the flag @ref HAM_HINT_PREPEND if you insert sequential data
- * and the current @a key is lower than any other key in this Database.
- * In this case hamsterdb will optimize the insert algorithm. hamsterdb will
- * verify that this key is the lowest; if not, it will perform a normal
- * insert.
- *
- * After inserting, the Cursor will point to the new item. If inserting
- * the item failed, the Cursor is not modified.
- *
- * Record Number Databases (created with @ref HAM_RECORD_NUMBER32 or
- * @ref HAM_RECORD_NUMBER64) expect either an empty @a key (with a size of
- * 0 and data pointing to NULL), or a user-supplied key (with key.flag
- * @ref HAM_KEY_USER_ALLOC and a valid data pointer).
- * If key.size is 0 and key.data is NULL, hamsterdb will temporarily
- * allocate memory for key->data, which will then point to an 4-byte (or 8-byte)
- * unsigned integer.
- *
- * @param cursor A valid Cursor handle
- * @param key A valid key structure
- * @param record A valid record structure
- * @param flags Optional flags for inserting the item, combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_OVERWRITE. If the @a key already exists, the record is
- * overwritten. Otherwise, the key is inserted. Not allowed in
- * combination with @ref HAM_DUPLICATE.
- * <li>@ref HAM_DUPLICATE. If the @a key already exists, a duplicate
- * key is inserted. Same as @ref HAM_DUPLICATE_INSERT_LAST. Not
- * allowed in combination with @ref HAM_DUPLICATE.
- * <li>@ref HAM_DUPLICATE_INSERT_BEFORE. If the @a key already exists,
- * a duplicate key is inserted before the duplicate pointed
- * to by the Cursor. Not allowed if duplicate sorting is enabled.
- * <li>@ref HAM_DUPLICATE_INSERT_AFTER. If the @a key already exists,
- * a duplicate key is inserted after the duplicate pointed
- * to by the Cursor. Not allowed if duplicate sorting is enabled.
- * <li>@ref HAM_DUPLICATE_INSERT_FIRST. If the @a key already exists,
- * a duplicate key is inserted as the first duplicate of
- * the current key. Not allowed if duplicate sorting is enabled.
- * <li>@ref HAM_DUPLICATE_INSERT_LAST. If the @a key already exists,
- * a duplicate key is inserted as the last duplicate of
- * the current key. Not allowed if duplicate sorting is enabled.
- * <li>@ref HAM_HINT_APPEND. Hints the hamsterdb engine that the
- * current key will compare as @e larger than any key already
- * existing in the Database. The hamsterdb engine will verify
- * this postulation and when found not to be true, will revert
- * to a regular insert operation as if this flag was not
- * specified. The incurred cost then is only one additional key
- * comparison. Mutually exclusive with flag @ref HAM_HINT_PREPEND.
- * This is the default for Record Number Databases.
- * <li>@ref HAM_HINT_PREPEND. Hints the hamsterdb engine that the
- * current key will compare as @e lower than any key already
- * existing in the Database. The hamsterdb engine will verify
- * this postulation and when found not to be true, will revert
- * to a regular insert operation as if this flag was not
- * specified. The incurred cost then is only one additional key
- * comparison. Mutually exclusive with flag @ref HAM_HINT_APPEND.
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a key or @a record is NULL
- * @return @ref HAM_INV_PARAMETER if the Database is a Record Number Database
- * and the key is invalid (see above)
- * @return @ref HAM_INV_PARAMETER if @ref HAM_PARTIAL is set but record
- * size is <= 8 or Transactions are enabled
- * @return @ref HAM_INV_PARAMETER if the flags @ref HAM_OVERWRITE <b>and</b>
- * @ref HAM_DUPLICATE were specified, or if @ref HAM_DUPLICATE
- * was specified, but the Database was not created with
- * flag @ref HAM_ENABLE_DUPLICATE_KEYS.
- * @return @ref HAM_WRITE_PROTECTED if you tried to insert a key to a read-only
- * Database.
- * @return @ref HAM_INV_KEY_SIZE if the key size is different from
- * the one specified with @a HAM_PARAM_KEY_SIZE
- * @return @ref HAM_INV_RECORD_SIZE if the record size is different from
- * the one specified with @a HAM_PARAM_RECORD_SIZE
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
- * @return @ref HAM_TXN_CONFLICT if the same key was inserted in another
- * Transaction which was not yet committed or aborted
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_insert(ham_cursor_t *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
-/**
- * Erases the current key
- *
- * Erases a key from the Database. If the erase was
- * successful, the Cursor is invalidated and does no longer point to
- * any item. In case of an error, the Cursor is not modified.
- *
- * If the Database was opened with the flag @ref HAM_ENABLE_DUPLICATE_KEYS,
- * this function erases only the duplicate item to which the Cursor refers.
- *
- * @param cursor A valid Cursor handle
- * @param flags Unused, set to 0
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if @a cursor is NULL
- * @return @ref HAM_WRITE_PROTECTED if you tried to erase a key from a read-only
- * Database
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
- * @return @ref HAM_TXN_CONFLICT if the same key was inserted in another
- * Transaction which was not yet committed or aborted
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_erase(ham_cursor_t *cursor, uint32_t flags);
-
-/**
- * Returns the number of duplicate keys
- *
- * Returns the number of duplicate keys of the item to which the
- * Cursor currently refers.
- * Returns 1 if the key has no duplicates.
- *
- * @param cursor A valid Cursor handle
- * @param count Returns the number of duplicate keys
- * @param flags Optional flags; unused, set to 0.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
- * @return @ref HAM_INV_PARAMETER if @a cursor or @a count is NULL
- * @return @ref HAM_TXN_CONFLICT if the same key was inserted in another
- * Transaction which was not yet committed or aborted
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_get_duplicate_count(ham_cursor_t *cursor,
- uint32_t *count, uint32_t flags);
-
-/**
- * Returns the current cursor position in the duplicate list
- *
- * Returns the position in the duplicate list of the current key. The position
- * is 0-based.
- *
- * @param cursor A valid Cursor handle
- * @param position Returns the duplicate position
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
- * @return @ref HAM_INV_PARAMETER if @a cursor or @a position is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_get_duplicate_position(ham_cursor_t *cursor,
- uint32_t *position);
-
-/**
- * Returns the record size of the current key
- *
- * Returns the record size of the item to which the Cursor currently refers.
- *
- * @param cursor A valid Cursor handle
- * @param size Returns the record size, in bytes
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
- * @return @ref HAM_INV_PARAMETER if @a cursor or @a size is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_get_record_size(ham_cursor_t *cursor, uint64_t *size);
-
-/**
- * Closes a Database Cursor
- *
- * Closes a Cursor and frees allocated memory. All Cursors
- * should be closed before closing the Database (see @ref ham_db_close).
- *
- * @param cursor A valid Cursor handle
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_CURSOR_IS_NIL if the Cursor does not point to an item
- * @return @ref HAM_INV_PARAMETER if @a cursor is NULL
- *
- * @sa ham_db_close
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_close(ham_cursor_t *cursor);
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* HAM_HAMSTERDB_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb.hpp b/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb.hpp
deleted file mode 100644
index 68892ac2d7..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb.hpp
+++ /dev/null
@@ -1,711 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file hamsterdb.hpp
- * @author Christoph Rupp, chris@crupp.de
- * @version 2.1.10
- *
- * This C++ wrapper class is a very tight wrapper around the C API. It does
- * not attempt to be STL compatible.
- *
- * All functions throw exceptions of class @sa ham::error in case of an error.
- * Please refer to the C API documentation for more information. You can find
- * it here: http://hamsterdb.com/?page=doxygen&module=globals.html
- *
- */
-
-#ifndef HAM_HAMSTERDB_HPP
-#define HAM_HAMSTERDB_HPP
-
-#include <ham/hamsterdb.h>
-#include <ham/hamsterdb_int.h>
-#include <cstring>
-#include <vector>
-
-#if defined(_MSC_VER) && defined(_DEBUG) && !defined(_CRTDBG_MAP_ALLOC)
-# define _CRTDBG_MAP_ALLOC
-# include <crtdbg.h>
-#endif
-
-/**
- * @defgroup ham_cpp hamsterdb C++ API wrapper
- * @{
- */
-
-/**
- * The global hamsterdb namespace.
- */
-namespace hamsterdb {
-
-class txn;
-class db;
-class env;
-
-/**
- * An error class.
- *
- * The hamsterdb C++ API throws this class as Exceptions.
- */
-class error {
- public:
- /** Constructor */
- error(ham_status_t st)
- : m_errno(st) {
- };
-
- /** Returns the error code. */
- ham_status_t get_errno() const {
- return (m_errno);
- }
-
- /** Returns an English error description. */
- const char *get_string() const {
- return (ham_strerror(m_errno));
- }
-
-private:
- ham_status_t m_errno;
-};
-
-/**
- * A key class.
- *
- * This class wraps structures of type ham_key_t.
- */
-class key {
- public:
- /** Constructor */
- key(void *data = 0, uint16_t size = 0, uint32_t flags = 0) {
- memset(&m_key, 0, sizeof(m_key));
- m_key.data = data;
- m_key.size = size;
- m_key.flags = flags;
- if (m_key.size != size) // check for overflow
- throw error(HAM_INV_KEYSIZE);
- }
-
- /** Copy constructor. */
- key(const key &other)
- : m_key(other.m_key) {
- }
-
- /** Assignment operator. */
- key &operator=(const key &other) {
- if (&other != this)
- m_key = other.m_key;
- return (*this);
- }
-
- /** Returns the key data. */
- void *get_data() const {
- return (m_key.data);
- }
-
- /** Sets the key data. */
- void set_data(void *data) {
- m_key.data = data;
- }
-
- /** Returns the size of the key. */
- uint16_t get_size() const {
- return (m_key.size);
- }
-
- /** Sets the size of the key. */
- void set_size(uint16_t size) {
- m_key.size = size;
- }
-
- /** Template assignment */
- template <class T>
- void set(T &t) {
- set_data(&t);
- set_size(sizeof(t));
- }
-
- /** Returns the flags of the key. */
- uint32_t get_flags() const {
- return (m_key.flags);
- }
-
- /** Sets the flags of the key. */
- void set_flags(uint32_t flags) {
- m_key.flags = flags;
- }
-
- /** Returns a pointer to the internal ham_key_t structure. */
- ham_key_t *get_handle() {
- return (&m_key);
- }
-
- /** Returns 'sign' of Approximate Match */
- int get_approximate_match_type() {
- return (ham_key_get_approximate_match_type(&m_key));
- }
-
-private:
- ham_key_t m_key;
-};
-
-/**
- * A record class.
- *
- * This class wraps structures of type ham_record_t.
- */
-class record {
- public:
- /** Constructor */
- record(void *data = 0, uint32_t size = 0, uint32_t flags = 0) {
- memset(&m_rec, 0, sizeof(m_rec));
- m_rec.data = data;
- m_rec.size = size;
- m_rec.flags = flags;
- }
-
- /** Copy constructor. */
- record(const record &other)
- : m_rec(other.m_rec) {
- }
-
- /** Assignment operator. */
- record &operator=(const record &other) {
- m_rec = other.m_rec;
- return (*this);
- }
-
- /** Returns the record data. */
- void *get_data() const {
- return (m_rec.data);
- }
-
- /** Sets the record data. */
- void set_data(void *data) {
- m_rec.data = data;
- }
-
- /** Returns the size of the record. */
- uint32_t get_size() const {
- return (m_rec.size);
- }
-
- /** Sets the size of the record. */
- void set_size(uint32_t size) {
- m_rec.size = size;
- }
-
- /** Returns the flags of the record. */
- uint32_t get_flags() const {
- return (m_rec.flags);
- }
-
- /** Sets the flags of the record. */
- void set_flags(uint32_t flags) {
- m_rec.flags = flags;
- }
-
- /** Returns a pointer to the internal ham_record_t structure. */
- ham_record_t *get_handle() {
- return (&m_rec);
- }
-
- protected:
- ham_record_t m_rec;
-};
-
-
-/**
- * A Transaction class
- *
- * This class wraps structures of type ham_txn_t.
- */
-class txn {
- public:
- /** Constructor */
- txn(ham_txn_t *t = 0)
- : m_txn(t) {
- }
-
- /** Abort the Transaction */
- void abort() {
- ham_status_t st = ham_txn_abort(m_txn, 0);
- if (st)
- throw error(st);
- }
-
- /** Commit the Transaction */
- void commit() {
- ham_status_t st = ham_txn_commit(m_txn, 0);
- if (st)
- throw error(st);
- }
-
- std::string get_name() {
- const char *p = ham_txn_get_name(m_txn);
- return (p ? p : "");
- }
-
- /** Returns a pointer to the internal ham_txn_t structure. */
- ham_txn_t *get_handle() {
- return (m_txn);
- }
-
- protected:
- ham_txn_t *m_txn;
-};
-
-
-/**
- * A Database class.
- *
- * This class wraps the ham_db_t Database handles.
- */
-class db {
- public:
- /** Set error handler function. */
- static void set_errhandler(ham_errhandler_fun f) {
- ham_set_errhandler(f);
- }
-
- /** Retrieves the hamsterdb library version. */
- static void get_version(uint32_t *major, uint32_t *minor,
- uint32_t *revision) {
- ham_get_version(major, minor, revision);
- }
-
- /** Constructor */
- db()
- : m_db(0) {
- }
-
- /** Destructor - automatically closes the Database, if necessary. */
- ~db() {
- close();
- }
-
- /**
- * Assignment operator.
- *
- * <b>Important!</b> This operator transfers the ownership of the
- * Database handle.
- */
- db &operator=(const db &other) {
- db &rhs = (db &)other;
- if (this == &other)
- return (*this);
- close();
- m_db = rhs.m_db;
- rhs.m_db = 0;
- return (*this);
- }
-
- /** Returns the last Database error. */
- ham_status_t get_error() {
- return (ham_db_get_error(m_db));
- }
-
- /** Sets the comparison function. */
- void set_compare_func(ham_compare_func_t foo) {
- ham_status_t st = ham_db_set_compare_func(m_db, foo);
- if (st)
- throw error(st);
- }
-
- /** Finds a record by looking up the key. */
- record find(txn *t, key *k, uint32_t flags = 0) {
- record r;
- ham_status_t st = ham_db_find(m_db,
- t ? t->get_handle() : 0,
- k ? k->get_handle() : 0,
- r.get_handle(), flags);
- if (st)
- throw error(st);
- return (r);
- }
-
- /** Finds a record by looking up the key. */
- record &find(txn *t, key *k, record *r, uint32_t flags = 0) {
- ham_status_t st = ham_db_find(m_db,
- t ? t->get_handle() : 0,
- k ? k->get_handle() : 0,
- r->get_handle(), flags);
- if (st)
- throw error(st);
- return (*r);
- }
-
- /** Finds a record by looking up the key. */
- record find(key *k, uint32_t flags = 0) {
- return (find(0, k, flags));
- }
-
- /** Inserts a key/record pair. */
- void insert(txn *t, key *k, record *r, uint32_t flags = 0) {
- ham_status_t st = ham_db_insert(m_db,
- t ? t->get_handle() : 0,
- k ? k->get_handle() : 0,
- r ? r->get_handle() : 0, flags);
- if (st)
- throw error(st);
- }
-
- /** Inserts a key/record pair. */
- void insert(key *k, record *r, uint32_t flags=0) {
- insert(0, k, r, flags);
- }
-
- /** Erases a key/record pair. */
- void erase(key *k, uint32_t flags = 0) {
- erase(0, k, flags);
- }
-
- /** Erases a key/record pair. */
- void erase(txn *t, key *k, uint32_t flags = 0) {
- ham_status_t st = ham_db_erase(m_db,
- t ? t->get_handle() : 0,
- k ? k->get_handle() : 0, flags);
- if (st)
- throw error(st);
- }
-
- /** Returns number of items in the Database. */
- uint64_t get_key_count(ham_txn_t *txn = 0, uint32_t flags = 0) {
- uint64_t count = 0;
- ham_status_t st = ham_db_get_key_count(m_db, txn, flags, &count);
- if (st)
- throw error(st);
- return (count);
- }
-
- /** Retrieves Database parameters. */
- void get_parameters(ham_parameter_t *param) {
- ham_status_t st = ham_db_get_parameters(m_db, param);
- if (st)
- throw error(st);
- }
-
- /** Closes the Database. */
- void close(uint32_t flags = 0) {
- if (!m_db)
- return;
- // disable auto-cleanup; all objects will be destroyed when
- // going out of scope
- flags &= ~HAM_AUTO_CLEANUP;
- ham_status_t st = ham_db_close(m_db, flags);
- if (st)
- throw error(st);
- m_db = 0;
- }
-
- /** Returns a pointer to the internal ham_db_t structure. */
- ham_db_t *get_handle() {
- return (m_db);
- }
-
-protected:
- friend class env;
-
- /* Copy Constructor. Is protected and should not be used. */
- db(ham_db_t *db)
- : m_db(db) {
- }
-
- private:
- ham_db_t *m_db;
-};
-
-
-/**
- * A Database Cursor.
- *
- * This class wraps the ham_cursor_t Cursor handles.
- */
-class cursor {
- public:
- /** Constructor */
- cursor(db *db = 0, txn *t = 0, uint32_t flags = 0)
- : m_cursor(0) {
- create(db, t, flags);
- }
-
- /** Constructor */
- cursor(txn *t, db *db = 0, uint32_t flags = 0)
- : m_cursor(0) {
- create(db, t, flags);
- }
-
- /** Destructor - automatically closes the Cursor, if necessary. */
- ~cursor() {
- close();
- }
-
- /** Creates a new Cursor. */
- void create(db *db, txn *t = 0, uint32_t flags = 0) {
- if (m_cursor)
- close();
- if (db) {
- ham_status_t st = ham_cursor_create(&m_cursor, db->get_handle(),
- t ? t->get_handle() : 0, flags);
- if (st)
- throw error(st);
- }
- }
-
- /** Clones the Cursor. */
- cursor clone() {
- ham_cursor_t *dest;
- ham_status_t st = ham_cursor_clone(m_cursor, &dest);
- if (st)
- throw error(st);
- return (cursor(dest));
- }
-
- /** Moves the Cursor, and retrieves the key/record of the new position. */
- void move(key *k, record *r, uint32_t flags = 0) {
- ham_status_t st = ham_cursor_move(m_cursor, k ? k->get_handle() : 0,
- r ? r->get_handle() : 0, flags);
- if (st)
- throw error(st);
- }
-
- /** Moves the Cursor to the first Database element. */
- void move_first(key *k = 0, record *r = 0) {
- move(k, r, HAM_CURSOR_FIRST);
- }
-
- /** Moves the Cursor to the last Database element. */
- void move_last(key *k = 0, record *r = 0) {
- move(k, r, HAM_CURSOR_LAST);
- }
-
- /** Moves the Cursor to the next Database element. */
- void move_next(key *k = 0, record *r = 0) {
- move(k, r, HAM_CURSOR_NEXT);
- }
-
- /** Moves the Cursor to the previous Database element. */
- void move_previous(key *k = 0, record *r = 0) {
- move(k, r, HAM_CURSOR_PREVIOUS);
- }
-
- /** Overwrites the current record. */
- void overwrite(record *r, uint32_t flags = 0) {
- ham_status_t st = ham_cursor_overwrite(m_cursor,
- r ? r->get_handle() : 0, flags);
- if (st)
- throw error(st);
- }
-
- /** Finds a key. */
- void find(key *k, record *r = 0, uint32_t flags = 0) {
- ham_status_t st = ham_cursor_find(m_cursor, k->get_handle(),
- (r ? r->get_handle() : 0), flags);
- if (st)
- throw error(st);
- }
-
- /** Inserts a key/record pair. */
- void insert(key *k, record *r, uint32_t flags = 0) {
- ham_status_t st = ham_cursor_insert(m_cursor, k ? k->get_handle() : 0,
- r ? r->get_handle() : 0, flags);
- if (st)
- throw error(st);
- }
-
- /** Erases the current key/record pair. */
- void erase(uint32_t flags = 0) {
- ham_status_t st = ham_cursor_erase(m_cursor, flags);
- if (st)
- throw error(st);
- }
-
- /** Returns the number of duplicate keys. */
- uint32_t get_duplicate_count(uint32_t flags = 0) {
- uint32_t c;
- ham_status_t st = ham_cursor_get_duplicate_count(m_cursor, &c, flags);
- if (st)
- throw error(st);
- return (c);
- }
-
- /** Returns the size of the current record. */
- uint64_t get_record_size() {
- uint64_t s;
- ham_status_t st = ham_cursor_get_record_size(m_cursor, &s);
- if (st)
- throw error(st);
- return (s);
- }
-
- /** Closes the Cursor. */
- void close() {
- if (!m_cursor)
- return;
- ham_status_t st = ham_cursor_close(m_cursor);
- if (st)
- throw error(st);
- m_cursor = 0;
- }
-
- protected:
- /* Copy Constructor. Is protected and should not be used. */
- cursor(ham_cursor_t *c) {
- m_cursor = c;
- }
-
- private:
- ham_cursor_t *m_cursor;
-};
-
-/**
- * An Environment class.
- *
- * This class wraps the ham_env_t structure.
- */
-class env {
- public:
- /** Constructor */
- env()
- : m_env(0) {
- }
-
- /** Destructor - automatically closes the Cursor, if necessary. */
- ~env() {
- close();
- }
-
- /** Creates a new Environment. */
- void create(const char *filename, uint32_t flags = 0,
- uint32_t mode = 0644, const ham_parameter_t *param = 0) {
- ham_status_t st = ham_env_create(&m_env, filename, flags, mode, param);
- if (st)
- throw error(st);
- }
-
- /** Opens an existing Environment. */
- void open(const char *filename, uint32_t flags = 0,
- const ham_parameter_t *param = 0) {
- ham_status_t st = ham_env_open(&m_env, filename, flags, param);
- if (st)
- throw error(st);
- }
-
- /** Flushes the Environment to disk. */
- void flush(uint32_t flags = 0) {
- ham_status_t st = ham_env_flush(m_env, flags);
- if (st)
- throw error(st);
- }
-
- /** Creates a new Database in the Environment. */
- db create_db(uint16_t name, uint32_t flags = 0,
- const ham_parameter_t *param = 0) {
- ham_db_t *dbh;
-
- ham_status_t st = ham_env_create_db(m_env, &dbh, name, flags, param);
- if (st)
- throw error(st);
-
- return (hamsterdb::db(dbh));
- }
-
- /** Opens an existing Database in the Environment. */
- db open_db(uint16_t name, uint32_t flags = 0,
- const ham_parameter_t *param = 0) {
- ham_db_t *dbh;
-
- ham_status_t st = ham_env_open_db(m_env, &dbh, name, flags, param);
- if (st)
- throw error(st);
-
- return (hamsterdb::db(dbh));
- }
-
- /** Renames an existing Database in the Environment. */
- void rename_db(uint16_t oldname, uint16_t newname, uint32_t flags = 0) {
- ham_status_t st = ham_env_rename_db(m_env, oldname, newname, flags);
- if (st)
- throw error(st);
- }
-
- /** Deletes a Database from the Environment. */
- void erase_db(uint16_t name, uint32_t flags = 0) {
- ham_status_t st = ham_env_erase_db(m_env, name, flags);
- if (st)
- throw error(st);
- }
-
- /** Begin a new Transaction */
- txn begin(const char *name = 0) {
- ham_txn_t *h;
- ham_status_t st = ham_txn_begin(&h, m_env, name, 0, 0);
- if (st)
- throw error(st);
- return (txn(h));
- }
-
-
- /** Closes the Environment. */
- void close(uint32_t flags = 0) {
- if (!m_env)
- return;
- // disable auto-cleanup; all objects will be destroyed when
- // going out of scope
- flags &= ~HAM_AUTO_CLEANUP;
- ham_status_t st = ham_env_close(m_env, flags);
- if (st)
- throw error(st);
- m_env = 0;
- }
-
- /** Retrieves Environment parameters. */
- void get_parameters(ham_parameter_t *param) {
- ham_status_t st = ham_env_get_parameters(m_env, param);
- if (st)
- throw error(st);
- }
-
- /** Get all Database names. */
- std::vector<uint16_t> get_database_names() {
- uint32_t count = 32;
- ham_status_t st;
- std::vector<uint16_t> v(count);
-
- for (;;) {
- st = ham_env_get_database_names(m_env, &v[0], &count);
- if (!st)
- break;
- if (st && st!=HAM_LIMITS_REACHED)
- throw error(st);
- count += 16;
- v.resize(count);
- }
-
- v.resize(count);
- return (v);
- }
-
- private:
- ham_env_t *m_env;
-};
-
-} // namespace hamsterdb
-
-/**
- * @}
- */
-
-#endif // HAMSTERDB_HPP
diff --git a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_int.h b/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_int.h
deleted file mode 100644
index ec05ece264..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_int.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file hamsterdb_int.h
- * @brief Internal hamsterdb Embedded Storage functions.
- * @author Christoph Rupp, chris@crupp.de
- *
- * Please be aware that the interfaces in this file are mostly for internal
- * use. Unlike those in hamsterdb.h they are not stable and can be changed
- * with every new version.
- *
- */
-
-#ifndef HAM_HAMSTERDB_INT_H
-#define HAM_HAMSTERDB_INT_H
-
-#include <ham/hamsterdb.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup ham_extended_api hamsterdb Enhanced API
- * @{
- */
-
-/** get the (non-persisted) flags of a key */
-#define ham_key_get_intflags(key) (key)->_flags
-
-/**
- * set the flags of a key
- *
- * Note that the ham_find/ham_cursor_find/ham_cursor_find_ex flags must
- * be defined such that those can peacefully co-exist with these; that's
- * why those public flags start at the value 0x1000 (4096).
- */
-#define ham_key_set_intflags(key, f) (key)->_flags=(f)
-
-/**
- * Verifies the integrity of the Database
- *
- * This function is only interesting if you want to debug hamsterdb.
- *
- * @param db A valid Database handle
- * @param flags Optional flags for the integrity check, combined with
- * bitwise OR. Possible flags are:
- * <ul>
- * <li>@ref HAM_PRINT_GRAPH</li> Prints the Btree as a graph; stores
- * the image as "graph.png" in the current working directory. It uses
- * the "dot" tool from graphviz to generate the image.
- * This functionality is only available in DEBUG builds!
- * </ul>
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INTEGRITY_VIOLATED if the Database is broken
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_check_integrity(ham_db_t *db, uint32_t flags);
-
-/** Flag for ham_db_check_integrity */
-#define HAM_PRINT_GRAPH 1
-
-/**
- * Set a user-provided context pointer
- *
- * This function sets a user-provided context pointer. This can be any
- * arbitrary pointer; it is stored in the Database handle and can be
- * retrieved with @a ham_get_context_data. It is mainly used by Wrappers
- * and language bindings.
- *
- * @param db A valid Database handle
- * @param data The pointer to the context data
- */
-HAM_EXPORT void HAM_CALLCONV
-ham_set_context_data(ham_db_t *db, void *data);
-
-/**
- * Retrieves a user-provided context pointer
- *
- * This function retrieves a user-provided context pointer. This can be any
- * arbitrary pointer which was previously stored with @a ham_set_context_data.
- *
- * @param db A valid Database handle
- * @param dont_lock Whether the Environment mutex should be locked or not
- * this is used to avoid recursive locks when retrieving the context
- * data in a compare function
- *
- * @return The pointer to the context data
- */
-HAM_EXPORT void * HAM_CALLCONV
-ham_get_context_data(ham_db_t *db, ham_bool_t dont_lock);
-
-/**
- * Retrieves the Database handle of a Cursor
- *
- * @param cursor A valid Cursor handle
- *
- * @return @a The Database handle of @a cursor
- */
-HAM_EXPORT ham_db_t * HAM_CALLCONV
-ham_cursor_get_database(ham_cursor_t *cursor);
-
-typedef struct min_max_avg_u32_t {
- uint32_t min;
- uint32_t max;
- uint32_t avg;
- uint32_t _total; /* for calculating the average */
- uint32_t _instances; /* for calculating the average */
-} min_max_avg_u32_t;
-
-/* btree metrics */
-typedef struct btree_metrics_t {
- /* the database name of the btree */
- uint16_t database_name;
-
- /* number of pages */
- uint64_t number_of_pages;
-
- /* number of keys */
- uint64_t number_of_keys;
-
- /* total btree space, including overhead */
- uint64_t total_btree_space;
-
- /* static overhead per page */
- uint32_t overhead_per_page;
-
- /* number of keys stored per page (w/o duplicates) */
- min_max_avg_u32_t keys_per_page;
-
- /* payload storage assigned to the KeyLists */
- min_max_avg_u32_t keylist_ranges;
-
- /* payload storage assigned to the RecordLists */
- min_max_avg_u32_t recordlist_ranges;
-
- /* storage assigned to the Indices (if available) */
- min_max_avg_u32_t keylist_index;
-
- /* storage assigned to the Indices (if available) */
- min_max_avg_u32_t recordlist_index;
-
- /* unused storage (i.e. gaps between pages, underfilled blocks etc) */
- min_max_avg_u32_t keylist_unused;
-
- /* unused storage (i.e. gaps between pages, underfilled blocks etc) */
- min_max_avg_u32_t recordlist_unused;
-
- /* number of blocks per page (if available) */
- min_max_avg_u32_t keylist_blocks_per_page;
-
- /* block sizes (if available) */
- min_max_avg_u32_t keylist_block_sizes;
-} btree_metrics_t;
-
-/**
- * Retrieves collected metrics from the hamsterdb Environment. Used mainly
- * for testing.
- * See below for the structure with the currently available metrics.
- * This structure will change a lot; the first field is a version indicator
- * that applications can use to verify that the structure layout is compatible.
- *
- * These metrics are NOT persisted to disk.
- *
- * Metrics marked "global" are stored globally and shared between multiple
- * Environments.
- */
-#define HAM_METRICS_VERSION 9
-
-typedef struct ham_env_metrics_t {
- /* the version indicator - must be HAM_METRICS_VERSION */
- uint16_t version;
-
- /* number of total allocations for the whole lifetime of the process */
- uint64_t mem_total_allocations;
-
- /* currently active allocations for the whole process */
- uint64_t mem_current_allocations;
-
- /* current amount of memory allocated and tracked by the process
- * (excludes memory used by the kernel or not allocated with
- * malloc/free) */
- uint64_t mem_current_usage;
-
- /* peak usage of memory (for the whole process) */
- uint64_t mem_peak_usage;
-
- /* the heap size of this process */
- uint64_t mem_heap_size;
-
- /* amount of pages fetched from disk */
- uint64_t page_count_fetched;
-
- /* amount of pages written to disk */
- uint64_t page_count_flushed;
-
- /* number of index pages in this Environment */
- uint64_t page_count_type_index;
-
- /* number of blob pages in this Environment */
- uint64_t page_count_type_blob;
-
- /* number of page-manager pages in this Environment */
- uint64_t page_count_type_page_manager;
-
- /* number of successful freelist hits */
- uint64_t freelist_hits;
-
- /* number of freelist misses */
- uint64_t freelist_misses;
-
- /* number of successful cache hits */
- uint64_t cache_hits;
-
- /* number of cache misses */
- uint64_t cache_misses;
-
- /* number of blobs allocated */
- uint64_t blob_total_allocated;
-
- /* number of blobs read */
- uint64_t blob_total_read;
-
- /* (global) number of btree page splits */
- uint64_t btree_smo_split;
-
- /* (global) number of btree page merges */
- uint64_t btree_smo_merge;
-
- /* (global) number of extended keys */
- uint64_t extended_keys;
-
- /* (global) number of extended duplicate tables */
- uint64_t extended_duptables;
-
- /* number of bytes that the log/journal flushes to disk */
- uint64_t journal_bytes_flushed;
-
- /* PRO: log/journal bytes before compression */
- uint64_t journal_bytes_before_compression;
-
- /* PRO: log/journal bytes after compression */
- uint64_t journal_bytes_after_compression;
-
- /* PRO: record bytes before compression */
- uint64_t record_bytes_before_compression;
-
- /* PRO: record bytes after compression */
- uint64_t record_bytes_after_compression;
-
- /* PRO: key bytes before compression */
- uint64_t key_bytes_before_compression;
-
- /* PRO: key bytes after compression */
- uint64_t key_bytes_after_compression;
-
- /* PRO: set to the max. SIMD lane width (0 if SIMD is not available) */
- int simd_lane_width;
-
- /* btree metrics for leaf nodes */
- btree_metrics_t btree_leaf_metrics;
-
- /* btree metrics for internal nodes */
- btree_metrics_t btree_internal_metrics;
-
-} ham_env_metrics_t;
-
-/**
- * Retrieves the current metrics from an Environment
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_get_metrics(ham_env_t *env, ham_env_metrics_t *metrics);
-
-/**
- * Returns @ref HAM_TRUE if this hamsterdb library was compiled with debug
- * diagnostics, checks and asserts
- */
-HAM_EXPORT ham_bool_t HAM_CALLCONV
-ham_is_debug();
-
-/**
- * Returns @ref HAM_TRUE if this hamsterdb library is the commercial
- * closed-source "hamsterdb pro" edition
- */
-HAM_EXPORT ham_bool_t HAM_CALLCONV
-ham_is_pro();
-
-/**
- * Returns the end time of the evaluation period, if this is an evaluation
- * license of the commercial closed-source "hamsterdb pro";
- * returns 0 otherwise
- */
-HAM_EXPORT uint32_t HAM_CALLCONV
-ham_is_pro_evaluation();
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* HAM_HAMSTERDB_INT_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_ola.h b/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_ola.h
deleted file mode 100644
index f65b98b8b1..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_ola.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file hamsterdb_hola.h
- * @brief Include file for hamsterdb OnLine Analytical functions
- * @author Christoph Rupp, chris@crupp.de
- * @version 2.1.10
- *
- * This API is EXPERIMENTAL!! The interface is not yet stable.
- */
-
-#ifndef HAM_HAMSTERDB_OLA_H
-#define HAM_HAMSTERDB_OLA_H
-
-#include <ham/hamsterdb.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * A predicate function with context parameters returning a bool value.
- *
- * The predicate function is applied to various analytical functions
- * of this API and is generally used to select keys where a predicate applies.
- */
-typedef struct {
- /** A function pointer; receives a key, returns a bool */
- ham_bool_t (*predicate_func)(const void *key_data, uint16_t key_size,
- void *context);
-
- /** User-supplied context data */
- void *context;
-
-} hola_bool_predicate_t;
-
-
-/**
- * A structure which returns the result of an operation.
- *
- * For now, the result is either a @a uint64_t counter or a @a double value.
- * The @a type parameter specifies which one is used; @a type's value is
- * one of @a HAM_TYPE_UINT64 or @a HAM_TYPE_REAL64.
- */
-typedef struct {
- union {
- /** The result as a 64bit unsigned integer */
- uint64_t result_u64;
-
- /** The result as a 64bit real */
- double result_double;
- } u;
-
- /** The actual type in the union - one of the @a HAM_TYPE_* macros */
- int type;
-
-} hola_result_t;
-
-
-/**
- * Counts the keys in a Database
- *
- * This is a non-distinct count. If the Database has duplicate keys then
- * they are included in the count.
- *
- * The actual count is returned in @a result->u.result_u64. @a result->type
- * is set to @a HAM_TYPE_U64.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-hola_count(ham_db_t *db, ham_txn_t *txn, hola_result_t *result);
-
-/**
- * Selectively counts the keys in a Database
- *
- * This is a non-distinct count. If the Database has duplicate keys then
- * they are included in the count. The predicate function is applied to
- * each key. If it returns true then the key (and its duplicates) is included
- * in the count; otherwise the key is ignored.
- *
- * The actual count is returned in @a result->u.result_u64. @a result->type
- * is set to @a HAM_TYPE_U64.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-hola_count_if(ham_db_t *db, ham_txn_t *txn, hola_bool_predicate_t *pred,
- hola_result_t *result);
-
-/**
- * Counts the distinct keys in a Database
- *
- * This is a distinct count. If the Database has duplicate keys then
- * they are not included in the count.
- *
- * The actual count is returned in @a result->u.result_u64. @a result->type
- * is set to @a HAM_TYPE_U64.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-hola_count_distinct(ham_db_t *db, ham_txn_t *txn, hola_result_t *result);
-
-/**
- * Selectively counts the distinct keys in a Database
- *
- * This is a distinct count. If the Database has duplicate keys then
- * they are not included in the count. The predicate function is applied to
- * each key. If it returns true then the key is included in the count;
- * otherwise the key is ignored.
- *
- * The actual count is returned in @a result->u.result_u64. @a result->type
- * is set to @a HAM_TYPE_U64.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-hola_count_distinct_if(ham_db_t *db, ham_txn_t *txn,
- hola_bool_predicate_t *pred, hola_result_t *result);
-
-/**
- * Calculates the average of all keys.
- *
- * This is a non-distinct function and includes all duplicate keys.
- *
- * Internally, a 64bit counter is used for the calculation. This function
- * does not protect against an overflow of this counter.
- *
- * The keys in the database (@a db) have to be numeric, which means that
- * the Database's type must be one of @a HAM_TYPE_UINT8, @a HAM_TYPE_UINT16,
- * HAM_TYPE_UINT32, @a HAM_TYPE_UINT64, @a HAM_TYPE_REAL32 or
- * @a HAM_TYPE_REAL64.
- *
- * The actual result is returned in @a result->u.result_u64 or
- * @a result->u.result_double, depending on the Database's configuration.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- * @return @ref HAM_INV_PARAMETER if the database is not numeric
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-hola_average(ham_db_t *db, ham_txn_t *txn, hola_result_t *result);
-
-/**
- * Calculates the average of all keys where a predicate applies.
- *
- * This is a non-distinct function and includes all duplicate keys for which
- * the predicate function returns true.
- *
- * Internally, a 64bit counter is used for the calculation. This function
- * does not protect against an overflow of this counter.
- *
- * The keys in the database (@a db) have to be numeric, which means that
- * the Database's type must be one of @a HAM_TYPE_UINT8, @a HAM_TYPE_UINT16,
- * HAM_TYPE_UINT32, @a HAM_TYPE_UINT64, @a HAM_TYPE_REAL32 or
- * @a HAM_TYPE_REAL64.
- *
- * The actual result is returned in @a result->u.result_u64 or
- * @a result->u.result_double, depending on the Database's configuration.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- * @return @ref HAM_INV_PARAMETER if the database is not numeric
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-hola_average_if(ham_db_t *db, ham_txn_t *txn, hola_bool_predicate_t *pred,
- hola_result_t *result);
-
-/**
- * Calculates the sum of all keys.
- *
- * This is a non-distinct function and includes all duplicate keys.
- *
- * Internally, a 64bit counter is used for the calculation. This function
- * does not protect against an overflow of this counter.
- *
- * The keys in the database (@a db) have to be numeric, which means that
- * the Database's type must be one of @a HAM_TYPE_UINT8, @a HAM_TYPE_UINT16,
- * HAM_TYPE_UINT32, @a HAM_TYPE_UINT64, @a HAM_TYPE_REAL32 or
- * @a HAM_TYPE_REAL64.
- *
- * The actual result is returned in @a result->u.result_u64 or
- * @a result->u.result_double, depending on the Database's configuration.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- * @return @ref HAM_INV_PARAMETER if the database is not numeric
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-hola_sum(ham_db_t *db, ham_txn_t *txn, hola_result_t *result);
-
-/**
- * Calculates the sum of all keys where a predicate applies.
- *
- * This is a non-distinct function and includes all duplicate keys for which
- * the predicate function returns true.
- *
- * Internally, a 64bit counter is used for the calculation. This function
- * does not protect against an overflow of this counter.
- *
- * The keys in the database (@a db) have to be numeric, which means that
- * the Database's type must be one of @a HAM_TYPE_UINT8, @a HAM_TYPE_UINT16,
- * HAM_TYPE_UINT32, @a HAM_TYPE_UINT64, @a HAM_TYPE_REAL32 or
- * @a HAM_TYPE_REAL64.
- *
- * The actual result is returned in @a result->u.result_u64 or
- * @a result->u.result_double, depending on the Database's configuration.
- *
- * @return @ref HAM_SUCCESS upon success
- * @return @ref HAM_INV_PARAMETER if one of the parameters is NULL
- * @return @ref HAM_INV_PARAMETER if the database is not numeric
- */
-HAM_EXPORT ham_status_t HAM_CALLCONV
-hola_sum_if(ham_db_t *db, ham_txn_t *txn, hola_bool_predicate_t *pred,
- hola_result_t *result);
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* HAM_HAMSTERDB_OLA_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_srv.h b/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_srv.h
deleted file mode 100644
index 83ffef8f2e..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/include/ham/hamsterdb_srv.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef HAM_HAMSTERDB_SRV_H
-#define HAM_HAMSTERDB_SRV_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <ham/hamsterdb.h>
-
-/**
- * @defgroup ham_server hamsterdb Embedded Server
- * @{
- */
-
-/**
- * A configuration structure
- *
- * It is always recommended to initialize the full structure with zeroes
- * before using it.
- */
-typedef struct {
- /** The server port */
- uint16_t port;
-
- /* Path of the access log, or NULL if no log should be written
- * - currently NOT USED! */
- const char *access_log_path;
-
- /** Path of the error log, or NULL if no log should be written
- * - currently NOT USED! */
- const char *error_log_path;
-
-} ham_srv_config_t;
-
-/**
- * A server handle
- */
-struct ham_srv_t;
-typedef struct ham_srv_t ham_srv_t;
-
-/**
- * Initialize the server
- *
- * This function initializes a ham_srv_t handle and starts the hamsterdb
- * database server on the port specified in the configuration object.
- *
- * @param config A configuration structure
- * @param srv A pointer to a ham_srv_t pointer; will be allocated
- * if this function returns successfully
- *
- * @return HAM_SUCCESS on success
- * @return HAM_OUT_OF_MEMORY if memory could not be allocated
- */
-extern ham_status_t
-ham_srv_init(ham_srv_config_t *config, ham_srv_t **srv);
-
-/**
- * Add a hamsterdb Environment
- *
- * This function adds a new hamsterdb Environment to the server. The
- * Environment has to be initialized properly by the caller. It will be
- * served at ham://localhost:port/urlname, where @a port was specified
- * for @ref ham_srv_init and @a urlname is the third parameter to this
- * function.
- *
- * A client accessing this Environment will specify this URL as a filename,
- * and hamsterdb will transparently connect to this server.
- *
- * @param srv A valid ham_srv_t handle
- * @param env A valid hamsterdb Environment handle
- * @param urlname URL of this Environment
- *
- * @return HAM_SUCCESS on success
- * @return HAM_LIMITS_REACHED if more than the max. number of Environments
- * were added (default limit: 128)
- */
-extern ham_status_t
-ham_srv_add_env(ham_srv_t *srv, ham_env_t *env, const char *urlname);
-
-/*
- * Release memory and clean up
- *
- * @param srv A valid ham_srv_t handle
- *
- * @warning
- * This function will not close open handles (i.e. of Databases, Cursors
- * or Transactions). The caller has to close the remaining Environment
- * handles (@see ham_env_close).
- */
-extern void
-ham_srv_close(ham_srv_t *srv);
-
-/**
- * @}
- */
-
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* HAM_HAMSTERDB_SRV_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/include/ham/msstdint.h b/plugins/Dbx_kv/src/hamsterdb/include/ham/msstdint.h
deleted file mode 100644
index 4fe0ef9a9b..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/include/ham/msstdint.h
+++ /dev/null
@@ -1,259 +0,0 @@
-// ISO C9x compliant stdint.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
-//
-// Copyright (c) 2006-2013 Alexander Chemeris
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// 3. Neither the name of the product nor the names of its contributors may
-// be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_STDINT_H_ // [
-#define _MSC_STDINT_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#if _MSC_VER >= 1600 // [
-#include <stdint.h>
-#else // ] _MSC_VER >= 1600 [
-
-#include <limits.h>
-
-// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
-// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
-// or compiler give many errors like this:
-// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
-#ifdef __cplusplus
-extern "C" {
-#endif
-# include <wchar.h>
-#ifdef __cplusplus
-}
-#endif
-
-// Define _W64 macros to mark types changing their size, like intptr_t.
-#ifndef _W64
-# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
-# define _W64 __w64
-# else
-# define _W64
-# endif
-#endif
-
-
-// 7.18.1 Integer types
-
-// 7.18.1.1 Exact-width integer types
-
-// Visual Studio 6 and Embedded Visual C++ 4 doesn't
-// realize that, e.g. char has the same size as __int8
-// so we give up on __intX for them.
-#if (_MSC_VER < 1300)
- typedef signed char int8_t;
- typedef signed short int16_t;
- typedef signed int int32_t;
- typedef unsigned char uint8_t;
- typedef unsigned short uint16_t;
- typedef unsigned int uint32_t;
-#else
- typedef signed __int8 int8_t;
- typedef signed __int16 int16_t;
- typedef signed __int32 int32_t;
- typedef unsigned __int8 uint8_t;
- typedef unsigned __int16 uint16_t;
- typedef unsigned __int32 uint32_t;
-#endif
-typedef signed __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-
-
-// 7.18.1.2 Minimum-width integer types
-typedef int8_t int_least8_t;
-typedef int16_t int_least16_t;
-typedef int32_t int_least32_t;
-typedef int64_t int_least64_t;
-typedef uint8_t uint_least8_t;
-typedef uint16_t uint_least16_t;
-typedef uint32_t uint_least32_t;
-typedef uint64_t uint_least64_t;
-
-// 7.18.1.3 Fastest minimum-width integer types
-typedef int8_t int_fast8_t;
-typedef int16_t int_fast16_t;
-typedef int32_t int_fast32_t;
-typedef int64_t int_fast64_t;
-typedef uint8_t uint_fast8_t;
-typedef uint16_t uint_fast16_t;
-typedef uint32_t uint_fast32_t;
-typedef uint64_t uint_fast64_t;
-
-// 7.18.1.4 Integer types capable of holding object pointers
-#ifdef _WIN64 // [
- typedef signed __int64 intptr_t;
- typedef unsigned __int64 uintptr_t;
-#else // _WIN64 ][
- typedef _W64 signed int intptr_t;
- typedef _W64 unsigned int uintptr_t;
-#endif // _WIN64 ]
-
-// 7.18.1.5 Greatest-width integer types
-typedef int64_t intmax_t;
-typedef uint64_t uintmax_t;
-
-
-// 7.18.2 Limits of specified-width integer types
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
-
-// 7.18.2.1 Limits of exact-width integer types
-#define INT8_MIN ((int8_t)_I8_MIN)
-#define INT8_MAX _I8_MAX
-#define INT16_MIN ((int16_t)_I16_MIN)
-#define INT16_MAX _I16_MAX
-#define INT32_MIN ((int32_t)_I32_MIN)
-#define INT32_MAX _I32_MAX
-#define INT64_MIN ((int64_t)_I64_MIN)
-#define INT64_MAX _I64_MAX
-#define UINT8_MAX _UI8_MAX
-#define UINT16_MAX _UI16_MAX
-#define UINT32_MAX _UI32_MAX
-#define UINT64_MAX _UI64_MAX
-
-// 7.18.2.2 Limits of minimum-width integer types
-#define INT_LEAST8_MIN INT8_MIN
-#define INT_LEAST8_MAX INT8_MAX
-#define INT_LEAST16_MIN INT16_MIN
-#define INT_LEAST16_MAX INT16_MAX
-#define INT_LEAST32_MIN INT32_MIN
-#define INT_LEAST32_MAX INT32_MAX
-#define INT_LEAST64_MIN INT64_MIN
-#define INT_LEAST64_MAX INT64_MAX
-#define UINT_LEAST8_MAX UINT8_MAX
-#define UINT_LEAST16_MAX UINT16_MAX
-#define UINT_LEAST32_MAX UINT32_MAX
-#define UINT_LEAST64_MAX UINT64_MAX
-
-// 7.18.2.3 Limits of fastest minimum-width integer types
-#define INT_FAST8_MIN INT8_MIN
-#define INT_FAST8_MAX INT8_MAX
-#define INT_FAST16_MIN INT16_MIN
-#define INT_FAST16_MAX INT16_MAX
-#define INT_FAST32_MIN INT32_MIN
-#define INT_FAST32_MAX INT32_MAX
-#define INT_FAST64_MIN INT64_MIN
-#define INT_FAST64_MAX INT64_MAX
-#define UINT_FAST8_MAX UINT8_MAX
-#define UINT_FAST16_MAX UINT16_MAX
-#define UINT_FAST32_MAX UINT32_MAX
-#define UINT_FAST64_MAX UINT64_MAX
-
-// 7.18.2.4 Limits of integer types capable of holding object pointers
-#ifdef _WIN64 // [
-# define INTPTR_MIN INT64_MIN
-# define INTPTR_MAX INT64_MAX
-# define UINTPTR_MAX UINT64_MAX
-#else // _WIN64 ][
-# define INTPTR_MIN INT32_MIN
-# define INTPTR_MAX INT32_MAX
-# define UINTPTR_MAX UINT32_MAX
-#endif // _WIN64 ]
-
-// 7.18.2.5 Limits of greatest-width integer types
-#define INTMAX_MIN INT64_MIN
-#define INTMAX_MAX INT64_MAX
-#define UINTMAX_MAX UINT64_MAX
-
-// 7.18.3 Limits of other integer types
-
-#ifdef _WIN64 // [
-# define PTRDIFF_MIN _I64_MIN
-# define PTRDIFF_MAX _I64_MAX
-#else // _WIN64 ][
-# define PTRDIFF_MIN _I32_MIN
-# define PTRDIFF_MAX _I32_MAX
-#endif // _WIN64 ]
-
-#define SIG_ATOMIC_MIN INT_MIN
-#define SIG_ATOMIC_MAX INT_MAX
-
-#ifndef SIZE_MAX // [
-# ifdef _WIN64 // [
-# define SIZE_MAX _UI64_MAX
-# else // _WIN64 ][
-# define SIZE_MAX _UI32_MAX
-# endif // _WIN64 ]
-#endif // SIZE_MAX ]
-
-// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
-#ifndef WCHAR_MIN // [
-# define WCHAR_MIN 0
-#endif // WCHAR_MIN ]
-#ifndef WCHAR_MAX // [
-# define WCHAR_MAX _UI16_MAX
-#endif // WCHAR_MAX ]
-
-#define WINT_MIN 0
-#define WINT_MAX _UI16_MAX
-
-#endif // __STDC_LIMIT_MACROS ]
-
-
-// 7.18.4 Limits of other integer types
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
-
-// 7.18.4.1 Macros for minimum-width integer constants
-
-#define INT8_C(val) val##i8
-#define INT16_C(val) val##i16
-#define INT32_C(val) val##i32
-#define INT64_C(val) val##i64
-
-#define UINT8_C(val) val##ui8
-#define UINT16_C(val) val##ui16
-#define UINT32_C(val) val##ui32
-#define UINT64_C(val) val##ui64
-
-// 7.18.4.2 Macros for greatest-width integer constants
-// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
-// Check out Issue 9 for the details.
-#ifndef INTMAX_C // [
-# define INTMAX_C INT64_C
-#endif // INTMAX_C ]
-#ifndef UINTMAX_C // [
-# define UINTMAX_C UINT64_C
-#endif // UINTMAX_C ]
-
-#endif // __STDC_CONSTANT_MACROS ]
-
-#endif // _MSC_VER >= 1600 ]
-
-#endif // _MSC_STDINT_H_ ]
diff --git a/plugins/Dbx_kv/src/hamsterdb/include/ham/types.h b/plugins/Dbx_kv/src/hamsterdb/include/ham/types.h
deleted file mode 100644
index 54d75aa7e0..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/include/ham/types.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file types.h
- * @brief Portable typedefs for hamsterdb Embedded Storage.
- * @author Christoph Rupp, chris@crupp.de
- *
- */
-
-#ifndef HAM_TYPES_H
-#define HAM_TYPES_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Check the operating system and word size
- */
-#ifdef WIN32
-# undef HAM_OS_WIN32
-# define HAM_OS_WIN32 1
-# ifdef WIN64
-# undef HAM_64BIT
-# define HAM_64BIT 1
-# elif WIN32
-# undef HAM_32BIT
-# define HAM_32BIT 1
-# else
-# error "Neither WIN32 nor WIN64 defined!"
-# endif
-#else /* posix? */
-# undef HAM_OS_POSIX
-# define HAM_OS_POSIX 1
-# if defined(__LP64__) || defined(__LP64) || __WORDSIZE == 64
-# undef HAM_64BIT
-# define HAM_64BIT 1
-# else
-# undef HAM_32BIT
-# define HAM_32BIT 1
-# endif
-#endif
-
-#if defined(HAM_OS_POSIX) && defined(HAM_OS_WIN32)
-# error "Unknown arch - neither HAM_OS_POSIX nor HAM_OS_WIN32 defined"
-#endif
-
-/*
- * improve memory debugging on WIN32 by using crtdbg.h (only MSVC
- * compiler and debug builds!)
- *
- * make sure crtdbg.h is loaded before malloc.h!
- */
-#if defined(_MSC_VER) && defined(HAM_OS_WIN32)
-# if (defined(WIN32) || defined(__WIN32)) && !defined(UNDER_CE)
-# if defined(DEBUG) || defined(_DEBUG)
-# ifndef _CRTDBG_MAP_ALLOC
-# define _CRTDBG_MAP_ALLOC 1
-# endif
-# endif
-# include <crtdbg.h>
-# include <malloc.h>
-# endif
-#endif
-
-/*
- * Create the EXPORT macro for Microsoft Visual C++
- */
-#ifndef HAM_EXPORT
-# ifdef _MSC_VER
-# define HAM_EXPORT __declspec(dllexport)
-# else
-# define HAM_EXPORT extern
-# endif
-#endif
-
-/*
- * The default calling convention is cdecl
- */
-#ifndef HAM_CALLCONV
-# define HAM_CALLCONV
-#endif
-
-/*
- * Common typedefs. Since stdint.h is not available on older versions of
- * Microsoft Visual Studio, they get declared here.
- * http://msinttypes.googlecode.com/svn/trunk/stdint.h
- */
-#if _MSC_VER
-# include <ham/msstdint.h>
-#else
-# include <stdint.h>
-#endif
-
-/* Deprecated typedefs; used prior to 2.1.9. Please do not use them! */
-typedef int64_t ham_s64_t;
-typedef uint64_t ham_u64_t;
-typedef int32_t ham_s32_t;
-typedef uint32_t ham_u32_t;
-typedef int16_t ham_s16_t;
-typedef uint16_t ham_u16_t;
-typedef int8_t ham_s8_t;
-typedef uint8_t ham_u8_t;
-
-/*
- * Undefine macros to avoid macro redefinitions
- */
-#undef HAM_INVALID_FD
-#undef HAM_FALSE
-#undef HAM_TRUE
-
-/**
- * a boolean type
- */
-typedef int ham_bool_t;
-#define HAM_FALSE 0
-#define HAM_TRUE (!HAM_FALSE)
-
-/**
- * typedef for error- and status-code
- */
-typedef int ham_status_t;
-
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* HAM_TYPES_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/0root/root.h b/plugins/Dbx_kv/src/hamsterdb/src/0root/root.h
deleted file mode 100644
index 38e003b7c7..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/0root/root.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The root of all evil. This header file must be included *before all others*!
- *
- * @thread_safe: yes
- * @exception_safe: nothrow
- */
-
-#ifndef HAM_ROOT_H
-#define HAM_ROOT_H
-
-//#define HAM_ENABLE_HELGRIND 1
-
-// some feature macros in config.h must be set *before* inclusion
-// of any system headers to have the desired effect.
-// assume sane default values if there is no config.h.
-#ifdef HAVE_CONFIG_H
-# include "../config.h"
-#else
-# define HAVE_MMAP 1
-# define HAVE_UNMMAP 1
-# define HAVE_PREAD 1
-# define HAVE_PWRITE 1
-#endif
-
-#include "ham/types.h"
-
-// check for a valid build
-#if (!defined(HAM_DEBUG))
-# if (defined(_DEBUG) || defined(DEBUG))
-# define HAM_DEBUG 1
-# endif
-#endif
-
-// the default cache size is 2 MB
-#define HAM_DEFAULT_CACHE_SIZE (2 * 1024 * 1024)
-
-// the default page size is 16 kb
-#define HAM_DEFAULT_PAGE_SIZE (16 * 1024)
-
-// use tcmalloc?
-#if HAVE_GOOGLE_TCMALLOC_H == 1
-# if HAVE_LIBTCMALLOC_MINIMAL == 1
-# define HAM_USE_TCMALLOC 1
-# endif
-#endif
-
-#include <stddef.h>
-#define OFFSETOF(type, member) offsetof(type, member)
-
-// helper macros to improve CPU branch prediction
-#if defined __GNUC__
-# define likely(x) __builtin_expect ((x), 1)
-# define unlikely(x) __builtin_expect ((x), 0)
-#else
-# define likely(x) (x)
-# define unlikely(x) (x)
-#endif
-
-#ifdef WIN32
-// MSVC: disable warning about use of 'this' in base member initializer list
-# pragma warning(disable:4355)
-# define WIN32_MEAN_AND_LEAN
-# include <windows.h>
-#endif
-
-// some compilers define min and max as macros; this leads to errors
-// when using std::min and std::max
-#ifdef min
-# undef min
-#endif
-
-#ifdef max
-# undef max
-#endif
-
-// a macro to cast pointers to u64 and vice versa to avoid compiler
-// warnings if the sizes of ptr and u64 are not equal
-#if defined(HAM_32BIT) && (!defined(_MSC_VER))
-# define U64_TO_PTR(p) (uint8_t *)(int)p
-# define PTR_TO_U64(p) (uint64_t)(int)p
-#else
-# define U64_TO_PTR(p) p
-# define PTR_TO_U64(p) p
-#endif
-
-#endif /* HAM_ROOT_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/abi.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/abi.h
deleted file mode 100644
index 57c086f24c..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/abi.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Returns the demangled name of a class
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_ABI_H
-#define HAM_ABI_H
-
-#include "0root/root.h"
-
-#ifdef HAVE_GCC_ABI_DEMANGLE
-# include <cxxabi.h>
-#endif
-
-#include <string>
-#include <stdlib.h>
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-template<class T> inline std::string
-get_classname(const T& t)
-{
-#ifdef HAVE_GCC_ABI_DEMANGLE
- int status;
- const std::type_info &ti = typeid(t);
- char *name = abi::__cxa_demangle(ti.name(), 0, 0, &status);
- if (!name)
- return ("");
- if (status) {
- ::free(name);
- return ("");
- }
- std::string s = name;
- ::free(name);
- return (s);
-#else
- return ("");
-#endif
-}
-
-} // namespace hamsterdb
-
-#endif /* HAM_ABI_H */
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/dynamic_array.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/dynamic_array.h
deleted file mode 100644
index 8cd8e2c8b7..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/dynamic_array.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A class managing a dynamically sized array for arbitrary types
- *
- * @exception_safe: strong
- * @thread_safe: no
- */
-
-#ifndef HAM_DYNAMIC_ARRAY_H
-#define HAM_DYNAMIC_ARRAY_H
-
-#include "0root/root.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1mem/mem.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/*
- * The DynamicArray class is a dynamic, resizable array. The internal memory
- * is released when the DynamicArray instance is destructed.
- *
- * Unlike std::vector, the DynamicArray uses libc functions for constructing,
- * copying and initializing elements.
- */
-template<typename T>
-class DynamicArray
-{
- public:
- typedef T value_t;
- typedef T *pointer_t;
-
- DynamicArray(size_t size = 0)
- : m_ptr(0), m_size(0), m_own(true) {
- resize(size);
- }
-
- DynamicArray(size_t size, uint8_t fill_byte)
- : m_ptr(0), m_size(0), m_own(true) {
- resize(size);
- if (m_ptr)
- ::memset(m_ptr, fill_byte, sizeof(T) * m_size);
- }
-
- ~DynamicArray() {
- clear();
- }
-
- void append(const T *ptr, size_t size) {
- size_t old_size = m_size;
- T *p = (T *)resize(m_size + size);
- ::memcpy(p + old_size, ptr, sizeof(T) * size);
- }
-
- void copy(const T *ptr, size_t size) {
- resize(size);
- ::memcpy(m_ptr, ptr, sizeof(T) * size);
- m_size = size;
- }
-
- void overwrite(uint32_t position, const T *ptr, size_t size) {
- ::memcpy(((uint8_t *)m_ptr) + position, ptr, sizeof(T) * size);
- }
-
- T *resize(size_t size) {
- if (size > m_size) {
- m_ptr = Memory::reallocate<T>(m_ptr, sizeof(T) * size);
- m_size = size;
- }
- return (m_ptr);
- }
-
- T *resize(size_t size, uint8_t fill_byte) {
- resize(size);
- if (m_ptr)
- ::memset(m_ptr, fill_byte, sizeof(T) * size);
- return (m_ptr);
- }
-
- size_t get_size() const {
- return (m_size);
- }
-
- void set_size(size_t size) {
- m_size = size;
- }
-
- T *get_ptr() {
- return (m_ptr);
- }
-
- const T *get_ptr() const {
- return (m_ptr);
- }
-
- void assign(T *ptr, size_t size) {
- clear();
- m_ptr = ptr;
- m_size = size;
- }
-
- void clear(bool release_memory = true) {
- if (m_own && release_memory)
- Memory::release(m_ptr);
- m_ptr = 0;
- m_size = 0;
- }
-
- bool is_empty() const {
- return (m_size == 0);
- }
-
- void disown() {
- m_own = false;
- }
-
- private:
- // Pointer to the data
- T *m_ptr;
-
- // The size of the array
- size_t m_size;
-
- // True if the destructor should free the pointer
- bool m_own;
-};
-
-/*
- * A ByteArray is a DynamicArray for bytes
- */
-typedef DynamicArray<uint8_t> ByteArray;
-
-} // namespace hamsterdb
-
-#endif // HAM_DYNAMIC_ARRAY_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/error.cc b/plugins/Dbx_kv/src/hamsterdb/src/1base/error.cc
deleted file mode 100644
index c7ebc530bb..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/error.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/util.h"
-#include "1globals/globals.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-void (*ham_test_abort)(void);
-
-static int
-dbg_snprintf(char *str, size_t size, const char *format, ...)
-{
- int s;
-
- va_list ap;
- va_start(ap, format);
- s = util_vsnprintf(str, size, format, ap);
- va_end(ap);
-
- return (s);
-}
-
-void HAM_CALLCONV
-default_errhandler(int level, const char *message)
-{
-#ifndef HAM_DEBUG
- if (level == HAM_DEBUG_LEVEL_DEBUG)
- return;
-#endif
- fprintf(stderr, "%s\n", message);
-}
-
-void
-dbg_prepare(int level, const char *file, int line, const char *function,
- const char *expr)
-{
- Globals::ms_error_level = level;
- Globals::ms_error_file = file;
- Globals::ms_error_line = line;
- Globals::ms_error_expr = expr;
- Globals::ms_error_function = function;
-}
-
-void
-dbg_log(const char *format, ...)
-{
- int s = 0;
- char buffer[1024 * 4];
-
- va_list ap;
- va_start(ap, format);
-#ifdef HAM_DEBUG
- s = dbg_snprintf(buffer, sizeof(buffer), "%s[%d]: ",
- Globals::ms_error_file, Globals::ms_error_line);
- util_vsnprintf(buffer + s, sizeof(buffer) - s, format, ap);
-#else
- if (Globals::ms_error_function)
- s = dbg_snprintf(buffer, sizeof(buffer), "%s: ",
- Globals::ms_error_function);
- util_vsnprintf(buffer + s, sizeof(buffer) - s, format, ap);
-#endif
- va_end(ap);
-
- Globals::ms_error_handler(Globals::ms_error_level, buffer);
-}
-
-/* coverity[+kill] */
-void
-dbg_verify_failed(int level, const char *file, int line, const char *function,
- const char *expr)
-{
- char buffer[1024 * 4];
-
- if (!expr)
- expr = "(none)";
-
- dbg_snprintf(buffer, sizeof(buffer),
- "ASSERT FAILED in file %s, line %d:\n\t\"%s\"\n",
- file, line, expr);
- buffer[sizeof(buffer) - 1] = '\0';
-
- Globals::ms_error_handler(Globals::ms_error_level, buffer);
-
- if (ham_test_abort)
- ham_test_abort();
- else
- abort();
-}
-
-} // namespace hamsterdb
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/error.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/error.h
deleted file mode 100644
index f02a8a8c24..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/error.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Error handling routines, assert macros, logging facilities
- *
- * @exception_safe: nothrow
- * @thread_safe: no (b/c of the logging macros)
- */
-
-#ifndef HAM_ERROR_H
-#define HAM_ERROR_H
-
-#include "0root/root.h"
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// A generic exception for storing a status code
-//
-struct Exception
-{
- Exception(ham_status_t st)
- : code(st) {
- }
-
- ham_status_t code;
-};
-
-// the default error handler
-void HAM_CALLCONV
-default_errhandler(int level, const char *message);
-
-extern void
-dbg_prepare(int level, const char *file, int line, const char *function,
- const char *expr);
-
-extern void
-dbg_log(const char *format, ...);
-
-#define CLANG_ANALYZER_NORETURN
-#if __clang__
-# if __has_feature(attribute_analyzer_noreturn)
-# undef CLANG_ANALYZER_NORETURN
-# define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
-# endif
-#endif
-
-// causes the actual abort()
-extern void
-dbg_verify_failed(int level, const char *file, int line,
- const char *function, const char *expr) CLANG_ANALYZER_NORETURN;
-
-// a hook for unittests; will be triggered when an assert fails
-extern void (*ham_test_abort)();
-
-// if your compiler does not support __FUNCTION__, you can define it here:
-// #define __FUNCTION__ 0
-
-/*
- * in debug mode we write trace()-messages to stderr, and assert()
- * is enabled.
- *
- * not every preprocessor supports ellipsis as macro-arguments -
- * therefore we have to use brackets, so preprocessors treat multiple
- * arguments like a single argument. and we need to lock the output,
- * otherwise we are not thread-safe. this is super-ugly.
- */
-#ifdef HAM_DEBUG
-# define ham_assert(e) while (!(e)) { \
- hamsterdb::dbg_verify_failed(HAM_DEBUG_LEVEL_FATAL, __FILE__, \
- __LINE__, __FUNCTION__, #e); \
- break; \
- }
-#else /* !HAM_DEBUG */
-# define ham_assert(e) (void)0
-#endif /* HAM_DEBUG */
-
-// ham_log() and ham_verify() are available in every build
-#define ham_trace(f) do { \
- hamsterdb::dbg_prepare(HAM_DEBUG_LEVEL_DEBUG, __FILE__, \
- __LINE__, __FUNCTION__, 0); \
- hamsterdb::dbg_log f; \
- } while (0)
-
-#define ham_log(f) do { \
- hamsterdb::dbg_prepare(HAM_DEBUG_LEVEL_NORMAL, __FILE__, \
- __LINE__, __FUNCTION__, 0); \
- hamsterdb::dbg_log f; \
- } while (0)
-
-#define ham_verify(e) if (!(e)) { \
- hamsterdb::dbg_verify_failed(HAM_DEBUG_LEVEL_FATAL, __FILE__, \
- __LINE__, __FUNCTION__, #e); \
- }
-
-} // namespace hamsterdb
-
-#endif /* HAM_ERROR_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/mutex.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/mutex.h
deleted file mode 100644
index 0e09ae046c..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/mutex.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A operating-system dependent mutex
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_MUTEX_H
-#define HAM_MUTEX_H
-
-#include "0root/root.h"
-
-#define BOOST_ALL_NO_LIB // disable MSVC auto-linking
-#include <boost/version.hpp>
-#include <boost/thread/mutex.hpp>
-#include <boost/thread/recursive_mutex.hpp>
-#include <boost/thread/thread.hpp>
-#include <boost/thread/tss.hpp>
-#include <boost/thread/condition.hpp>
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-typedef boost::mutex::scoped_lock ScopedLock;
-typedef boost::thread Thread;
-typedef boost::condition Condition;
-typedef boost::mutex Mutex;
-typedef boost::recursive_mutex RecursiveMutex;
-
-} // namespace hamsterdb
-
-#endif /* HAM_MUTEX_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/packstart.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/packstart.h
deleted file mode 100644
index 3a6b1981a7..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/packstart.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Macros for packing structures; should work with most compilers.
- *
- * Example usage:
- *
- * #include "packstart.h"
- *
- * typedef HAM_PACK_0 struct HAM_PACK_1 foo {
- * int bar;
- * } HAM_PACK_2 foo_t;
- *
- * #include "packstop.h"
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-/* This class does NOT include root.h! */
-
-#ifdef __GNUC__
-# if (((__GNUC__==2) && (__GNUC_MINOR__>=7)) || (__GNUC__>2))
-# define HAM_PACK_2 __attribute__ ((packed))
-# define _NEWGNUC_
-# endif
-#endif
-
-#ifdef __WATCOMC__
-# define HAM_PACK_0 _Packed
-#endif
-
-#if (defined(_MSC_VER) && (_MSC_VER >= 900)) || defined(__BORLANDC__)
-# define _NEWMSC_
-#endif
-#if !defined(_NEWGNUC_) && !defined(__WATCOMC__) && !defined(_NEWMSC_)
-# pragma pack(1)
-#endif
-#ifdef _NEWMSC_
-# pragma pack(push, 1)
-# define HAM_PACK_2 __declspec(align(1))
-#endif
-
-#if defined(_NEWMSC_) && !defined(_WIN32_WCE)
-# pragma pack(push, 1)
-# define HAM_PACK_2 __declspec(align(1))
-#endif
-
-#ifndef HAM_PACK_0
-# define HAM_PACK_0
-#endif
-
-#ifndef HAM_PACK_1
-# define HAM_PACK_1
-#endif
-
-#ifndef HAM_PACK_2
-# define HAM_PACK_2
-#endif
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/packstop.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/packstop.h
deleted file mode 100644
index a32566f4f9..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/packstop.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Macros for packing structures; should work with most compilers.
- * See packstart.h for a usage example.
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-/* This class does NOT include root.h! */
-
-#if !defined(_NEWGNUC_) && !defined(__WATCOMC__) && !defined(_NEWMSC_)
-# pragma pack()
-#endif
-#ifdef _NEWMSC_
-# pragma pack(pop)
-#endif
-#if defined(_NEWMSC_) && !defined(_WIN32_WCE)
-# pragma pack(pop)
-#endif
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/pickle.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/pickle.h
deleted file mode 100644
index 8927e08910..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/pickle.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Class for pickling/unpickling data to a buffer
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_PICKLE_H
-#define HAM_PICKLE_H
-
-#include "0root/root.h"
-
-#include "ham/types.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Pickle {
- /* encodes a uint64 number and stores it in |p|; returns the number of
- * bytes used */
- static size_t encode_u64(uint8_t *p, uint64_t n) {
- if (n <= 0xf) {
- *p = (uint8_t)n;
- return (1);
- }
- if (n <= 0xff) {
- *(p + 1) = (n & 0xf0) >> 4;
- *(p + 0) = n & 0xf;
- return (2);
- }
- if (n <= 0xfff) {
- *(p + 2) = (n & 0xf00) >> 8;
- *(p + 1) = (n & 0xf0) >> 4;
- *(p + 0) = n & 0xf;
- return (3);
- }
- if (n <= 0xffff) {
- *(p + 3) = (n & 0xf000) >> 12;
- *(p + 2) = (n & 0xf00) >> 8;
- *(p + 1) = (n & 0xf0) >> 4;
- *(p + 0) = n & 0xf;
- return (4);
- }
- if (n <= 0xfffff) {
- *(p + 4) = (n & 0xf0000) >> 16;
- *(p + 3) = (n & 0xf000) >> 12;
- *(p + 2) = (n & 0xf00) >> 8;
- *(p + 1) = (n & 0xf0) >> 4;
- *(p + 0) = n & 0xf;
- return (5);
- }
- if (n <= 0xffffff) {
- *(p + 5) = (n & 0xf00000) >> 24;
- *(p + 4) = (n & 0xf0000) >> 16;
- *(p + 3) = (n & 0xf000) >> 12;
- *(p + 2) = (n & 0xf00) >> 8;
- *(p + 1) = (n & 0xf0) >> 4;
- *(p + 0) = n & 0xf;
- return (6);
- }
- if (n <= 0xfffffff) {
- *(p + 6) = (n & 0xf000000) >> 32;
- *(p + 5) = (n & 0xf00000) >> 24;
- *(p + 4) = (n & 0xf0000) >> 16;
- *(p + 3) = (n & 0xf000) >> 12;
- *(p + 2) = (n & 0xf00) >> 8;
- *(p + 1) = (n & 0xf0) >> 4;
- *(p + 0) = n & 0xf;
- return (7);
- }
- *(p + 7) = (n & 0xf0000000) >> 36;
- *(p + 6) = (n & 0xf000000) >> 32;
- *(p + 5) = (n & 0xf00000) >> 24;
- *(p + 4) = (n & 0xf0000) >> 16;
- *(p + 3) = (n & 0xf000) >> 12;
- *(p + 2) = (n & 0xf00) >> 8;
- *(p + 1) = (n & 0xf0) >> 4;
- *(p + 0) = n & 0xf;
- return (8);
- }
-
- /* decodes and returns a pickled number of |len| bytes */
- static uint64_t decode_u64(size_t len, uint8_t *p) {
- uint64_t ret = 0;
-
- for (size_t i = 0; i < len - 1; i++) {
- ret += *(p + (len - i - 1));
- ret <<= 4;
- }
-
- // last assignment is without *= 10
- return (ret + *p);
- }
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_PICKLE_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/scoped_ptr.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/scoped_ptr.h
deleted file mode 100644
index b920059aad..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/scoped_ptr.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A (stupid) smart pointer
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_SCOPED_PTR_H
-#define HAM_SCOPED_PTR_H
-
-#include "0root/root.h"
-
-#define BOOST_ALL_NO_LIB // disable MSVC auto-linking
-#include <boost/scoped_ptr.hpp>
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-template <typename T>
-struct ScopedPtr : public boost::scoped_ptr<T>
-{
- ScopedPtr()
- : boost::scoped_ptr<T>() {
- }
-
- ScopedPtr(T *t)
- : boost::scoped_ptr<T>(t) {
- }
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_SCOPED_PTR_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/spinlock.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/spinlock.h
deleted file mode 100644
index e9d917212c..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/spinlock.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A fast spinlock, taken from the boost documentation
- * http://www.boost.org/doc/libs/1_57_0/doc/html/atomic/usage_examples.html
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_SPINLOCK_H
-#define HAM_SPINLOCK_H
-
-#include "0root/root.h"
-
-#include <stdio.h>
-#ifndef HAM_OS_WIN32
-# include <sched.h>
-# include <unistd.h>
-#endif
-#include <boost/atomic.hpp>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1base/mutex.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-#ifdef HAM_ENABLE_HELGRIND
-typedef Mutex Spinlock;
-#else
-
-class Spinlock {
- typedef enum {
- kLocked,
- kUnlocked,
- kSpinThreshold = 10
- } LockState;
-
- public:
- Spinlock()
- : m_state(kUnlocked) {
- }
-
- // Need user-defined copy constructor because boost::atomic<> is not
- // copyable
- Spinlock(const Spinlock &other)
- : m_state(other.m_state.load()) {
- }
-
- void lock() {
- int k = 0;
- while (m_state.exchange(kLocked, boost::memory_order_acquire) == kLocked)
- spin(++k);
- }
-
- void unlock() {
- m_state.store(kUnlocked, boost::memory_order_release);
- }
-
- bool try_lock() {
- return (m_state.exchange(kLocked, boost::memory_order_acquire)
- != kLocked);
- }
-
- static void spin(int loop) {
- if (loop < kSpinThreshold) {
-#ifdef HAM_OS_WIN32
- ::Sleep(0);
-#elif HAVE_SCHED_YIELD
- ::sched_yield();
-#else
- ham_assert(!"Please implement me");
-#endif
- }
- else {
-#ifdef HAM_OS_WIN32
- ::Sleep(25);
-#elif HAVE_USLEEP
- ::usleep(25);
-#else
- ham_assert(!"Please implement me");
-#endif
- }
- }
-
- private:
- boost::atomic<LockState> m_state;
-};
-#endif // HAM_ENABLE_HELGRIND
-
-class ScopedSpinlock {
- public:
- ScopedSpinlock(Spinlock &lock)
- : m_spinlock(lock) {
- m_spinlock.lock();
- }
-
- ~ScopedSpinlock() {
- m_spinlock.unlock();
- }
-
- private:
- Spinlock &m_spinlock;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_SPINLOCK_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/util.cc b/plugins/Dbx_kv/src/hamsterdb/src/1base/util.cc
deleted file mode 100644
index 828fb3ec9d..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/util.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/util.h"
-
-namespace hamsterdb {
-
-int
-util_vsnprintf(char *str, size_t size, const char *format, va_list ap)
-{
-#if defined(HAM_OS_POSIX)
- return vsnprintf(str, size, format, ap);
-#elif defined(HAM_OS_WIN32)
- return _vsnprintf(str, size, format, ap);
-#else
- (void)size;
- return (vsprintf(str, format, ap));
-#endif
-}
-
-} // namespace hamsterdb
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1base/util.h b/plugins/Dbx_kv/src/hamsterdb/src/1base/util.h
deleted file mode 100644
index 4e7857bd34..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1base/util.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Misc. utility classes and functions
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_UTIL_H
-#define HAM_UTIL_H
-
-#include "0root/root.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// vsnprintf replacement/wrapper
-//
-// uses vsprintf on platforms which do not define vsnprintf
-//
-extern int
-util_vsnprintf(char *str, size_t size, const char *format, va_list ap);
-
-//
-// snprintf replacement/wrapper
-//
-// uses sprintf on platforms which do not define snprintf
-//
-#ifndef HAM_OS_POSIX
-# define util_snprintf _snprintf
-#else
-# define util_snprintf snprintf
-#endif
-
-} // namespace hamsterdb
-
-#endif // HAM_UTIL_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1errorinducer/errorinducer.cc b/plugins/Dbx_kv/src/hamsterdb/src/1errorinducer/errorinducer.cc
deleted file mode 100644
index 9f343c5ed6..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1errorinducer/errorinducer.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1errorinducer/errorinducer.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-ErrorInducer ErrorInducer::ms_instance;
-bool ErrorInducer::ms_is_active = false;
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1errorinducer/errorinducer.h b/plugins/Dbx_kv/src/hamsterdb/src/1errorinducer/errorinducer.h
deleted file mode 100644
index 4a7b2107af..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1errorinducer/errorinducer.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Facility to simulate errors
- *
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_ERRORINDUCER_H
-#define HAM_ERRORINDUCER_H
-
-#include "0root/root.h"
-
-#include <string.h>
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-// a macro to invoke errors
-#define HAM_INDUCE_ERROR(id) \
- while (ErrorInducer::is_active()) { \
- ham_status_t st = ErrorInducer::get_instance()->induce(id); \
- if (st) \
- throw Exception(st); \
- break; \
- }
-
-namespace hamsterdb {
-
-class ErrorInducer {
- struct State {
- State()
- : loops(0), error(HAM_INTERNAL_ERROR) {
- }
-
- int loops;
- ham_status_t error;
- };
-
- public:
- enum Action {
- // simulates a failure in Changeset::flush
- kChangesetFlush,
-
- // simulates a hang in hamserver-connect
- kServerConnect,
-
- kMaxActions
- };
-
- // Activates or deactivates the error inducer
- static void activate(bool active) {
- ms_is_active = active;
- }
-
- // Returns true if the error inducer is active
- static bool is_active() {
- return (ms_is_active);
- }
-
- // Returns the singleton instance
- static ErrorInducer *get_instance() {
- return (&ms_instance);
- }
-
- ErrorInducer() {
- memset(&m_state[0], 0, sizeof(m_state));
- }
-
- void add(Action action, int loops,
- ham_status_t error = HAM_INTERNAL_ERROR) {
- m_state[action].loops = loops;
- m_state[action].error = error;
- }
-
- ham_status_t induce(Action action) {
- ham_assert(m_state[action].loops >= 0);
- if (m_state[action].loops > 0 && --m_state[action].loops == 0)
- return (m_state[action].error);
- return (0);
- }
-
- private:
- State m_state[kMaxActions];
-
- // The singleton instance
- static ErrorInducer ms_instance;
-
- // Is the ErrorInducer active?
- static bool ms_is_active;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_ERRORINDUCER_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1globals/globals.cc b/plugins/Dbx_kv/src/hamsterdb/src/1globals/globals.cc
deleted file mode 100644
index 9f5d184c55..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1globals/globals.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-uint64_t Globals::ms_extended_keys;
-
-uint64_t Globals::ms_extended_duptables;
-
-uint32_t Globals::ms_extended_threshold;
-
-uint32_t Globals::ms_duplicate_threshold;
-
-int Globals::ms_linear_threshold;
-
-int Globals::ms_error_level;
-
-const char *Globals::ms_error_file;
-
-int Globals::ms_error_line;
-
-const char *Globals::ms_error_expr;
-
-const char *Globals::ms_error_function;
-
-// the default error handler
-void HAM_CALLCONV default_errhandler(int level, const char *message);
-
-ham_errhandler_fun Globals::ms_error_handler = default_errhandler;
-
-uint64_t Globals::ms_bytes_before_compression;
-
-uint64_t Globals::ms_bytes_after_compression;
-
-bool Globals::ms_is_simd_enabled = true;
-
-} // namespace hamsterdb
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1globals/globals.h b/plugins/Dbx_kv/src/hamsterdb/src/1globals/globals.h
deleted file mode 100644
index efe3449e93..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1globals/globals.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Global variables; used for tests and metrics
- *
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_GLOBALS_H
-#define HAM_GLOBALS_H
-
-#include "0root/root.h"
-
-#include "ham/types.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Globals {
- // for counting extended keys
- static uint64_t ms_extended_keys;
-
- // for counting extended duplicate tables
- static uint64_t ms_extended_duptables;
-
- // Move every key > threshold to a blob. For testing purposes.
- // TODO currently gets assigned at runtime
- static uint32_t ms_extended_threshold;
-
- // Create duplicate table if amount of duplicates > threshold. For testing
- // purposes.
- // TODO currently gets assigned at runtime
- static uint32_t ms_duplicate_threshold;
-
- // linear search threshold for the PAX layout
- static int ms_linear_threshold;
-
- // used in error.h/error.cc
- static int ms_error_level;
-
- // used in error.h/error.cc
- static const char *ms_error_file;
-
- // used in error.h/error.cc
- static int ms_error_line;
-
- // used in error.h/error.cc
- static const char *ms_error_expr;
-
- // used in error.h/error.cc
- static const char *ms_error_function;
-
- // used in error.h/error.cc
- static ham_errhandler_fun ms_error_handler;
-
- // PRO: Tracking key bytes before compression
- static uint64_t ms_bytes_before_compression;
-
- // PRO: Tracking key bytes after compression
- static uint64_t ms_bytes_after_compression;
-
- // PRO: enable/disable SIMD
- static bool ms_is_simd_enabled;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_GLOBALS_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1mem/mem.cc b/plugins/Dbx_kv/src/hamsterdb/src/1mem/mem.cc
deleted file mode 100644
index 58a00b87c3..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1mem/mem.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#ifdef HAM_USE_TCMALLOC
-# include <google/tcmalloc.h>
-# include <google/malloc_extension.h>
-#endif
-#include <stdlib.h>
-
-#include "ham/hamsterdb_int.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1os/file.h"
-#include "1mem/mem.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-uint64_t Memory::ms_peak_memory;
-uint64_t Memory::ms_total_allocations;
-uint64_t Memory::ms_current_allocations;
-
-void
-Memory::get_global_metrics(ham_env_metrics_t *metrics)
-{
-#ifdef HAM_USE_TCMALLOC
- size_t value = 0;
- MallocExtension::instance()->GetNumericProperty(
- "generic.current_allocated_bytes", &value);
- metrics->mem_current_usage = value;
- if (ms_peak_memory < value)
- ms_peak_memory = metrics->mem_peak_usage = value;
- MallocExtension::instance()->GetNumericProperty(
- "generic.heap_size", &value);
- metrics->mem_heap_size = value;
-#endif
-
- metrics->mem_total_allocations = ms_total_allocations;
- metrics->mem_current_allocations = ms_current_allocations;
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1mem/mem.h b/plugins/Dbx_kv/src/hamsterdb/src/1mem/mem.h
deleted file mode 100644
index 13f79b618c..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1mem/mem.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Memory handling
- *
- * @exception_safe: nothrow
- * @thread_safe: no (b/c of metrics)
- */
-
-#ifndef HAM_MEM_H
-#define HAM_MEM_H
-
-#include "0root/root.h"
-
-#include <new>
-#include <stdlib.h>
-#ifdef HAM_USE_TCMALLOC
-# include <google/tcmalloc.h>
-#endif
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-struct ham_env_metrics_t;
-
-namespace hamsterdb {
-
-/*
- * The static Memory class provides memory management functions in a common
- * c++ namespace. The functions can allocate, reallocate and free memory
- * while tracking usage statistics.
- *
- * If tcmalloc is used then additional metrics will be available.
- *
- * This class only has static members and methods. It does not have a
- * constructor.
- */
-class Memory {
- public:
- // allocates |size| bytes, casted into type |T *|;
- // returns null if out of memory.
- // usage:
- //
- // char *p = Memory::allocate<char>(1024);
- //
- template<typename T>
- static T *allocate(size_t size) {
- ms_total_allocations++;
- ms_current_allocations++;
-#ifdef HAM_USE_TCMALLOC
- T *t = (T *)::tc_malloc(size);
-#else
- T *t = (T *)::malloc(size);
-#endif
- if (!t)
- throw Exception(HAM_OUT_OF_MEMORY);
- return (t);
- }
-
- // allocates |size| bytes; returns null if out of memory. initializes
- // the allocated memory with zeroes.
- // usage:
- //
- // const char *p = Memory::callocate<const char>(50);
- //
- template<typename T>
- static T *callocate(size_t size) {
- ms_total_allocations++;
- ms_current_allocations++;
-
-#ifdef HAM_USE_TCMALLOC
- T *t = (T *)::tc_calloc(1, size);
-#else
- T *t = (T *)::calloc(1, size);
-#endif
- if (!t)
- throw Exception(HAM_OUT_OF_MEMORY);
- return (t);
- }
-
- // re-allocates |ptr| for |size| bytes; returns null if out of memory.
- // |ptr| can be null on first use.
- // usage:
- //
- // p = Memory::reallocate<char>(p, 100);
- //
- template<typename T>
- static T *reallocate(T *ptr, size_t size) {
- if (ptr == 0) {
- ms_total_allocations++;
- ms_current_allocations++;
- }
-#ifdef HAM_USE_TCMALLOC
- T *t = (T *)::tc_realloc(ptr, size);
-#else
- T *t = (T *)::realloc(ptr, size);
-#endif
- if (!t)
- throw Exception(HAM_OUT_OF_MEMORY);
- return (t);
- }
-
- // releases a memory block; can deal with NULL pointers.
- static void release(void *ptr) {
- if (ptr) {
- ms_current_allocations--;
-#ifdef HAM_USE_TCMALLOC
- ::tc_free(ptr);
-#else
- ::free(ptr);
-#endif
- }
- }
-
- // updates and returns the collected metrics
- static void get_global_metrics(ham_env_metrics_t *metrics);
-
- private:
- // peak memory usage
- static uint64_t ms_peak_memory;
-
- // total memory allocations
- static uint64_t ms_total_allocations;
-
- // currently active allocations
- static uint64_t ms_current_allocations;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_MEM_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1os/file.h b/plugins/Dbx_kv/src/hamsterdb/src/1os/file.h
deleted file mode 100644
index df9049c6de..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1os/file.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A simple wrapper around a file handle. Throws exceptions in
- * case of errors. Moves the file handle when copied.
- *
- * @exception_safe: strong
- * @thread_safe: unknown
- */
-
-#ifndef HAM_FILE_H
-#define HAM_FILE_H
-
-#include "0root/root.h"
-
-#include <stdio.h>
-#include <limits.h>
-
-#include "ham/types.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1os/os.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class File
-{
- public:
- enum {
-#ifdef HAM_OS_POSIX
- kSeekSet = SEEK_SET,
- kSeekEnd = SEEK_END,
- kSeekCur = SEEK_CUR,
- kMaxPath = PATH_MAX
-#else
- kSeekSet = FILE_BEGIN,
- kSeekEnd = FILE_END,
- kSeekCur = FILE_CURRENT,
- kMaxPath = MAX_PATH
-#endif
- };
-
- // Constructor: creates an empty File handle
- File()
- : m_fd(HAM_INVALID_FD), m_mmaph(HAM_INVALID_FD), m_posix_advice(0) {
- }
-
- // Copy constructor: moves ownership of the file handle
- File(File &other)
- : m_fd(other.m_fd), m_mmaph(other.m_mmaph),
- m_posix_advice(other.m_posix_advice) {
- other.m_fd = HAM_INVALID_FD;
- other.m_mmaph = HAM_INVALID_FD;
- }
-
- // Destructor: closes the file
- ~File() {
- close();
- }
-
- // Assignment operator: moves ownership of the file handle
- File &operator=(File &other) {
- m_fd = other.m_fd;
- other.m_fd = HAM_INVALID_FD;
- return (*this);
- }
-
- // Creates a new file
- void create(const char *filename, uint32_t mode);
-
- // Opens an existing file
- void open(const char *filename, bool read_only);
-
- // Returns true if the file is open
- bool is_open() const {
- return (m_fd != HAM_INVALID_FD);
- }
-
- // Flushes a file
- void flush();
-
- // Sets the parameter for posix_fadvise()
- void set_posix_advice(int parameter);
-
- // Maps a file in memory
- //
- // mmap is called with MAP_PRIVATE - the allocated buffer
- // is just a copy of the file; writing to the buffer will not alter
- // the file itself.
- void mmap(uint64_t position, size_t size, bool readonly,
- uint8_t **buffer);
-
- // Unmaps a buffer
- void munmap(void *buffer, size_t size);
-
- // Positional read from a file
- void pread(uint64_t addr, void *buffer, size_t len);
-
- // Positional write to a file
- void pwrite(uint64_t addr, const void *buffer, size_t len);
-
- // Write data to a file; uses the current file position
- void write(const void *buffer, size_t len);
-
- // Get the page allocation granularity of the operating system
- static size_t get_granularity();
-
- // Seek position in a file
- void seek(uint64_t offset, int whence);
-
- // Tell the position in a file
- uint64_t tell();
-
- // Returns the size of the file
- uint64_t get_file_size();
-
- // Truncate/resize the file
- void truncate(uint64_t newsize);
-
- // Closes the file descriptor
- void close();
-
- private:
- // The file handle
- ham_fd_t m_fd;
-
- // The mmap handle - required for Win32
- ham_fd_t m_mmaph;
-
- // Parameter for posix_fadvise()
- int m_posix_advice;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_FILE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1os/os.cc b/plugins/Dbx_kv/src/hamsterdb/src/1os/os.cc
deleted file mode 100644
index 8f8c0c991c..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1os/os.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "1os/os.h"
-
-namespace hamsterdb {
-
-int
-os_get_simd_lane_width()
-{
- // only supported in hamsterdb pro
- return (0);
-}
-
-} // namespace hamsterdb
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1os/os.h b/plugins/Dbx_kv/src/hamsterdb/src/1os/os.h
deleted file mode 100644
index dd2f52a4dc..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1os/os.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Abstraction layer for operating system functions
- *
- * @exception_safe: basic // for socket
- * @exception_safe: strong // for file
- * @thread_safe: unknown
- */
-
-#ifndef HAM_OS_H
-#define HAM_OS_H
-
-#include "0root/root.h"
-
-#include <stdio.h>
-#include <limits.h>
-
-#include "ham/types.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/*
- * typedefs for posix
- */
-#ifdef HAM_OS_POSIX
-typedef int ham_fd_t;
-typedef int ham_socket_t;
-# define HAM_INVALID_FD (-1)
-#endif
-
-/*
- * typedefs for Windows 32- and 64-bit
- */
-#ifdef HAM_OS_WIN32
-# ifdef CYGWIN
-typedef int ham_fd_t;
-typedef int ham_socket_t;
-# else
-typedef HANDLE ham_fd_t;
-typedef SOCKET ham_socket_t;
-# endif
-# define HAM_INVALID_FD (0)
-#endif
-
-// Returns the number of 32bit integers that the CPU can process in
-// parallel (the SIMD lane width)
-extern int
-os_get_simd_lane_width();
-
-} // namespace hamsterdb
-
-#endif /* HAM_OS_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1os/os_posix.cc b/plugins/Dbx_kv/src/hamsterdb/src/1os/os_posix.cc
deleted file mode 100644
index 135899e7ea..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1os/os_posix.cc
+++ /dev/null
@@ -1,474 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _GNU_SOURCE 1 // for O_LARGEFILE
-#define _FILE_OFFSET_BITS 64
-
-#include "0root/root.h"
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#if HAVE_MMAP
-# include <sys/mman.h>
-#endif
-#if HAVE_WRITEV
-# include <sys/uio.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1os/file.h"
-#include "1os/socket.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-#if 0
-# define os_log(x) ham_log(x)
-#else
-# define os_log(x)
-#endif
-
-static void
-lock_exclusive(int fd, bool lock)
-{
-#ifdef HAM_SOLARIS
- // SunOS 5.9 doesn't have LOCK_* unless i include /usr/ucbinclude; but then,
- // mmap behaves strangely (the first write-access to the mmapped buffer
- // leads to a segmentation fault).
- //
- // Tell me if this troubles you/if you have suggestions for fixes.
-#else
- int flags;
-
- if (lock)
- flags = LOCK_EX | LOCK_NB;
- else
- flags = LOCK_UN;
-
- if (0 != flock(fd, flags)) {
- ham_log(("flock failed with status %u (%s)", errno, strerror(errno)));
- // it seems that linux does not only return EWOULDBLOCK, as stated
- // in the documentation (flock(2)), but also other errors...
- if (errno && lock)
- throw Exception(HAM_WOULD_BLOCK);
- throw Exception(HAM_IO_ERROR);
- }
-#endif
-}
-
-static void
-enable_largefile(int fd)
-{
- // not available on cygwin...
-#ifdef HAVE_O_LARGEFILE
- int oflag = fcntl(fd, F_GETFL, 0);
- fcntl(fd, F_SETFL, oflag | O_LARGEFILE);
-#endif
-}
-
-static void
-os_read(ham_fd_t fd, uint8_t *buffer, size_t len)
-{
- os_log(("os_read: fd=%d, size=%lld", fd, len));
-
- int r;
- size_t total = 0;
-
- while (total < len) {
- r = read(fd, &buffer[total], len - total);
- if (r < 0) {
- ham_log(("os_read failed with status %u (%s)", errno, strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
- if (r == 0)
- break;
- total += r;
- }
-
- if (total != len) {
- ham_log(("os_read() failed with short read (%s)", strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-}
-
-static void
-os_write(ham_fd_t fd, const void *buffer, size_t len)
-{
- int w;
- size_t total = 0;
- const char *p = (const char *)buffer;
-
- while (total < len) {
- w = ::write(fd, p + total, len - total);
- if (w < 0) {
- ham_log(("os_write failed with status %u (%s)", errno,
- strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
- if (w == 0)
- break;
- total += w;
- }
-
- if (total != len) {
- ham_log(("os_write() failed with short read (%s)", strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-}
-
-size_t
-File::get_granularity()
-{
- return ((size_t)sysconf(_SC_PAGE_SIZE));
-}
-
-void
-File::set_posix_advice(int advice)
-{
- m_posix_advice = advice;
- ham_assert(m_fd != HAM_INVALID_FD);
-
-#if HAVE_POSIX_FADVISE
- if (m_posix_advice == HAM_POSIX_FADVICE_RANDOM) {
- int r = ::posix_fadvise(m_fd, 0, 0, POSIX_FADV_RANDOM);
- if (r != 0) {
- ham_log(("posix_fadvise failed with status %d (%s)",
- errno, strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
- }
-#endif
-}
-
-void
-File::mmap(uint64_t position, size_t size, bool readonly, uint8_t **buffer)
-{
- os_log(("File::mmap: fd=%d, position=%lld, size=%lld", m_fd, position, size));
-
- int prot = PROT_READ;
- if (!readonly)
- prot |= PROT_WRITE;
-
-#if HAVE_MMAP
- *buffer = (uint8_t *)::mmap(0, size, prot, MAP_PRIVATE, m_fd, position);
- if (*buffer == (void *)-1) {
- *buffer = 0;
- ham_log(("mmap failed with status %d (%s)", errno, strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-#else
- throw Exception(HAM_NOT_IMPLEMENTED);
-#endif
-
-#if HAVE_MADVISE
- if (m_posix_advice == HAM_POSIX_FADVICE_RANDOM) {
- int r = ::madvise(*buffer, size, MADV_RANDOM);
- if (r != 0) {
- ham_log(("madvise failed with status %d (%s)", errno, strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
- }
-#endif
-}
-
-void
-File::munmap(void *buffer, size_t size)
-{
- os_log(("File::munmap: size=%lld", size));
-
-#if HAVE_MUNMAP
- int r = ::munmap(buffer, size);
- if (r) {
- ham_log(("munmap failed with status %d (%s)", errno, strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-#else
- throw Exception(HAM_NOT_IMPLEMENTED);
-#endif
-}
-
-void
-File::pread(uint64_t addr, void *buffer, size_t len)
-{
-#if HAVE_PREAD
- os_log(("File::pread: fd=%d, address=%lld, size=%lld", m_fd, addr,
- len));
-
- int r;
- size_t total = 0;
-
- while (total < len) {
- r = ::pread(m_fd, (uint8_t *)buffer + total, len - total,
- addr + total);
- if (r < 0) {
- ham_log(("File::pread failed with status %u (%s)", errno,
- strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
- if (r == 0)
- break;
- total += r;
- }
-
- if (total != len) {
- ham_log(("File::pread() failed with short read (%s)", strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-#else
- File::seek(addr, kSeekSet);
- os_read(m_fd, (uint8_t *)buffer, len);
-#endif
-}
-
-void
-File::pwrite(uint64_t addr, const void *buffer, size_t len)
-{
- os_log(("File::pwrite: fd=%d, address=%lld, size=%lld", m_fd, addr, len));
-
-#if HAVE_PWRITE
- ssize_t s;
- size_t total = 0;
-
- while (total < len) {
- s = ::pwrite(m_fd, buffer, len, addr + total);
- if (s < 0) {
- ham_log(("pwrite() failed with status %u (%s)", errno, strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
- if (s == 0)
- break;
- total += s;
- }
-
- if (total != len) {
- ham_log(("pwrite() failed with short read (%s)", strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-#else
- seek(addr, kSeekSet);
- write(buffer, len);
-#endif
-}
-
-void
-File::write(const void *buffer, size_t len)
-{
- os_log(("File::write: fd=%d, size=%lld", m_fd, len));
- os_write(m_fd, buffer, len);
-}
-
-void
-File::seek(uint64_t offset, int whence)
-{
- os_log(("File::seek: fd=%d, offset=%lld, whence=%d", m_fd, offset, whence));
- if (lseek(m_fd, offset, whence) < 0)
- throw Exception(HAM_IO_ERROR);
-}
-
-uint64_t
-File::tell()
-{
- uint64_t offset = lseek(m_fd, 0, SEEK_CUR);
- os_log(("File::tell: fd=%d, offset=%lld", m_fd, offset));
- if (offset == (uint64_t) - 1)
- throw Exception(HAM_IO_ERROR);
- return (offset);
-}
-
-uint64_t
-File::get_file_size()
-{
- seek(0, kSeekEnd);
- uint64_t size = tell();
- os_log(("File::get_file_size: fd=%d, size=%lld", m_fd, size));
- return (size);
-}
-
-void
-File::truncate(uint64_t newsize)
-{
- os_log(("File::truncate: fd=%d, size=%lld", m_fd, newsize));
- if (ftruncate(m_fd, newsize))
- throw Exception(HAM_IO_ERROR);
-}
-
-void
-File::create(const char *filename, uint32_t mode)
-{
- int osflags = O_CREAT | O_RDWR | O_TRUNC;
-#if HAVE_O_NOATIME
- osflags |= O_NOATIME;
-#endif
-
- ham_fd_t fd = ::open(filename, osflags, mode ? mode : 0644);
- if (fd < 0) {
- ham_log(("creating file %s failed with status %u (%s)", filename,
- errno, strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-
- /* lock the file - this is default behaviour since 1.1.0 */
- lock_exclusive(fd, true);
-
- /* enable O_LARGEFILE support */
- enable_largefile(fd);
-
- m_fd = fd;
-}
-
-void
-File::flush()
-{
- os_log(("File::flush: fd=%d", m_fd));
- /* unlike fsync(), fdatasync() does not flush the metadata unless
- * it's really required. it's therefore a lot faster. */
-#if HAVE_FDATASYNC && !__APPLE__
- if (fdatasync(m_fd) == -1) {
-#else
- if (fsync(m_fd) == -1) {
-#endif
- ham_log(("fdatasync failed with status %u (%s)",
- errno, strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-}
-
-void
-File::open(const char *filename, bool read_only)
-{
- int osflags = 0;
-
- if (read_only)
- osflags |= O_RDONLY;
- else
- osflags |= O_RDWR;
-#if HAVE_O_NOATIME
- osflags |= O_NOATIME;
-#endif
-
- ham_fd_t fd = ::open(filename, osflags);
- if (fd < 0) {
- ham_log(("opening file %s failed with status %u (%s)", filename,
- errno, strerror(errno)));
- throw Exception(errno == ENOENT ? HAM_FILE_NOT_FOUND : HAM_IO_ERROR);
- }
-
- /* lock the file - this is default behaviour since 1.1.0 */
- lock_exclusive(fd, true);
-
- /* enable O_LARGEFILE support */
- enable_largefile(fd);
-
- m_fd = fd;
-}
-
-void
-File::close()
-{
- if (m_fd != HAM_INVALID_FD) {
- // on posix, we most likely don't want to close descriptors 0 and 1
- ham_assert(m_fd != 0 && m_fd != 1);
-
- // unlock the file - this is default behaviour since 1.1.0
- lock_exclusive(m_fd, false);
-
- // now close the descriptor
- if (::close(m_fd) == -1)
- throw Exception(HAM_IO_ERROR);
-
- m_fd = HAM_INVALID_FD;
- }
-}
-
-void
-Socket::connect(const char *hostname, uint16_t port, uint32_t timeout_sec)
-{
- ham_socket_t s = ::socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- ham_log(("failed creating socket: %s", strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-
- struct hostent *server = ::gethostbyname(hostname);
- if (!server) {
- ham_log(("unable to resolve hostname %s: %s", hostname,
- hstrerror(h_errno)));
- ::close(s);
- throw Exception(HAM_NETWORK_ERROR);
- }
-
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- memcpy(&addr.sin_addr.s_addr, server->h_addr, server->h_length);
- addr.sin_port = htons(port);
- if (::connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- ham_log(("unable to connect to %s:%d: %s", hostname, (int)port,
- strerror(errno)));
- ::close(s);
- throw Exception(HAM_NETWORK_ERROR);
- }
-
- if (timeout_sec) {
- struct timeval tv;
- tv.tv_sec = timeout_sec;
- tv.tv_usec = 0;
- if (::setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) < 0) {
- ham_log(("unable to set socket timeout to %d sec: %s", timeout_sec,
- strerror(errno)));
- // fall through, this is not critical
- }
- }
-
- m_socket = s;
-}
-
-void
-Socket::send(const uint8_t *data, size_t len)
-{
- os_write(m_socket, data, len);
-}
-
-void
-Socket::recv(uint8_t *data, size_t len)
-{
- os_read(m_socket, data, len);
-}
-
-void
-Socket::close()
-{
- if (m_socket != HAM_INVALID_FD) {
- if (::close(m_socket) == -1)
- throw Exception(HAM_IO_ERROR);
- m_socket = HAM_INVALID_FD;
- }
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1os/os_win32.cc b/plugins/Dbx_kv/src/hamsterdb/src/1os/os_win32.cc
deleted file mode 100644
index ac51a4a7b7..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1os/os_win32.cc
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <winsock2.h>
-#include <windows.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1os/file.h"
-#include "1os/socket.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-static const char *
-DisplayError(char* buf, uint32_t buflen, DWORD errorcode)
-{
- size_t len;
-
- buf[0] = 0;
- FormatMessageA(/* FORMAT_MESSAGE_ALLOCATE_BUFFER | */
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, errorcode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPSTR)buf, buflen, NULL);
- buf[buflen - 1] = 0;
-
- /* strip trailing whitespace\newlines */
- for (len = strlen(buf); len-- > 0; ) {
- if (!isspace(buf[len]))
- break;
- buf[len] = 0;
- }
-
- return (buf);
-}
-
-/*
- * MS says:
- *
- * Security Alert
- *
- * Using the MultiByteToWideChar function incorrectly can compromise the
- * security of your application. Calling this function can easily cause a
- * buffer overrun because the size of the input buffer indicated by
- * lpMultiByteStr equals the number of bytes in the string, while the size of
- * the output buffer indicated by lpWideCharStr equals the number of WCHAR
- * values.
- *
- * To avoid a buffer overrun, your application must specify a buffer size
- * appropriate for the data type the buffer receives. For more information, see
- * Security Considerations: International Features.
- */
-static void
-utf8_string(const char *filename, WCHAR *wfilename, int wlen)
-{
- MultiByteToWideChar(CP_ACP, 0, filename, -1, wfilename, wlen);
-}
-
-static int
-calc_wlen4str(const char *str)
-{
- // Since we call MultiByteToWideChar with an input length of -1, the
- // output will include the wchar NUL sentinel as well, so count it
- return (int)(strlen(str) + 1);
-}
-
-size_t
-File::get_granularity()
-{
- SYSTEM_INFO info;
- GetSystemInfo(&info);
- return ((size_t)info.dwAllocationGranularity);
-}
-
-void
-File::set_posix_advice(int advice)
-{
- // Only available for posix platforms
-}
-
-void
-File::mmap(uint64_t position, size_t size, bool readonly, uint8_t **buffer)
-{
- ham_status_t st;
- DWORD protect = (readonly ? PAGE_READONLY : PAGE_WRITECOPY);
- DWORD access = FILE_MAP_COPY;
- LARGE_INTEGER i;
- i.QuadPart = position;
-
- m_mmaph = CreateFileMapping(m_fd, 0, protect, 0, 0, 0);
- if (!m_mmaph) {
- char buf[256];
- *buffer = 0;
- st = (ham_status_t)GetLastError();
- ham_log(("CreateFileMapping failed with OS status %u (%s)",
- st, DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-
- *buffer = (uint8_t *)MapViewOfFile(m_mmaph, access, i.HighPart, i.LowPart,
- (SIZE_T)size);
- if (!*buffer) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- /* make sure to release the mapping */
- (void)CloseHandle(m_mmaph);
- m_mmaph = HAM_INVALID_FD;
- ham_log(("MapViewOfFile failed with OS status %u (%s)",
- st, DisplayError(buf, sizeof(buf), st)));
- if (st == ERROR_NOT_ENOUGH_QUOTA) // not enough resources - fallback to r/w
- throw Exception(HAM_LIMITS_REACHED);
- throw Exception(HAM_IO_ERROR);
- }
-}
-
-void
-File::munmap(void *buffer, size_t size)
-{
- ham_status_t st;
-
- if (!UnmapViewOfFile(buffer)) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- ham_log(("UnMapViewOfFile failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-
- if (m_mmaph != HAM_INVALID_FD) {
- if (!CloseHandle(m_mmaph)) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- ham_log(("CloseHandle failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- }
-
- m_mmaph = HAM_INVALID_FD;
-}
-
-void
-File::pread(uint64_t addr, void *buffer, size_t len)
-{
- ham_status_t st;
- OVERLAPPED ov = { 0 };
- ov.Offset = (DWORD)addr;
- ov.OffsetHigh = addr >> 32;
- DWORD read;
- if (!::ReadFile(m_fd, buffer, (DWORD)len, &read, &ov)) {
- if (GetLastError() != ERROR_IO_PENDING) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- ham_log(("ReadFile failed with OS status %u (%s)",
- st, DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- if (!::GetOverlappedResult(m_fd, &ov, &read, TRUE)) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- ham_log(("GetOverlappedResult failed with OS status %u (%s)",
- st, DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- }
-
- if (read != len)
- throw Exception(HAM_IO_ERROR);
-}
-
-void
-File::pwrite(uint64_t addr, const void *buffer, size_t len)
-{
- ham_status_t st;
- OVERLAPPED ov = { 0 };
- ov.Offset = (DWORD)addr;
- ov.OffsetHigh = addr >> 32;
- DWORD written;
- if (!::WriteFile(m_fd, buffer, (DWORD)len, &written, &ov)) {
- if (GetLastError() != ERROR_IO_PENDING) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- ham_log(("WriteFile failed with OS status %u (%s)",
- st, DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- if (!::GetOverlappedResult(m_fd, &ov, &written, TRUE)) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- ham_log(("GetOverlappedResult failed with OS status %u (%s)",
- st, DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- }
-
- if (written != len)
- throw Exception(HAM_IO_ERROR);
-}
-
-void
-File::write(const void *buffer, size_t len)
-{
- ham_status_t st;
- DWORD written = 0;
-
- if (!WriteFile(m_fd, buffer, (DWORD)len, &written, 0)) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- ham_log(("WriteFile failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-
- if (written != len)
- throw Exception(HAM_IO_ERROR);
-}
-
-#ifndef INVALID_SET_FILE_POINTER
-# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-#endif
-
-void
-File::seek(uint64_t offset, int whence)
-{
- DWORD st;
- LARGE_INTEGER i;
- i.QuadPart = offset;
-
- i.LowPart = ::SetFilePointer(m_fd, i.LowPart, &i.HighPart, whence);
- if (i.LowPart == INVALID_SET_FILE_POINTER &&
- (st = GetLastError())!=NO_ERROR) {
- char buf[256];
- ham_log(("SetFilePointer failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-}
-
-uint64_t
-File::tell()
-{
- DWORD st;
- LARGE_INTEGER i;
- i.QuadPart = 0;
-
- i.LowPart = SetFilePointer(m_fd, i.LowPart, &i.HighPart, kSeekCur);
- if (i.LowPart == INVALID_SET_FILE_POINTER &&
- (st = GetLastError()) != NO_ERROR) {
- char buf[256];
- ham_log(("SetFilePointer failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-
- return ((size_t)i.QuadPart);
-}
-
-#ifndef INVALID_FILE_SIZE
-# define INVALID_FILE_SIZE ((DWORD)-1)
-#endif
-
-uint64_t
-File::get_file_size()
-{
- ham_status_t st;
- LARGE_INTEGER i;
- i.QuadPart = 0;
- i.LowPart = GetFileSize(m_fd, (LPDWORD)&i.HighPart);
-
- if (i.LowPart == INVALID_FILE_SIZE && (st = GetLastError()) != NO_ERROR) {
- char buf[256];
- ham_log(("GetFileSize failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-
- return ((size_t)i.QuadPart);
-}
-
-void
-File::truncate(uint64_t newsize)
-{
- File::seek(newsize, kSeekSet);
-
- if (!SetEndOfFile(m_fd)) {
- char buf[256];
- ham_status_t st = (ham_status_t)GetLastError();
- ham_log(("SetEndOfFile failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-}
-
-void
-File::create(const char *filename, uint32_t mode)
-{
- ham_status_t st;
- DWORD share = 0; /* 1.1.0: default behaviour is exclusive locking */
- DWORD access = GENERIC_READ | GENERIC_WRITE;
- ham_fd_t fd;
-
-#ifdef UNICODE
- int fnameWlen = calc_wlen4str(filename);
- WCHAR *wfilename = (WCHAR *)malloc(fnameWlen * sizeof(wfilename[0]));
- if (!wfilename)
- throw Exception(HAM_OUT_OF_MEMORY);
-
- /* translate ASCII filename to unicode */
- utf8_string(filename, wfilename, fnameWlen);
- fd = (ham_fd_t)CreateFileW(wfilename, access,
- share, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, 0);
- free(wfilename);
-#else
- fd = (ham_fd_t)CreateFileA(filename, access,
- share, NULL, CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, 0);
-#endif
-
- if (fd == INVALID_HANDLE_VALUE) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- if (st == ERROR_SHARING_VIOLATION)
- throw Exception(HAM_WOULD_BLOCK);
- ham_log(("CreateFile(%s, %x, %x, ...) (create) failed with OS status "
- "%u (%s)", filename, access, share, st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-
- m_fd = fd;
-}
-
-void
-File::flush()
-{
- ham_status_t st;
-
- if (!FlushFileBuffers(m_fd)) {
- char buf[256];
- st = (ham_status_t)GetLastError();
- ham_log(("FlushFileBuffers failed with OS status %u (%s)",
- st, DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
-}
-
-void
-File::open(const char *filename, bool read_only)
-{
- ham_status_t st;
- DWORD share = 0; /* 1.1.0: default behaviour is exclusive locking */
- DWORD access = read_only
- ? GENERIC_READ
- : (GENERIC_READ | GENERIC_WRITE);
- DWORD dispo = OPEN_EXISTING;
- DWORD osflags = 0;
- ham_fd_t fd;
-
-#ifdef UNICODE
- {
- int fnameWlen = calc_wlen4str(filename);
- WCHAR *wfilename = (WCHAR *)malloc(fnameWlen * sizeof(wfilename[0]));
- if (!wfilename)
- throw Exception(HAM_OUT_OF_MEMORY);
-
- /* translate ASCII filename to unicode */
- utf8_string(filename, wfilename, fnameWlen);
- fd = (ham_fd_t)CreateFileW(wfilename, access, share, NULL,
- dispo, osflags, 0);
- free(wfilename);
- }
-#else
- fd = (ham_fd_t)CreateFileA(filename, access, share, NULL,
- dispo, osflags, 0);
-#endif
-
- if (fd == INVALID_HANDLE_VALUE) {
- char buf[256];
- fd = HAM_INVALID_FD;
- st = (ham_status_t)GetLastError();
- ham_log(("CreateFile(%s, %x, %x, ...) (open) failed with OS status "
- "%u (%s)", filename, access, share,
- st, DisplayError(buf, sizeof(buf), st)));
- if (st == ERROR_SHARING_VIOLATION)
- throw Exception(HAM_WOULD_BLOCK);
- throw Exception(st == ERROR_FILE_NOT_FOUND
- ? HAM_FILE_NOT_FOUND
- : HAM_IO_ERROR);
- }
-
- m_fd = fd;
-}
-
-void
-File::close()
-{
- if (m_fd != HAM_INVALID_FD) {
- if (!CloseHandle((HANDLE)m_fd)) {
- char buf[256];
- ham_status_t st = (ham_status_t)GetLastError();
- ham_log(("CloseHandle failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- m_fd = HAM_INVALID_FD;
- }
-
- if (m_mmaph != HAM_INVALID_FD) {
- if (!CloseHandle((HANDLE)m_mmaph)) {
- char buf[256];
- ham_status_t st = (ham_status_t)GetLastError();
- ham_log(("CloseHandle failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- m_mmaph = HAM_INVALID_FD;
- }
-}
-
-void
-Socket::connect(const char *hostname, uint16_t port, uint32_t timeout_sec)
-{
- WORD sockVersion = MAKEWORD(1, 1);
- WSADATA wsaData;
- WSAStartup(sockVersion, &wsaData);
-
- ham_socket_t s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (s < 0) {
- ham_log(("failed creating socket: %s", strerror(errno)));
- throw Exception(HAM_IO_ERROR);
- }
-
- LPHOSTENT server = ::gethostbyname(hostname);
- if (!server) {
- ham_log(("unable to resolve hostname %s", hostname));
- ::closesocket(s);
- throw Exception(HAM_NETWORK_ERROR);
- }
-
- SOCKADDR_IN addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr = *((LPIN_ADDR)*server->h_addr_list);
- addr.sin_port = htons(port);
- if (::connect(s, (LPSOCKADDR)&addr, sizeof(addr)) < 0) {
- ham_log(("unable to connect to %s:%d: %s", hostname, (int)port,
- strerror(errno)));
- ::closesocket(s);
- throw Exception(HAM_NETWORK_ERROR);
- }
-
- if (timeout_sec) {
- struct timeval tv;
- tv.tv_sec = timeout_sec;
- tv.tv_usec = 0;
- if (::setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)) < 0) {
- char buf[256];
- ham_log(("unable to set socket timeout to %u sec: %u/%s", timeout_sec,
- WSAGetLastError(), DisplayError(buf, sizeof(buf),
- WSAGetLastError())));
- // fall through, this is not critical
- }
- }
-
- m_socket = s;
-}
-
-void
-Socket::send(const uint8_t *data, size_t len)
-{
- size_t sent = 0;
- char buf[256];
- ham_status_t st;
-
- while (sent != len) {
- int s = ::send(m_socket, (const char *)(data + sent), len - sent, 0);
- if (s <= 0) {
- st = (ham_status_t)GetLastError();
- ham_log(("send failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- sent += s;
- }
-}
-
-void
-Socket::recv(uint8_t *data, size_t len)
-{
- size_t read = 0;
- char buf[256];
- ham_status_t st;
-
- while (read != len) {
- int r = ::recv(m_socket, (char *)(data + read), len - read, 0);
- if (r <= 0) {
- st = (ham_status_t)GetLastError();
- ham_log(("recv failed with OS status %u (%s)", st,
- DisplayError(buf, sizeof(buf), st)));
- throw Exception(HAM_IO_ERROR);
- }
- read += r;
- }
-}
-
-void
-Socket::close()
-{
- if (m_socket != HAM_INVALID_FD) {
- if (::closesocket(m_socket) == -1)
- throw Exception(HAM_IO_ERROR);
- m_socket = HAM_INVALID_FD;
- }
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1os/socket.h b/plugins/Dbx_kv/src/hamsterdb/src/1os/socket.h
deleted file mode 100644
index 0acdfdd14e..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1os/socket.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A simple wrapper around a tcp socket handle. Throws exceptions in
- * case of errors
- *
- * @exception_safe: basic
- * @thread_safe: unknown
- */
-
-#ifndef HAM_SOCKET_H
-#define HAM_SOCKET_H
-
-#include "0root/root.h"
-
-#include <stdio.h>
-#include <limits.h>
-
-#include "ham/types.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1os/os.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Socket
-{
- public:
- // Constructor creates an empty socket
- Socket()
- : m_socket(HAM_INVALID_FD) {
- }
-
- // Destructor closes the socket
- ~Socket() {
- close();
- }
-
- // Connects to a remote host
- void connect(const char *hostname, uint16_t port, uint32_t timeout_sec);
-
- // Sends data to the connected server
- void send(const uint8_t *data, size_t len);
-
- // Receives data from the connected server; blocking!
- void recv(uint8_t *data, size_t len);
-
- // Closes the connection; no problem if socket was already closed
- void close();
-
- private:
- ham_socket_t m_socket;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_SOCKET_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/1rb/rb.h b/plugins/Dbx_kv/src/hamsterdb/src/1rb/rb.h
deleted file mode 100644
index fcf0c135d5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/1rb/rb.h
+++ /dev/null
@@ -1,977 +0,0 @@
-/*-
- *******************************************************************************
- *
- * cpp macro implementation of left-leaning 2-3 red-black trees. Parent
- * pointers are not used, and color bits are stored in the least significant
- * bit of right-child pointers (if RB_COMPACT is defined), thus making node
- * linkage as compact as is possible for red-black trees.
- *
- * Usage:
- *
- * #include <stdint.h>
- * #include <stdbool.h>
- * #define NDEBUG // (Optional, see assert(3).)
- * #include <assert.h>
- * #define RB_COMPACT // (Optional, embed color bits in right-child pointers.)
- * #include <rb.h>
- * ...
- *
- *******************************************************************************
- */
-
-#ifndef RB_H_
-#define RB_H_
-
-#include "0root/root.h"
-
-#ifndef HAM_OS_WIN32
-# include <stdint.h>
-# include <sys/cdefs.h>
-#endif
-#include <assert.h>
-
-#ifdef RB_COMPACT
-/* Node structure. */
-#define rb_node(a_type) \
-struct { \
- a_type *rbn_left; \
- a_type *rbn_right_red; \
-}
-#else
-#define rb_node(a_type) \
-struct { \
- a_type *rbn_left; \
- a_type *rbn_right; \
- bool rbn_red; \
-}
-#endif
-
-/* Root structure. */
-#define rbt(a_type) \
-struct { \
- a_type *rbt_root; \
- a_type rbt_nil; \
-}
-
-/* Left accessors. */
-#define rbtn_left_get(a_type, a_field, a_node) \
- ((a_node)->a_field.rbn_left)
-#define rbtn_left_set(a_type, a_field, a_node, a_left) do { \
- (a_node)->a_field.rbn_left = a_left; \
-} while (0)
-
-#ifdef RB_COMPACT
-/* Right accessors. */
-#define rbtn_right_get(a_type, a_field, a_node) \
- ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red) \
- & ((ssize_t)-2)))
-#define rbtn_right_set(a_type, a_field, a_node, a_right) do { \
- (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right) \
- | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1))); \
-} while (0)
-
-/* Color accessors. */
-#define rbtn_red_get(a_type, a_field, a_node) \
- ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red) \
- & ((size_t)1)))
-#define rbtn_color_set(a_type, a_field, a_node, a_red) do { \
- (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t) \
- (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)) \
- | ((ssize_t)a_red)); \
-} while (0)
-#define rbtn_red_set(a_type, a_field, a_node) do { \
- (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) \
- (a_node)->a_field.rbn_right_red) | ((size_t)1)); \
-} while (0)
-#define rbtn_black_set(a_type, a_field, a_node) do { \
- (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t) \
- (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)); \
-} while (0)
-#else
-/* Right accessors. */
-#define rbtn_right_get(a_type, a_field, a_node) \
- ((a_node)->a_field.rbn_right)
-#define rbtn_right_set(a_type, a_field, a_node, a_right) do { \
- (a_node)->a_field.rbn_right = a_right; \
-} while (0)
-
-/* Color accessors. */
-#define rbtn_red_get(a_type, a_field, a_node) \
- ((a_node)->a_field.rbn_red)
-#define rbtn_color_set(a_type, a_field, a_node, a_red) do { \
- (a_node)->a_field.rbn_red = (a_red); \
-} while (0)
-#define rbtn_red_set(a_type, a_field, a_node) do { \
- (a_node)->a_field.rbn_red = true; \
-} while (0)
-#define rbtn_black_set(a_type, a_field, a_node) do { \
- (a_node)->a_field.rbn_red = false; \
-} while (0)
-#endif
-
-/* Node initializer. */
-#define rbt_node_new(a_type, a_field, a_rbt, a_node) do { \
- rbtn_left_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil); \
- rbtn_right_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil); \
- rbtn_red_set(a_type, a_field, (a_node)); \
-} while (0)
-
-/* Tree initializer. */
-#define rb_new(a_type, a_field, a_rbt) do { \
- (a_rbt)->rbt_root = &(a_rbt)->rbt_nil; \
- rbt_node_new(a_type, a_field, a_rbt, &(a_rbt)->rbt_nil); \
- rbtn_black_set(a_type, a_field, &(a_rbt)->rbt_nil); \
-} while (0)
-
-/* Internal utility macros. */
-#define rbtn_first(a_type, a_field, a_rbt, a_root, r_node) do { \
- (r_node) = (a_root); \
- if ((r_node) != &(a_rbt)->rbt_nil) { \
- for (; \
- rbtn_left_get(a_type, a_field, (r_node)) != &(a_rbt)->rbt_nil;\
- (r_node) = rbtn_left_get(a_type, a_field, (r_node))) { \
- } \
- } \
-} while (0)
-
-#define rbtn_last(a_type, a_field, a_rbt, a_root, r_node) do { \
- (r_node) = (a_root); \
- if ((r_node) != &(a_rbt)->rbt_nil) { \
- for (; rbtn_right_get(a_type, a_field, (r_node)) != \
- &(a_rbt)->rbt_nil; (r_node) = rbtn_right_get(a_type, a_field, \
- (r_node))) { \
- } \
- } \
-} while (0)
-
-#define rbtn_rotate_left(a_type, a_field, a_node, r_node) do { \
- (r_node) = rbtn_right_get(a_type, a_field, (a_node)); \
- rbtn_right_set(a_type, a_field, (a_node), \
- rbtn_left_get(a_type, a_field, (r_node))); \
- rbtn_left_set(a_type, a_field, (r_node), (a_node)); \
-} while (0)
-
-#define rbtn_rotate_right(a_type, a_field, a_node, r_node) do { \
- (r_node) = rbtn_left_get(a_type, a_field, (a_node)); \
- rbtn_left_set(a_type, a_field, (a_node), \
- rbtn_right_get(a_type, a_field, (r_node))); \
- rbtn_right_set(a_type, a_field, (r_node), (a_node)); \
-} while (0)
-
-/*
- * The rb_proto() macro generates function prototypes that correspond to the
- * functions generated by an equivalently parameterized call to rb_gen().
- */
-
-#define rb_proto(a_attr, a_prefix, a_rbt_type, a_type) \
-a_attr void \
-a_prefix##new(a_rbt_type *rbtree); \
-a_attr a_type * \
-a_prefix##first(a_rbt_type *rbtree); \
-a_attr a_type * \
-a_prefix##last(a_rbt_type *rbtree); \
-a_attr a_type * \
-a_prefix##next(a_rbt_type *rbtree, a_type *node); \
-a_attr a_type * \
-a_prefix##prev(a_rbt_type *rbtree, a_type *node); \
-a_attr a_type * \
-a_prefix##search(a_rbt_type *rbtree, a_type *key); \
-a_attr a_type * \
-a_prefix##nsearch(a_rbt_type *rbtree, a_type *key); \
-a_attr a_type * \
-a_prefix##psearch(a_rbt_type *rbtree, a_type *key); \
-a_attr void \
-a_prefix##insert(a_rbt_type *rbtree, a_type *node); \
-a_attr void \
-a_prefix##remove(a_rbt_type *rbtree, a_type *node);/* \
-a_attr a_type * \
-a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \
- a_rbt_type *, a_type *, void *), void *arg); \
-a_attr a_type * \
-a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \
- a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg);*/
-
-/*
- * The rb_gen() macro generates a type-specific red-black tree implementation,
- * based on the above cpp macros.
- *
- * Arguments:
- *
- * a_attr : Function attribute for generated functions (ex: static).
- * a_prefix : Prefix for generated functions (ex: ex_).
- * a_rb_type : Type for red-black tree data structure (ex: ex_t).
- * a_type : Type for red-black tree node data structure (ex: ex_node_t).
- * a_field : Name of red-black tree node linkage (ex: ex_link).
- * a_cmp : Node comparison function name, with the following prototype:
- * int (a_cmp *)(a_type *a_node, a_type *a_other);
- * ^^^^^^
- * or a_key
- * Interpretation of comparision function return values:
- * -1 : a_node < a_other
- * 0 : a_node == a_other
- * 1 : a_node > a_other
- * In all cases, the a_node or a_key macro argument is the first
- * argument to the comparison function, which makes it possible
- * to write comparison functions that treat the first argument
- * specially.
- *
- * Assuming the following setup:
- *
- * typedef struct ex_node_s ex_node_t;
- * struct ex_node_s {
- * rb_node(ex_node_t) ex_link;
- * };
- * typedef rbt(ex_node_t) ex_t;
- * rb_gen(static, ex_, ex_t, ex_node_t, ex_link, ex_cmp)
- *
- * The following API is generated:
- *
- * static void
- * ex_new(ex_t *tree);
- * Description: Initialize a red-black tree structure.
- * Args:
- * tree: Pointer to an uninitialized red-black tree object.
- *
- * static ex_node_t *
- * ex_first(ex_t *tree);
- * static ex_node_t *
- * ex_last(ex_t *tree);
- * Description: Get the first/last node in tree.
- * Args:
- * tree: Pointer to an initialized red-black tree object.
- * Ret: First/last node in tree, or NULL if tree is empty.
- *
- * static ex_node_t *
- * ex_next(ex_t *tree, ex_node_t *node);
- * static ex_node_t *
- * ex_prev(ex_t *tree, ex_node_t *node);
- * Description: Get node's successor/predecessor.
- * Args:
- * tree: Pointer to an initialized red-black tree object.
- * node: A node in tree.
- * Ret: node's successor/predecessor in tree, or NULL if node is
- * last/first.
- *
- * static ex_node_t *
- * ex_search(ex_t *tree, ex_node_t *key);
- * Description: Search for node that matches key.
- * Args:
- * tree: Pointer to an initialized red-black tree object.
- * key : Search key.
- * Ret: Node in tree that matches key, or NULL if no match.
- *
- * static ex_node_t *
- * ex_nsearch(ex_t *tree, ex_node_t *key);
- * static ex_node_t *
- * ex_psearch(ex_t *tree, ex_node_t *key);
- * Description: Search for node that matches key. If no match is found,
- * return what would be key's successor/predecessor, were
- * key in tree.
- * Args:
- * tree: Pointer to an initialized red-black tree object.
- * key : Search key.
- * Ret: Node in tree that matches key, or if no match, hypothetical node's
- * successor/predecessor (NULL if no successor/predecessor).
- *
- * static void
- * ex_insert(ex_t *tree, ex_node_t *node);
- * Description: Insert node into tree.
- * Args:
- * tree: Pointer to an initialized red-black tree object.
- * node: Node to be inserted into tree.
- *
- * static void
- * ex_remove(ex_t *tree, ex_node_t *node);
- * Description: Remove node from tree.
- * Args:
- * tree: Pointer to an initialized red-black tree object.
- * node: Node in tree to be removed.
- *
- * static ex_node_t *
- * ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *,
- * ex_node_t *, void *), void *arg);
- * static ex_node_t *
- * ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *,
- * ex_node_t *, void *), void *arg);
- * Description: Iterate forward/backward over tree, starting at node. If
- * tree is modified, iteration must be immediately
- * terminated by the callback function that causes the
- * modification.
- * Args:
- * tree : Pointer to an initialized red-black tree object.
- * start: Node at which to start iteration, or NULL to start at
- * first/last node.
- * cb : Callback function, which is called for each node during
- * iteration. Under normal circumstances the callback function
- * should return NULL, which causes iteration to continue. If a
- * callback function returns non-NULL, iteration is immediately
- * terminated and the non-NULL return value is returned by the
- * iterator. This is useful for re-starting iteration after
- * modifying tree.
- * arg : Opaque pointer passed to cb().
- * Ret: NULL if iteration completed, or the non-NULL callback return value
- * that caused termination of the iteration.
- */
-#define rb_gen(a_attr, a_prefix, a_rbt_type, a_type, a_field, a_cmp) \
-a_attr void \
-a_prefix##new(a_rbt_type *rbtree) { \
- rb_new(a_type, a_field, rbtree); \
-} \
-a_attr a_type * \
-a_prefix##first(a_rbt_type *rbtree) { \
- a_type *ret; \
- rbtn_first(a_type, a_field, rbtree, rbtree->rbt_root, ret); \
- if (ret == &rbtree->rbt_nil) { \
- ret = NULL; \
- } \
- return (ret); \
-} \
-a_attr a_type * \
-a_prefix##last(a_rbt_type *rbtree) { \
- a_type *ret; \
- rbtn_last(a_type, a_field, rbtree, rbtree->rbt_root, ret); \
- if (ret == &rbtree->rbt_nil) { \
- ret = NULL; \
- } \
- return (ret); \
-} \
-a_attr a_type * \
-a_prefix##next(a_rbt_type *rbtree, a_type *node) { \
- a_type *ret; \
- if (rbtn_right_get(a_type, a_field, node) != &rbtree->rbt_nil) { \
- rbtn_first(a_type, a_field, rbtree, rbtn_right_get(a_type, \
- a_field, node), ret); \
- } else { \
- a_type *tnode = rbtree->rbt_root; \
- assert(tnode != &rbtree->rbt_nil); \
- ret = &rbtree->rbt_nil; \
- while (true) { \
- int cmp = (a_cmp)(node, tnode); \
- if (cmp < 0) { \
- ret = tnode; \
- tnode = rbtn_left_get(a_type, a_field, tnode); \
- } else if (cmp > 0) { \
- tnode = rbtn_right_get(a_type, a_field, tnode); \
- } else { \
- break; \
- } \
- assert(tnode != &rbtree->rbt_nil); \
- } \
- } \
- if (ret == &rbtree->rbt_nil) { \
- ret = (NULL); \
- } \
- return (ret); \
-} \
-a_attr a_type * \
-a_prefix##prev(a_rbt_type *rbtree, a_type *node) { \
- a_type *ret; \
- if (rbtn_left_get(a_type, a_field, node) != &rbtree->rbt_nil) { \
- rbtn_last(a_type, a_field, rbtree, rbtn_left_get(a_type, \
- a_field, node), ret); \
- } else { \
- a_type *tnode = rbtree->rbt_root; \
- assert(tnode != &rbtree->rbt_nil); \
- ret = &rbtree->rbt_nil; \
- while (true) { \
- int cmp = (a_cmp)(node, tnode); \
- if (cmp < 0) { \
- tnode = rbtn_left_get(a_type, a_field, tnode); \
- } else if (cmp > 0) { \
- ret = tnode; \
- tnode = rbtn_right_get(a_type, a_field, tnode); \
- } else { \
- break; \
- } \
- assert(tnode != &rbtree->rbt_nil); \
- } \
- } \
- if (ret == &rbtree->rbt_nil) { \
- ret = (NULL); \
- } \
- return (ret); \
-} \
-a_attr a_type * \
-a_prefix##search(a_rbt_type *rbtree, a_type *key) { \
- a_type *ret; \
- int cmp; \
- ret = rbtree->rbt_root; \
- while (ret != &rbtree->rbt_nil \
- && (cmp = (a_cmp)(key, ret)) != 0) { \
- if (cmp < 0) { \
- ret = rbtn_left_get(a_type, a_field, ret); \
- } else { \
- ret = rbtn_right_get(a_type, a_field, ret); \
- } \
- } \
- if (ret == &rbtree->rbt_nil) { \
- ret = (NULL); \
- } \
- return (ret); \
-} \
-a_attr a_type * \
-a_prefix##nsearch(a_rbt_type *rbtree, a_type *key) { \
- a_type *ret; \
- a_type *tnode = rbtree->rbt_root; \
- ret = &rbtree->rbt_nil; \
- while (tnode != &rbtree->rbt_nil) { \
- int cmp = (a_cmp)(key, tnode); \
- if (cmp < 0) { \
- ret = tnode; \
- tnode = rbtn_left_get(a_type, a_field, tnode); \
- } else if (cmp > 0) { \
- tnode = rbtn_right_get(a_type, a_field, tnode); \
- } else { \
- ret = tnode; \
- break; \
- } \
- } \
- if (ret == &rbtree->rbt_nil) { \
- ret = (NULL); \
- } \
- return (ret); \
-} \
-a_attr a_type * \
-a_prefix##psearch(a_rbt_type *rbtree, a_type *key) { \
- a_type *ret; \
- a_type *tnode = rbtree->rbt_root; \
- ret = &rbtree->rbt_nil; \
- while (tnode != &rbtree->rbt_nil) { \
- int cmp = (a_cmp)(key, tnode); \
- if (cmp < 0) { \
- tnode = rbtn_left_get(a_type, a_field, tnode); \
- } else if (cmp > 0) { \
- ret = tnode; \
- tnode = rbtn_right_get(a_type, a_field, tnode); \
- } else { \
- ret = tnode; \
- break; \
- } \
- } \
- if (ret == &rbtree->rbt_nil) { \
- ret = (NULL); \
- } \
- return (ret); \
-} \
-a_attr void \
-a_prefix##insert(a_rbt_type *rbtree, a_type *node) { \
- struct { \
- a_type *node; \
- int cmp; \
- } path[sizeof(void *) << 4], *pathp; \
- rbt_node_new(a_type, a_field, rbtree, node); \
- /* Wind. */ \
- path->node = rbtree->rbt_root; \
- for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) { \
- int cmp = pathp->cmp = a_cmp(node, pathp->node); \
- assert(cmp != 0); \
- if (cmp < 0) { \
- pathp[1].node = rbtn_left_get(a_type, a_field, \
- pathp->node); \
- } else { \
- pathp[1].node = rbtn_right_get(a_type, a_field, \
- pathp->node); \
- } \
- } \
- pathp->node = node; \
- /* Unwind. */ \
- for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \
- a_type *cnode = pathp->node; \
- if (pathp->cmp < 0) { \
- a_type *left = pathp[1].node; \
- rbtn_left_set(a_type, a_field, cnode, left); \
- if (rbtn_red_get(a_type, a_field, left)) { \
- a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
- if (rbtn_red_get(a_type, a_field, leftleft)) { \
- /* Fix up 4-node. */ \
- a_type *tnode; \
- rbtn_black_set(a_type, a_field, leftleft); \
- rbtn_rotate_right(a_type, a_field, cnode, tnode); \
- cnode = tnode; \
- } \
- } else { \
- return; \
- } \
- } else { \
- a_type *right = pathp[1].node; \
- rbtn_right_set(a_type, a_field, cnode, right); \
- if (rbtn_red_get(a_type, a_field, right)) { \
- a_type *left = rbtn_left_get(a_type, a_field, cnode); \
- if (rbtn_red_get(a_type, a_field, left)) { \
- /* Split 4-node. */ \
- rbtn_black_set(a_type, a_field, left); \
- rbtn_black_set(a_type, a_field, right); \
- rbtn_red_set(a_type, a_field, cnode); \
- } else { \
- /* Lean left. */ \
- a_type *tnode; \
- bool tred = rbtn_red_get(a_type, a_field, cnode); \
- rbtn_rotate_left(a_type, a_field, cnode, tnode); \
- rbtn_color_set(a_type, a_field, tnode, tred); \
- rbtn_red_set(a_type, a_field, cnode); \
- cnode = tnode; \
- } \
- } else { \
- return; \
- } \
- } \
- pathp->node = cnode; \
- } \
- /* Set root, and make it black. */ \
- rbtree->rbt_root = path->node; \
- rbtn_black_set(a_type, a_field, rbtree->rbt_root); \
-} \
-a_attr void \
-a_prefix##remove(a_rbt_type *rbtree, a_type *node) { \
- struct { \
- a_type *node; \
- int cmp; \
- } *pathp, *nodep, path[sizeof(void *) << 4]; \
- /* Wind. */ \
- nodep = NULL; /* Silence compiler warning. */ \
- path->node = rbtree->rbt_root; \
- for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) { \
- int cmp = pathp->cmp = a_cmp(node, pathp->node); \
- if (cmp < 0) { \
- pathp[1].node = rbtn_left_get(a_type, a_field, \
- pathp->node); \
- } else { \
- pathp[1].node = rbtn_right_get(a_type, a_field, \
- pathp->node); \
- if (cmp == 0) { \
- /* Find node's successor, in preparation for swap. */ \
- pathp->cmp = 1; \
- nodep = pathp; \
- for (pathp++; pathp->node != &rbtree->rbt_nil; \
- pathp++) { \
- pathp->cmp = -1; \
- pathp[1].node = rbtn_left_get(a_type, a_field, \
- pathp->node); \
- } \
- break; \
- } \
- } \
- } \
- assert(nodep->node == node); \
- pathp--; \
- if (pathp->node != node) { \
- /* Swap node with its successor. */ \
- bool tred = rbtn_red_get(a_type, a_field, pathp->node); \
- rbtn_color_set(a_type, a_field, pathp->node, \
- rbtn_red_get(a_type, a_field, node)); \
- rbtn_left_set(a_type, a_field, pathp->node, \
- rbtn_left_get(a_type, a_field, node)); \
- /* If node's successor is its right child, the following code */\
- /* will do the wrong thing for the right child pointer. */\
- /* However, it doesn't matter, because the pointer will be */\
- /* properly set when the successor is pruned. */\
- rbtn_right_set(a_type, a_field, pathp->node, \
- rbtn_right_get(a_type, a_field, node)); \
- rbtn_color_set(a_type, a_field, node, tred); \
- /* The pruned leaf node's child pointers are never accessed */\
- /* again, so don't bother setting them to nil. */\
- nodep->node = pathp->node; \
- pathp->node = node; \
- if (nodep == path) { \
- rbtree->rbt_root = nodep->node; \
- } else { \
- if (nodep[-1].cmp < 0) { \
- rbtn_left_set(a_type, a_field, nodep[-1].node, \
- nodep->node); \
- } else { \
- rbtn_right_set(a_type, a_field, nodep[-1].node, \
- nodep->node); \
- } \
- } \
- } else { \
- a_type *left = rbtn_left_get(a_type, a_field, node); \
- if (left != &rbtree->rbt_nil) { \
- /* node has no successor, but it has a left child. */\
- /* Splice node out, without losing the left child. */\
- assert(rbtn_red_get(a_type, a_field, node) == false); \
- assert(rbtn_red_get(a_type, a_field, left)); \
- rbtn_black_set(a_type, a_field, left); \
- if (pathp == path) { \
- rbtree->rbt_root = left; \
- } else { \
- if (pathp[-1].cmp < 0) { \
- rbtn_left_set(a_type, a_field, pathp[-1].node, \
- left); \
- } else { \
- rbtn_right_set(a_type, a_field, pathp[-1].node, \
- left); \
- } \
- } \
- return; \
- } else if (pathp == path) { \
- /* The tree only contained one node. */ \
- rbtree->rbt_root = &rbtree->rbt_nil; \
- return; \
- } \
- } \
- if (rbtn_red_get(a_type, a_field, pathp->node)) { \
- /* Prune red node, which requires no fixup. */ \
- assert(pathp[-1].cmp < 0); \
- rbtn_left_set(a_type, a_field, pathp[-1].node, \
- &rbtree->rbt_nil); \
- return; \
- } \
- /* The node to be pruned is black, so unwind until balance is */\
- /* restored. */\
- pathp->node = &rbtree->rbt_nil; \
- for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \
- assert(pathp->cmp != 0); \
- if (pathp->cmp < 0) { \
- rbtn_left_set(a_type, a_field, pathp->node, \
- pathp[1].node); \
- assert(rbtn_red_get(a_type, a_field, pathp[1].node) \
- == false); \
- if (rbtn_red_get(a_type, a_field, pathp->node)) { \
- a_type *right = rbtn_right_get(a_type, a_field, \
- pathp->node); \
- a_type *rightleft = rbtn_left_get(a_type, a_field, \
- right); \
- a_type *tnode; \
- if (rbtn_red_get(a_type, a_field, rightleft)) { \
- /* In the following diagrams, ||, //, and \\ */\
- /* indicate the path to the removed node. */\
- /* */\
- /* || */\
- /* pathp(r) */\
- /* // \ */\
- /* (b) (b) */\
- /* / */\
- /* (r) */\
- /* */\
- rbtn_black_set(a_type, a_field, pathp->node); \
- rbtn_rotate_right(a_type, a_field, right, tnode); \
- rbtn_right_set(a_type, a_field, pathp->node, tnode);\
- rbtn_rotate_left(a_type, a_field, pathp->node, \
- tnode); \
- } else { \
- /* || */\
- /* pathp(r) */\
- /* // \ */\
- /* (b) (b) */\
- /* / */\
- /* (b) */\
- /* */\
- rbtn_rotate_left(a_type, a_field, pathp->node, \
- tnode); \
- } \
- /* Balance restored, but rotation modified subtree */\
- /* root. */\
- assert((uintptr_t)pathp > (uintptr_t)path); \
- if (pathp[-1].cmp < 0) { \
- rbtn_left_set(a_type, a_field, pathp[-1].node, \
- tnode); \
- } else { \
- rbtn_right_set(a_type, a_field, pathp[-1].node, \
- tnode); \
- } \
- return; \
- } else { \
- a_type *right = rbtn_right_get(a_type, a_field, \
- pathp->node); \
- a_type *rightleft = rbtn_left_get(a_type, a_field, \
- right); \
- if (rbtn_red_get(a_type, a_field, rightleft)) { \
- /* || */\
- /* pathp(b) */\
- /* // \ */\
- /* (b) (b) */\
- /* / */\
- /* (r) */\
- a_type *tnode; \
- rbtn_black_set(a_type, a_field, rightleft); \
- rbtn_rotate_right(a_type, a_field, right, tnode); \
- rbtn_right_set(a_type, a_field, pathp->node, tnode);\
- rbtn_rotate_left(a_type, a_field, pathp->node, \
- tnode); \
- /* Balance restored, but rotation modified */\
- /* subree root, which may actually be the tree */\
- /* root. */\
- if (pathp == path) { \
- /* Set root. */ \
- rbtree->rbt_root = tnode; \
- } else { \
- if (pathp[-1].cmp < 0) { \
- rbtn_left_set(a_type, a_field, \
- pathp[-1].node, tnode); \
- } else { \
- rbtn_right_set(a_type, a_field, \
- pathp[-1].node, tnode); \
- } \
- } \
- return; \
- } else { \
- /* || */\
- /* pathp(b) */\
- /* // \ */\
- /* (b) (b) */\
- /* / */\
- /* (b) */\
- a_type *tnode; \
- rbtn_red_set(a_type, a_field, pathp->node); \
- rbtn_rotate_left(a_type, a_field, pathp->node, \
- tnode); \
- pathp->node = tnode; \
- } \
- } \
- } else { \
- a_type *left; \
- rbtn_right_set(a_type, a_field, pathp->node, \
- pathp[1].node); \
- left = rbtn_left_get(a_type, a_field, pathp->node); \
- if (rbtn_red_get(a_type, a_field, left)) { \
- a_type *tnode; \
- a_type *leftright = rbtn_right_get(a_type, a_field, \
- left); \
- a_type *leftrightleft = rbtn_left_get(a_type, a_field, \
- leftright); \
- if (rbtn_red_get(a_type, a_field, leftrightleft)) { \
- /* || */\
- /* pathp(b) */\
- /* / \\ */\
- /* (r) (b) */\
- /* \ */\
- /* (b) */\
- /* / */\
- /* (r) */\
- a_type *unode; \
- rbtn_black_set(a_type, a_field, leftrightleft); \
- rbtn_rotate_right(a_type, a_field, pathp->node, \
- unode); \
- rbtn_rotate_right(a_type, a_field, pathp->node, \
- tnode); \
- rbtn_right_set(a_type, a_field, unode, tnode); \
- rbtn_rotate_left(a_type, a_field, unode, tnode); \
- } else { \
- /* || */\
- /* pathp(b) */\
- /* / \\ */\
- /* (r) (b) */\
- /* \ */\
- /* (b) */\
- /* / */\
- /* (b) */\
- assert(leftright != &rbtree->rbt_nil); \
- rbtn_red_set(a_type, a_field, leftright); \
- rbtn_rotate_right(a_type, a_field, pathp->node, \
- tnode); \
- rbtn_black_set(a_type, a_field, tnode); \
- } \
- /* Balance restored, but rotation modified subtree */\
- /* root, which may actually be the tree root. */\
- if (pathp == path) { \
- /* Set root. */ \
- rbtree->rbt_root = tnode; \
- } else { \
- if (pathp[-1].cmp < 0) { \
- rbtn_left_set(a_type, a_field, pathp[-1].node, \
- tnode); \
- } else { \
- rbtn_right_set(a_type, a_field, pathp[-1].node, \
- tnode); \
- } \
- } \
- return; \
- } else if (rbtn_red_get(a_type, a_field, pathp->node)) { \
- a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
- if (rbtn_red_get(a_type, a_field, leftleft)) { \
- /* || */\
- /* pathp(r) */\
- /* / \\ */\
- /* (b) (b) */\
- /* / */\
- /* (r) */\
- a_type *tnode; \
- rbtn_black_set(a_type, a_field, pathp->node); \
- rbtn_red_set(a_type, a_field, left); \
- rbtn_black_set(a_type, a_field, leftleft); \
- rbtn_rotate_right(a_type, a_field, pathp->node, \
- tnode); \
- /* Balance restored, but rotation modified */\
- /* subtree root. */\
- assert((uintptr_t)pathp > (uintptr_t)path); \
- if (pathp[-1].cmp < 0) { \
- rbtn_left_set(a_type, a_field, pathp[-1].node, \
- tnode); \
- } else { \
- rbtn_right_set(a_type, a_field, pathp[-1].node, \
- tnode); \
- } \
- return; \
- } else { \
- /* || */\
- /* pathp(r) */\
- /* / \\ */\
- /* (b) (b) */\
- /* / */\
- /* (b) */\
- rbtn_red_set(a_type, a_field, left); \
- rbtn_black_set(a_type, a_field, pathp->node); \
- /* Balance restored. */ \
- return; \
- } \
- } else { \
- a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
- if (rbtn_red_get(a_type, a_field, leftleft)) { \
- /* || */\
- /* pathp(b) */\
- /* / \\ */\
- /* (b) (b) */\
- /* / */\
- /* (r) */\
- a_type *tnode; \
- rbtn_black_set(a_type, a_field, leftleft); \
- rbtn_rotate_right(a_type, a_field, pathp->node, \
- tnode); \
- /* Balance restored, but rotation modified */\
- /* subtree root, which may actually be the tree */\
- /* root. */\
- if (pathp == path) { \
- /* Set root. */ \
- rbtree->rbt_root = tnode; \
- } else { \
- if (pathp[-1].cmp < 0) { \
- rbtn_left_set(a_type, a_field, \
- pathp[-1].node, tnode); \
- } else { \
- rbtn_right_set(a_type, a_field, \
- pathp[-1].node, tnode); \
- } \
- } \
- return; \
- } else { \
- /* || */\
- /* pathp(b) */\
- /* / \\ */\
- /* (b) (b) */\
- /* / */\
- /* (b) */\
- rbtn_red_set(a_type, a_field, left); \
- } \
- } \
- } \
- } \
- /* Set root. */ \
- rbtree->rbt_root = path->node; \
- assert(rbtn_red_get(a_type, a_field, rbtree->rbt_root) == false); \
-}/* \
-a_attr a_type * \
-a_prefix##iter_recurse(a_rbt_type *rbtree, a_type *node, \
- a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \
- if (node == &rbtree->rbt_nil) { \
- return (&rbtree->rbt_nil); \
- } else { \
- a_type *ret; \
- if ((ret = a_prefix##iter_recurse(rbtree, rbtn_left_get(a_type, \
- a_field, node), cb, arg)) != &rbtree->rbt_nil \
- || (ret = cb(rbtree, node, arg)) != NULL) { \
- return (ret); \
- } \
- return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \
- a_field, node), cb, arg)); \
- } \
-} \
-a_attr a_type * \
-a_prefix##iter_start(a_rbt_type *rbtree, a_type *start, a_type *node, \
- a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \
- int cmp = a_cmp(start, node); \
- if (cmp < 0) { \
- a_type *ret; \
- if ((ret = a_prefix##iter_start(rbtree, start, \
- rbtn_left_get(a_type, a_field, node), cb, arg)) != \
- &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \
- return (ret); \
- } \
- return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \
- a_field, node), cb, arg)); \
- } else if (cmp > 0) { \
- return (a_prefix##iter_start(rbtree, start, \
- rbtn_right_get(a_type, a_field, node), cb, arg)); \
- } else { \
- a_type *ret; \
- if ((ret = cb(rbtree, node, arg)) != NULL) { \
- return (ret); \
- } \
- return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \
- a_field, node), cb, arg)); \
- } \
-} \
-a_attr a_type * \
-a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \
- a_rbt_type *, a_type *, void *), void *arg) { \
- a_type *ret; \
- if (start != NULL) { \
- ret = a_prefix##iter_start(rbtree, start, rbtree->rbt_root, \
- cb, arg); \
- } else { \
- ret = a_prefix##iter_recurse(rbtree, rbtree->rbt_root, cb, arg);\
- } \
- if (ret == &rbtree->rbt_nil) { \
- ret = NULL; \
- } \
- return (ret); \
-} \
-a_attr a_type * \
-a_prefix##reverse_iter_recurse(a_rbt_type *rbtree, a_type *node, \
- a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \
- if (node == &rbtree->rbt_nil) { \
- return (&rbtree->rbt_nil); \
- } else { \
- a_type *ret; \
- if ((ret = a_prefix##reverse_iter_recurse(rbtree, \
- rbtn_right_get(a_type, a_field, node), cb, arg)) != \
- &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \
- return (ret); \
- } \
- return (a_prefix##reverse_iter_recurse(rbtree, \
- rbtn_left_get(a_type, a_field, node), cb, arg)); \
- } \
-} \
-a_attr a_type * \
-a_prefix##reverse_iter_start(a_rbt_type *rbtree, a_type *start, \
- a_type *node, a_type *(*cb)(a_rbt_type *, a_type *, void *), \
- void *arg) { \
- int cmp = a_cmp(start, node); \
- if (cmp > 0) { \
- a_type *ret; \
- if ((ret = a_prefix##reverse_iter_start(rbtree, start, \
- rbtn_right_get(a_type, a_field, node), cb, arg)) != \
- &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \
- return (ret); \
- } \
- return (a_prefix##reverse_iter_recurse(rbtree, \
- rbtn_left_get(a_type, a_field, node), cb, arg)); \
- } else if (cmp < 0) { \
- return (a_prefix##reverse_iter_start(rbtree, start, \
- rbtn_left_get(a_type, a_field, node), cb, arg)); \
- } else { \
- a_type *ret; \
- if ((ret = cb(rbtree, node, arg)) != NULL) { \
- return (ret); \
- } \
- return (a_prefix##reverse_iter_recurse(rbtree, \
- rbtn_left_get(a_type, a_field, node), cb, arg)); \
- } \
-} \
-a_attr a_type * \
-a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \
- a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \
- a_type *ret; \
- if (start != NULL) { \
- ret = a_prefix##reverse_iter_start(rbtree, start, \
- rbtree->rbt_root, cb, arg); \
- } else { \
- ret = a_prefix##reverse_iter_recurse(rbtree, rbtree->rbt_root, \
- cb, arg); \
- } \
- if (ret == &rbtree->rbt_nil) { \
- ret = NULL; \
- } \
- return (ret); \
-}*/
-
-#endif /* RB_H_ */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2config/db_config.h b/plugins/Dbx_kv/src/hamsterdb/src/2config/db_config.h
deleted file mode 100644
index 77f63944ef..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2config/db_config.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The configuration settings of a Database.
- *
- * @exception_safe nothrow
- * @thread_safe no
- */
-
-#ifndef HAM_DB_CONFIG_H
-#define HAM_DB_CONFIG_H
-
-#include "0root/root.h"
-
-#include <ham/types.h>
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct DatabaseConfiguration
-{
- // Constructor initializes with default values
- DatabaseConfiguration()
- : db_name(0), flags(0), key_type(HAM_TYPE_BINARY),
- key_size(HAM_KEY_SIZE_UNLIMITED), record_size(HAM_RECORD_SIZE_UNLIMITED),
- key_compressor(0), record_compressor(0) {
- }
-
- // the database name
- uint16_t db_name;
-
- // the database flags
- uint32_t flags;
-
- // the key type
- int key_type;
-
- // the key size (if specified)
- size_t key_size;
-
- // the record size (if specified)
- size_t record_size;
-
- // the algorithm for key compression
- int key_compressor;
-
- // the algorithm for record compression
- int record_compressor;
-
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_DB_CONFIG_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2config/env_config.h b/plugins/Dbx_kv/src/hamsterdb/src/2config/env_config.h
deleted file mode 100644
index 9db5de4771..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2config/env_config.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The configuration settings of an Environment.
- *
- * @exception_safe nothrow
- * @thread_safe no
- */
-
-#ifndef HAM_ENV_CONFIG_H
-#define HAM_ENV_CONFIG_H
-
-#include "0root/root.h"
-
-#include <string>
-#include <limits>
-
-#include <ham/hamsterdb.h>
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-#undef max
-
-namespace hamsterdb {
-
-struct EnvironmentConfiguration
-{
- // Constructor initializes with default values
- EnvironmentConfiguration()
- : flags(0), file_mode(0644), max_databases(0),
- page_size_bytes(HAM_DEFAULT_PAGE_SIZE),
- cache_size_bytes(HAM_DEFAULT_CACHE_SIZE),
- file_size_limit_bytes(std::numeric_limits<size_t>::max()),
- remote_timeout_sec(0), journal_compressor(0),
- is_encryption_enabled(false), journal_switch_threshold(0),
- posix_advice(HAM_POSIX_FADVICE_NORMAL) {
- }
-
- // the environment's flags
- uint32_t flags;
-
- // the file mode
- int file_mode;
-
- // the number of databases
- int max_databases;
-
- // the page size (in bytes)
- size_t page_size_bytes;
-
- // the cache size (in bytes)
- uint64_t cache_size_bytes;
-
- // the file size limit (in bytes)
- size_t file_size_limit_bytes;
-
- // the remote timeout (in seconds)
- size_t remote_timeout_sec;
-
- // the path (or remote location)
- std::string filename;
-
- // the path of the logfile
- std::string log_filename;
-
- // the algorithm for journal compression
- int journal_compressor;
-
- // true if AES encryption is enabled
- bool is_encryption_enabled;
-
- // the AES encryption key
- uint8_t encryption_key[16];
-
- // threshold for switching journal files
- size_t journal_switch_threshold;
-
- // parameter for posix_fadvise()
- int posix_advice;
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_ENV_CONFIG_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2device/device.h b/plugins/Dbx_kv/src/hamsterdb/src/2device/device.h
deleted file mode 100644
index 7550fad06a..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2device/device.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Device management; a device encapsulates the physical device, either a
- * file or memory chunks (for in-memory-databases)
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_DEVICE_H
-#define HAM_DEVICE_H
-
-#include "0root/root.h"
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "2config/env_config.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Page;
-
-class Device {
- public:
- // Constructor
- Device(const EnvironmentConfiguration &config)
- : m_config(config) {
- }
-
- // virtual destructor
- virtual ~Device() {
- }
-
- // Returns the current page size
- size_t page_size() const {
- return (m_config.page_size_bytes);
- }
-
- // Create a new device - called in ham_env_create
- virtual void create() = 0;
-
- // Opens an existing device - called in ham_env_open
- virtual void open() = 0;
-
- // Returns true if the device is open
- virtual bool is_open() = 0;
-
- // Closes the device - called in ham_env_close
- virtual void close() = 0;
-
- // Flushes the device - called in ham_env_flush
- virtual void flush() = 0;
-
- // Truncate/resize the device
- virtual void truncate(uint64_t new_size) = 0;
-
- // Returns the current file/storage size
- virtual uint64_t file_size() = 0;
-
- // Seek position in a file
- virtual void seek(uint64_t offset, int whence) = 0;
-
- // Tell the position in a file
- virtual uint64_t tell() = 0;
-
- // Reads from the device; this function does not use mmap
- virtual void read(uint64_t offset, void *buffer, size_t len) = 0;
-
- // Writes to the device; this function does not use mmap
- virtual void write(uint64_t offset, void *buffer, size_t len) = 0;
-
- // Allocate storage from this device; this function
- // will *NOT* use mmap. returns the offset of the allocated storage.
- virtual uint64_t alloc(size_t len) = 0;
-
- // Reads a page from the device; this function CAN use mmap
- virtual void read_page(Page *page, uint64_t address) = 0;
-
- // Writes a page to the device
- virtual void write_page(Page *page) = 0;
-
- // Allocate storage for a page from this device; this function
- // can use mmap if available
- virtual void alloc_page(Page *page) = 0;
-
- // Frees a page on the device.
- // The caller is responsible for flushing the page; the @ref free_page
- // function will assert that the page is not dirty.
- virtual void free_page(Page *page) = 0;
-
- // Returns true if the specified range is in mapped memory
- virtual bool is_mapped(uint64_t file_offset, size_t size) const = 0;
-
- protected:
- // the Environment configuration settings
- const EnvironmentConfiguration &m_config;
-
- friend class DeviceTest;
- friend class InMemoryDeviceTest;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_DEVICE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2device/device_disk.h b/plugins/Dbx_kv/src/hamsterdb/src/2device/device_disk.h
deleted file mode 100644
index 1bd62a904e..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2device/device_disk.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Device-implementation for disk-based files. Exception safety is "strong"
- * for most operations, but currently it's possible that the Page is modified
- * if DiskDevice::read_page fails in the middle.
- *
- * @exception_safe: basic/strong
- * @thread_safe: no
- */
-
-#ifndef HAM_DEVICE_DISK_H
-#define HAM_DEVICE_DISK_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1os/file.h"
-#include "1mem/mem.h"
-#include "2device/device.h"
-#include "2page/page.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/*
- * a File-based device
- */
-class DiskDevice : public Device {
- struct State {
- // the database file
- File file;
-
- // pointer to the the mmapped data
- uint8_t *mmapptr;
-
- // the size of mmapptr as used in mmap
- uint64_t mapped_size;
-
- // the (cached) size of the file
- uint64_t file_size;
- };
-
- public:
- DiskDevice(const EnvironmentConfiguration &config)
- : Device(config) {
- State state;
- state.mmapptr = 0;
- state.mapped_size = 0;
- state.file_size = 0;
- std::swap(m_state, state);
- }
-
- // Create a new device
- virtual void create() {
- File file;
- file.create(m_config.filename.c_str(), m_config.file_mode);
- file.set_posix_advice(m_config.posix_advice);
- m_state.file = file;
- }
-
- // opens an existing device
- //
- // tries to map the file; if it fails then continue with read/write
- virtual void open() {
- bool read_only = (m_config.flags & HAM_READ_ONLY) != 0;
-
- State state = m_state;
- state.file.open(m_config.filename.c_str(), read_only);
- state.file.set_posix_advice(m_config.posix_advice);
-
- // the file size which backs the mapped ptr
- state.file_size = state.file.get_file_size();
-
- if (m_config.flags & HAM_DISABLE_MMAP) {
- std::swap(m_state, state);
- return;
- }
-
- // make sure we do not exceed the "real" size of the file, otherwise
- // we crash when accessing memory which exceeds the mapping (at least
- // on Win32)
- size_t granularity = File::get_granularity();
- if (state.file_size == 0 || state.file_size % granularity) {
- std::swap(m_state, state);
- return;
- }
-
- state.mapped_size = state.file_size;
- state.file.mmap(0, state.mapped_size, read_only, &state.mmapptr);
- std::swap(m_state, state);
- }
-
- // returns true if the device is open
- virtual bool is_open() {
- return (m_state.file.is_open());
- }
-
- // closes the device
- virtual void close() {
- State state = m_state;
- if (state.mmapptr)
- state.file.munmap(state.mmapptr, state.mapped_size);
- state.file.close();
-
- std::swap(m_state, state);
- }
-
- // flushes the device
- virtual void flush() {
- m_state.file.flush();
- }
-
- // truncate/resize the device
- virtual void truncate(uint64_t new_file_size) {
- if (new_file_size > m_config.file_size_limit_bytes)
- throw Exception(HAM_LIMITS_REACHED);
- m_state.file.truncate(new_file_size);
- m_state.file_size = new_file_size;
- }
-
- // get the current file/storage size
- virtual uint64_t file_size() {
- ham_assert(m_state.file_size == m_state.file.get_file_size());
- return (m_state.file_size);
- }
-
- // seek to a position in a file
- virtual void seek(uint64_t offset, int whence) {
- m_state.file.seek(offset, whence);
- }
-
- // tell the position in a file
- virtual uint64_t tell() {
- return (m_state.file.tell());
- }
-
- // reads from the device; this function does NOT use mmap
- virtual void read(uint64_t offset, void *buffer, size_t len) {
- m_state.file.pread(offset, buffer, len);
- }
-
- // writes to the device; this function does not use mmap,
- // and is responsible for writing the data is run through the file
- // filters
- virtual void write(uint64_t offset, void *buffer, size_t len) {
- m_state.file.pwrite(offset, buffer, len);
- }
-
- // allocate storage from this device; this function
- // will *NOT* return mmapped memory
- virtual uint64_t alloc(size_t len) {
- uint64_t address = m_state.file_size;
- truncate(address + len);
- return ((uint64_t)address);
- }
-
- // reads a page from the device; this function CAN return a
- // pointer to mmapped memory
- virtual void read_page(Page *page, uint64_t address) {
- // if this page is in the mapped area: return a pointer into that area.
- // otherwise fall back to read/write.
- if (address < m_state.mapped_size && m_state.mmapptr != 0) {
- // ok, this page is mapped. If the Page object has a memory buffer
- // then free it; afterwards return a pointer into the mapped memory
- page->free_buffer();
- // the following line will not throw a C++ exception, but can
- // raise a signal. If that's the case then we don't catch it because
- // something is seriously wrong and proper recovery is not possible.
- page->assign_mapped_buffer(&m_state.mmapptr[address], address);
- return;
- }
-
- // this page is not in the mapped area; allocate a buffer
- if (page->get_data() == 0) {
- // note that |p| will not leak if file.pread() throws; |p| is stored
- // in the |page| object and will be cleaned up by the caller in
- // case of an exception.
- uint8_t *p = Memory::allocate<uint8_t>(m_config.page_size_bytes);
- page->assign_allocated_buffer(p, address);
- }
-
- m_state.file.pread(address, page->get_data(), m_config.page_size_bytes);
- }
-
- // writes a page to the device
- virtual void write_page(Page *page) {
- write(page->get_address(), page->get_data(), m_config.page_size_bytes);
- }
-
- // Allocates storage for a page from this device; this function
- // will *NOT* return mmapped memory
- virtual void alloc_page(Page *page) {
- uint64_t address = m_state.file_size;
-
- truncate(address + m_config.page_size_bytes);
- page->set_address(address);
-
- // allocate a memory buffer
- uint8_t *p = Memory::allocate<uint8_t>(m_config.page_size_bytes);
- page->assign_allocated_buffer(p, address);
- }
-
- // Frees a page on the device; plays counterpoint to |alloc_page|
- virtual void free_page(Page *page) {
- ham_assert(page->get_data() != 0);
- page->free_buffer();
- }
-
- // Returns true if the specified range is in mapped memory
- virtual bool is_mapped(uint64_t file_offset, size_t size) const {
- return (file_offset + size <= m_state.mapped_size);
- }
-
- private:
- State m_state;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_DEVICE_DISK_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2device/device_factory.h b/plugins/Dbx_kv/src/hamsterdb/src/2device/device_factory.h
deleted file mode 100644
index 7cde29d5af..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2device/device_factory.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A factory for Device objects
- *
- * @exception_safe: strong
- * @thread_safe: yes
- */
-
-#ifndef HAM_DEVICE_FACTORY_H
-#define HAM_DEVICE_FACTORY_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "2config/env_config.h"
-#include "2device/device_disk.h"
-#include "2device/device_inmem.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct DeviceFactory {
- // creates a new Device instance depending on the flags
- static Device *create(const EnvironmentConfiguration &config) {
- if (config.flags & HAM_IN_MEMORY)
- return (new InMemoryDevice(config));
- else
- return (new DiskDevice(config));
- }
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_DEVICE_FACTORY_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2device/device_inmem.h b/plugins/Dbx_kv/src/hamsterdb/src/2device/device_inmem.h
deleted file mode 100644
index 3e2055148b..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2device/device_inmem.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: strong
- * @thread_safe: no
- */
-
-#ifndef HAM_DEVICE_INMEM_H
-#define HAM_DEVICE_INMEM_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1mem/mem.h"
-#include "2device/device.h"
-#include "2page/page.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/*
- * an In-Memory device
- */
-class InMemoryDevice : public Device {
- struct State {
- // flag whether this device was "opened" or is uninitialized
- bool is_open;
-
- // the allocated bytes
- uint64_t allocated_size;
- };
-
- public:
- // constructor
- InMemoryDevice(const EnvironmentConfiguration &config)
- : Device(config) {
- State state;
- state.is_open = false;
- state.allocated_size = 0;
- std::swap(m_state, state);
- }
-
- // Create a new device
- virtual void create() {
- m_state.is_open = true;
- }
-
- // opens an existing device
- virtual void open() {
- ham_assert(!"can't open an in-memory-device");
- throw Exception(HAM_NOT_IMPLEMENTED);
- }
-
- // returns true if the device is open
- virtual bool is_open() {
- return (m_state.is_open);
- }
-
- // closes the device
- virtual void close() {
- ham_assert(m_state.is_open);
- m_state.is_open = false;
- }
-
- // flushes the device
- virtual void flush() {
- }
-
- // truncate/resize the device
- virtual void truncate(uint64_t newsize) {
- }
-
- // get the current file/storage size
- virtual uint64_t file_size() {
- ham_assert(!"this operation is not possible for in-memory-databases");
- throw Exception(HAM_NOT_IMPLEMENTED);
- }
-
- // seek position in a file
- virtual void seek(uint64_t offset, int whence) {
- ham_assert(!"can't seek in an in-memory-device");
- throw Exception(HAM_NOT_IMPLEMENTED);
- }
-
- // tell the position in a file
- virtual uint64_t tell() {
- ham_assert(!"can't tell in an in-memory-device");
- throw Exception(HAM_NOT_IMPLEMENTED);
- }
-
- // reads from the device; this function does not use mmap
- virtual void read(uint64_t offset, void *buffer, size_t len) {
- ham_assert(!"operation is not possible for in-memory-databases");
- throw Exception(HAM_NOT_IMPLEMENTED);
- }
-
- // writes to the device
- virtual void write(uint64_t offset, void *buffer, size_t len) {
- ham_assert(!"operation is not possible for in-memory-databases");
- throw Exception(HAM_NOT_IMPLEMENTED);
- }
-
- // reads a page from the device
- virtual void read_page(Page *page, uint64_t address) {
- ham_assert(!"operation is not possible for in-memory-databases");
- throw Exception(HAM_NOT_IMPLEMENTED);
- }
-
- // writes a page to the device
- virtual void write_page(Page *page) {
- }
-
- // allocate storage from this device; this function
- // will *NOT* use mmap.
- virtual uint64_t alloc(size_t size) {
- if (m_state.allocated_size + size > m_config.file_size_limit_bytes)
- throw Exception(HAM_LIMITS_REACHED);
-
- uint64_t retval = (uint64_t)Memory::allocate<uint8_t>(size);
- m_state.allocated_size += size;
- return (retval);
- }
-
- // allocate storage for a page from this device
- virtual void alloc_page(Page *page) {
- ham_assert(page->get_data() == 0);
-
- size_t page_size = m_config.page_size_bytes;
- if (m_state.allocated_size + page_size > m_config.file_size_limit_bytes)
- throw Exception(HAM_LIMITS_REACHED);
-
- uint8_t *p = Memory::allocate<uint8_t>(page_size);
- page->assign_allocated_buffer(p, (uint64_t)PTR_TO_U64(p));
-
- m_state.allocated_size += page_size;
- }
-
- // frees a page on the device; plays counterpoint to @ref alloc_page
- virtual void free_page(Page *page) {
- page->free_buffer();
-
- ham_assert(m_state.allocated_size >= m_config.page_size_bytes);
- m_state.allocated_size -= m_config.page_size_bytes;
- }
-
- // Returns true if the specified range is in mapped memory
- virtual bool is_mapped(uint64_t file_offset, size_t size) const {
- return (false);
- }
-
- // releases a chunk of memory previously allocated with alloc()
- void release(void *ptr, size_t size) {
- Memory::release(ptr);
- ham_assert(m_state.allocated_size >= size);
- m_state.allocated_size -= size;
- }
-
- private:
- State m_state;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_DEVICE_INMEM_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2lsn_manager/lsn_manager.h b/plugins/Dbx_kv/src/hamsterdb/src/2lsn_manager/lsn_manager.h
deleted file mode 100644
index 3a6be50d44..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2lsn_manager/lsn_manager.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Manager for the log sequence number (lsn)
- *
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_LSN_MANAGER_H
-#define HAM_LSN_MANAGER_H
-
-#include "0root/root.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class LsnManager
-{
- public:
- // Constructor
- LsnManager()
- : m_state(1) {
- }
-
- // Returns the next lsn
- uint64_t next() {
- return (m_state++);
- }
-
- private:
- friend struct LsnManagerTest;
-
- // the actual lsn
- uint64_t m_state;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_LSN_MANAGER_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2lsn_manager/lsn_manager_test.h b/plugins/Dbx_kv/src/hamsterdb/src/2lsn_manager/lsn_manager_test.h
deleted file mode 100644
index 59197a66cd..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2lsn_manager/lsn_manager_test.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Test gateway for LsnManager
- *
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_LSN_MANAGER_TEST_H
-#define HAM_LSN_MANAGER_TEST_H
-
-#include "0root/root.h"
-
-#include "2lsn_manager/lsn_manager.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct LsnManagerTest
-{
- // Constructor
- LsnManagerTest(LsnManager *lsn_manager)
- : m_state(lsn_manager->m_state) {
- }
-
- // Returns the current lsn
- uint64_t lsn() const {
- return (m_state);
- }
-
- uint64_t &m_state;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_LSN_MANAGER_TEST_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2page/page.cc b/plugins/Dbx_kv/src/hamsterdb/src/2page/page.cc
deleted file mode 100644
index 64558e9370..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2page/page.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-
-#include "1base/error.h"
-#include "1os/os.h"
-#include "2page/page.h"
-#include "2device/device.h"
-#include "3btree/btree_node_proxy.h"
-
-namespace hamsterdb {
-
-uint64_t Page::ms_page_count_flushed = 0;
-
-Page::Page(Device *device, LocalDatabase *db)
- : m_device(device), m_db(db), m_address(0), m_is_allocated(false),
- m_is_without_header(false), m_is_dirty(false), m_cursor_list(0),
- m_node_proxy(0), m_data(0)
-{
- memset(&m_prev[0], 0, sizeof(m_prev));
- memset(&m_next[0], 0, sizeof(m_next));
-}
-
-Page::~Page()
-{
- ham_assert(m_cursor_list == 0);
-
-#ifdef HAM_ENABLE_HELGRIND
- // safely unlock the mutex
- m_mutex.try_lock();
-#endif
- m_mutex.unlock();
-
- if (m_node_proxy) {
- delete m_node_proxy;
- m_node_proxy = 0;
- }
-
- if (m_data != 0)
- m_device->free_page(this);
-}
-
-void
-Page::alloc(uint32_t type, uint32_t flags)
-{
- m_device->alloc_page(this);
-
- if (flags & kInitializeWithZeroes) {
- size_t page_size = m_device->page_size();
- memset(get_raw_payload(), 0, page_size);
- }
-
- if (type)
- set_type(type);
-}
-
-void
-Page::fetch(uint64_t address)
-{
- m_device->read_page(this, address);
- set_address(address);
-}
-
-void
-Page::flush()
-{
- if (is_dirty()) {
- m_device->write_page(this);
- set_dirty(false);
- ms_page_count_flushed++;
- }
-}
-
-void
-Page::free_buffer()
-{
- if (m_node_proxy) {
- delete m_node_proxy;
- m_node_proxy = 0;
- }
-
- if (m_is_allocated)
- Memory::release(m_data);
- m_data = 0;
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2page/page.h b/plugins/Dbx_kv/src/hamsterdb/src/2page/page.h
deleted file mode 100644
index f68edc474b..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2page/page.h
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: strong
- * @thread_safe: no
- */
-
-#ifndef HAM_PAGE_H
-#define HAM_PAGE_H
-
-#include <string.h>
-#include <boost/atomic.hpp>
-
-#include "1base/error.h"
-#include "1base/spinlock.h"
-#include "1mem/mem.h"
-
-namespace hamsterdb {
-
-class Device;
-class BtreeCursor;
-class BtreeNodeProxy;
-class LocalDatabase;
-
-#include "1base/packstart.h"
-
-/*
- * This header is only available if the (non-persistent) flag
- * kNpersNoHeader is not set! Blob pages do not have this header.
- */
-typedef HAM_PACK_0 struct HAM_PACK_1 PPageHeader {
- // flags of this page - currently only used for the Page::kType* codes
- uint32_t flags;
-
- // reserved
- uint32_t reserved;
-
- // the lsn of the last operation
- uint64_t lsn;
-
- // the persistent data blob
- uint8_t payload[1];
-
-} HAM_PACK_2 PPageHeader;
-
-#include "1base/packstop.h"
-
-#include "1base/packstart.h"
-
-/*
- * A union combining the page header and a pointer to the raw page data.
- *
- * This structure definition is present outside of @ref Page scope
- * to allow compile-time OFFSETOF macros to correctly judge the size,
- * depending on platform and compiler settings.
- */
-typedef HAM_PACK_0 union HAM_PACK_1 PPageData {
- // the persistent header
- struct PPageHeader header;
-
- // a char pointer to the allocated storage on disk
- uint8_t payload[1];
-
-} HAM_PACK_2 PPageData;
-
-#include "1base/packstop.h"
-
-/*
- * The Page class
- *
- * Each Page instance is a node in several linked lists.
- * In order to avoid multiple memory allocations, the previous/next pointers
- * are part of the Page class (m_prev and m_next). Both fields are arrays
- * of pointers and can be used i.e. with m_prev[Page::kListBucket] etc.
- * (or with the methods defined below).
- */
-class Page {
- public:
- // Misc. enums
- enum {
- // sizeof the persistent page header
- kSizeofPersistentHeader = sizeof(PPageHeader) - 1,
-
- // instruct Page::alloc() to reset the page with zeroes
- kInitializeWithZeroes,
- };
-
- // The various linked lists (indices in m_prev, m_next)
- enum {
- // list of all cached pages
- kListCache = 0,
-
- // list of all pages in a changeset
- kListChangeset = 1,
-
- // a bucket in the hash table of the cache
- kListBucket = 2,
-
- // array limit
- kListMax = 3
- };
-
- // non-persistent page flags
- enum {
- // page->m_data was allocated with malloc, not mmap
- kNpersMalloc = 1,
-
- // page has no header (i.e. it's part of a large blob)
- kNpersNoHeader = 2
- };
-
- // Page types
- //
- // When large BLOBs span multiple pages, only their initial page
- // will have a valid type code; subsequent pages of this blog will store
- // the data as-is, so as to provide one continuous storage space
- enum {
- // unidentified db page type
- kTypeUnknown = 0x00000000,
-
- // the header page: this is the first page in the environment (offset 0)
- kTypeHeader = 0x10000000,
-
- // a B+tree root page
- kTypeBroot = 0x20000000,
-
- // a B+tree node page
- kTypeBindex = 0x30000000,
-
- // a page storing the state of the PageManager
- kTypePageManager = 0x40000000,
-
- // a page which stores blobs
- kTypeBlob = 0x50000000
- };
-
- // Default constructor
- Page(Device *device, LocalDatabase *db = 0);
-
- // Destructor - releases allocated memory and resources, but neither
- // flushes dirty pages to disk nor moves them to the freelist!
- // Asserts that no cursors are attached.
- ~Page();
-
- // Returns the size of the usable persistent payload of a page
- // (page_size minus the overhead of the page header)
- static uint32_t usable_page_size(uint32_t raw_page_size) {
- return (raw_page_size - Page::kSizeofPersistentHeader);
- }
-
-
- // Returns the database which manages this page; can be NULL if this
- // page belongs to the Environment (i.e. for freelist-pages)
- LocalDatabase *get_db() {
- return (m_db);
- }
-
- // Sets the database to which this Page belongs
- void set_db(LocalDatabase *db) {
- m_db = db;
- }
-
- // Returns the spinlock
- Spinlock &mutex() {
- return (m_mutex);
- }
-
- // Returns the device
- Device *device() {
- return (m_device);
- }
-
- // Returns true if this is the header page of the Environment
- bool is_header() const {
- return (m_address == 0);
- }
-
- // Returns the address of this page
- uint64_t get_address() const {
- return (m_address);
- }
-
- // Sets the address of this page
- void set_address(uint64_t address) {
- m_address = address;
- }
-
- // Returns true if this page is dirty (and needs to be flushed to disk)
- bool is_dirty() const {
- return (m_is_dirty);
- }
-
- // Sets this page dirty/not dirty
- void set_dirty(bool dirty) {
- m_is_dirty = dirty;
- }
-
- // Returns true if the page's buffer was allocated with malloc
- bool is_allocated() const {
- return (m_is_allocated);
- }
-
- // Returns true if the page has no persistent header
- bool is_without_header() const {
- return (m_is_without_header);
- }
-
- // Sets a flag whether the page has no persistent header
- void set_without_header(bool without_header) {
- m_is_without_header = without_header;
- }
-
- // Assign a buffer which was allocated with malloc()
- void assign_allocated_buffer(void *buffer, uint64_t address) {
- m_data = (PPageData *)buffer;
- m_is_allocated = true;
- m_address = address;
- }
-
- // Assign a buffer from mmapped storage
- void assign_mapped_buffer(void *buffer, uint64_t address) {
- m_data = (PPageData *)buffer;
- m_is_allocated = false;
- m_address = address;
- }
-
- // Free resources associated with the buffer
- void free_buffer();
-
- // Returns the linked list of coupled cursors (can be NULL)
- BtreeCursor *cursor_list() {
- return (m_cursor_list);
- }
-
- // Sets the (head of the) linked list of cursors
- void set_cursor_list(BtreeCursor *cursor) {
- m_cursor_list = cursor;
- }
-
- // Returns the page's type (kType*)
- uint32_t get_type() const {
- return (m_data->header.flags);
- }
-
- // Sets the page's type (kType*)
- void set_type(uint32_t type) {
- m_data->header.flags = type;
- }
-
- // Returns the lsn of the last modification
- uint64_t get_lsn() const {
- return (m_data->header.lsn);
- }
-
- // Sets the lsn of the last modification
- void set_lsn(uint64_t lsn) {
- m_data->header.lsn = lsn;
- }
-
- // Sets the pointer to the persistent data
- void set_data(PPageData *data) {
- m_data = data;
- }
-
- // Returns the pointer to the persistent data
- PPageData *get_data() {
- return (m_data);
- }
-
- // Returns the persistent payload (after the header!)
- uint8_t *get_payload() {
- return (m_data->header.payload);
- }
-
- // Returns the persistent payload (after the header!)
- const uint8_t *get_payload() const {
- return (m_data->header.payload);
- }
-
- // Returns the persistent payload (including the header!)
- uint8_t *get_raw_payload() {
- return (m_data->payload);
- }
-
- // Returns the persistent payload (including the header!)
- const uint8_t *get_raw_payload() const {
- return (m_data->payload);
- }
-
- // Allocates a new page from the device
- // |flags|: either 0 or kInitializeWithZeroes
- void alloc(uint32_t type, uint32_t flags = 0);
-
- // Reads a page from the device
- void fetch(uint64_t address);
-
- // Writes the page to the device
- void flush();
-
- // Returns true if this page is in a linked list
- bool is_in_list(Page *list_head, int list) {
- if (get_next(list) != 0)
- return (true);
- if (get_previous(list) != 0)
- return (true);
- return (list_head == this);
- }
-
- // Inserts this page at the beginning of a list and returns the
- // new head of the list
- Page *list_insert(Page *list_head, int list) {
- set_next(list, 0);
- set_previous(list, 0);
-
- if (!list_head)
- return (this);
-
- set_next(list, list_head);
- list_head->set_previous(list, this);
- return (this);
- }
-
- // Removes this page from a list and returns the new head of the list
- Page *list_remove(Page *list_head, int list) {
- Page *n, *p;
-
- if (this == list_head) {
- n = get_next(list);
- if (n)
- n->set_previous(list, 0);
- set_next(list, 0);
- set_previous(list, 0);
- return (n);
- }
-
- n = get_next(list);
- p = get_previous(list);
- if (p)
- p->set_next(list, n);
- if (n)
- n->set_previous(list, p);
- set_next(list, 0);
- set_previous(list, 0);
- return (list_head);
- }
-
- // Returns the next page in a linked list
- Page *get_next(int list) {
- return (m_next[list]);
- }
-
- // Returns the previous page of a linked list
- Page *get_previous(int list) {
- return (m_prev[list]);
- }
-
- // Returns the cached BtreeNodeProxy
- BtreeNodeProxy *get_node_proxy() {
- return (m_node_proxy);
- }
-
- // Sets the cached BtreeNodeProxy
- void set_node_proxy(BtreeNodeProxy *proxy) {
- m_node_proxy = proxy;
- }
-
- // tracks number of flushed pages
- static uint64_t ms_page_count_flushed;
-
- private:
- friend class PageCollection;
-
- // Sets the previous page of a linked list
- void set_previous(int list, Page *other) {
- m_prev[list] = other;
- }
-
- // Sets the next page in a linked list
- void set_next(int list, Page *other) {
- m_next[list] = other;
- }
-
- // the Device for allocating storage
- Device *m_device;
-
- // the Database handle (can be NULL)
- LocalDatabase *m_db;
-
- // The spinlock is locked if the page is in use or written to disk
- Spinlock m_mutex;
-
- // address of this page
- uint64_t m_address;
-
- // Page buffer was allocated with malloc() (if not then it was mapped
- // with mmap)
- bool m_is_allocated;
-
- // Page does not have a persistent header
- bool m_is_without_header;
-
- // is this page dirty and needs to be flushed to disk?
- bool m_is_dirty;
-
- // linked list of all cursors which point to that page
- BtreeCursor *m_cursor_list;
-
- // linked lists of pages - see comments above
- Page *m_prev[Page::kListMax];
- Page *m_next[Page::kListMax];
-
- // the cached BtreeNodeProxy object
- BtreeNodeProxy *m_node_proxy;
-
- // the persistent data of this page
- PPageData *m_data;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_PAGE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2page/page_collection.h b/plugins/Dbx_kv/src/hamsterdb/src/2page/page_collection.h
deleted file mode 100644
index b396c78165..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2page/page_collection.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: strong
- * @thread_safe: no
- */
-
-#ifndef HAM_PAGE_COLLECTION_H
-#define HAM_PAGE_COLLECTION_H
-
-#include <string.h>
-
-#include <boost/atomic.hpp>
-
-#include "1mem/mem.h"
-#include "2page/page.h"
-
-namespace hamsterdb {
-
-/*
- * The PageCollection class
- */
-class PageCollection {
- public:
- // Default constructor
- PageCollection(int list_id)
- : m_head(0), m_tail(0), m_size(0), m_id(list_id) {
- }
-
- // Destructor
- ~PageCollection() {
- clear();
- }
-
- bool is_empty() const {
- return (m_size == 0);
- }
-
- int size() const {
- return (m_size);
- }
-
- // Atomically applies the |visitor()| to each page
- template<typename Visitor>
- void for_each(Visitor &visitor) {
- for (Page *p = m_head; p != 0; p = p->get_next(m_id)) {
- if (!visitor(p))
- break;
- }
- }
-
- // Atomically applies the |visitor()| to each page; starts at the tail
- template<typename Visitor>
- void for_each_reverse(Visitor &visitor) {
- for (Page *p = m_tail; p != 0; p = p->get_previous(m_id)) {
- if (!visitor(p))
- break;
- }
- }
-
- // Same as |for_each()|, but removes the page if |visitor()| returns true
- template<typename Visitor>
- void extract(Visitor &visitor) {
- Page *page = m_head;
- while (page) {
- Page *next = page->get_next(m_id);
- if (visitor(page)) {
- del_impl(page);
- }
- page = next;
- }
- }
-
- // Clears the collection.
- void clear() {
- Page *page = m_head;
- while (page) {
- Page *next = page->get_next(m_id);
- del_impl(page);
- page = next;
- }
-
- ham_assert(m_head == 0);
- ham_assert(m_tail == 0);
- ham_assert(m_size == 0);
- }
-
- // Returns the head
- Page *head() const {
- return (m_head);
- }
-
- // Returns the tail
- Page *tail() const {
- return (m_tail);
- }
-
- // Returns a page from the collection
- Page *get(uint64_t address) const {
- for (Page *p = m_head; p != 0; p = p->get_next(m_id)) {
- if (p->get_address() == address)
- return (p);
- }
- return (0);
- }
-
- // Removes a page from the collection. Returns true if the page was removed,
- // otherwise false (if the page was not in the list)
- bool del(Page *page) {
- if (has(page)) {
- del_impl(page);
- return (true);
- }
- return (false);
- }
-
- // Adds a new page at the head of the list. Returns true if the page was
- // added, otherwise false (that's the case if the page is already part of
- // the list)
- bool put(Page *page) {
- if (!has(page)) {
- m_head = page->list_insert(m_head, m_id);
- if (!m_tail)
- m_tail = page;
- ++m_size;
- return (true);
- }
- return (false);
- }
-
- // Returns true if a page with the |address| is already stored.
- bool has(uint64_t address) const {
- return (get(address) != 0);
- }
-
- // Returns true if the |page| is already stored. This is much faster
- // than has(uint64_t address).
- bool has(Page *page) const {
- return (page->is_in_list(m_head, m_id));
- }
-
- private:
- void del_impl(Page *page) {
- // First update the tail because Page::list_remove() will change the
- // pointers!
- if (m_tail == page)
- m_tail = page->get_previous(m_id);
- m_head = page->list_remove(m_head, m_id);
- ham_assert(m_size > 0);
- --m_size;
- }
-
- // The head of the linked list
- Page *m_head;
-
- // The tail of the linked list
- Page *m_tail;
-
- // Number of elements in the list
- int m_size;
-
- // The list ID
- int m_id;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_PAGE_COLLECTION_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/Makefile.am b/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/Makefile.am
deleted file mode 100644
index b5c5c881f4..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-
-AM_CPPFLAGS = -DHAM_ENABLE_REMOTE -I$(top_builddir)/include
-
-# INCLUDES =
-
-noinst_LTLIBRARIES = libprotocol.la
-
-nodist_libprotocol_la_SOURCES = messages.pb.cc
-libprotocol_la_SOURCES = protocol.h
-libprotocol_la_LIBADD = -lprotobuf
-
-EXTRA_DIST = messages.proto
-messages.pb.cc proto: $(srcdir)/messages.proto
- protoc $(srcdir)/messages.proto --cpp_out=.
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/Makefile.in b/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/Makefile.in
deleted file mode 100644
index e198a11d7d..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/Makefile.in
+++ /dev/null
@@ -1,627 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
- case $${target_option-} in \
- ?) ;; \
- *) echo "am__make_running_with_option: internal error: invalid" \
- "target option '$${target_option-}' specified" >&2; \
- exit 1;; \
- esac; \
- has_opt=no; \
- sane_makeflags=$$MAKEFLAGS; \
- if $(am__is_gnu_make); then \
- sane_makeflags=$$MFLAGS; \
- else \
- case $$MAKEFLAGS in \
- *\\[\ \ ]*) \
- bs=\\; \
- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
- esac; \
- fi; \
- skip_next=no; \
- strip_trailopt () \
- { \
- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
- }; \
- for flg in $$sane_makeflags; do \
- test $$skip_next = yes && { skip_next=no; continue; }; \
- case $$flg in \
- *=*|--*) continue;; \
- -*I) strip_trailopt 'I'; skip_next=yes;; \
- -*I?*) strip_trailopt 'I';; \
- -*O) strip_trailopt 'O'; skip_next=yes;; \
- -*O?*) strip_trailopt 'O';; \
- -*l) strip_trailopt 'l'; skip_next=yes;; \
- -*l?*) strip_trailopt 'l';; \
- -[dEDm]) skip_next=yes;; \
- -[JT]) skip_next=yes;; \
- esac; \
- case $$flg in \
- *$$target_option*) has_opt=yes; break;; \
- esac; \
- done; \
- test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/2protobuf
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
- $(top_srcdir)/depcomp
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/ax_cxx_gcc_abi_demangle.m4 \
- $(top_srcdir)/m4/boost.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-LTLIBRARIES = $(noinst_LTLIBRARIES)
-libprotocol_la_DEPENDENCIES =
-am_libprotocol_la_OBJECTS =
-nodist_libprotocol_la_OBJECTS = messages.pb.lo
-libprotocol_la_OBJECTS = $(am_libprotocol_la_OBJECTS) \
- $(nodist_libprotocol_la_OBJECTS)
-AM_V_lt = $(am__v_lt_@AM_V@)
-am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
-am__v_lt_0 = --silent
-am__v_lt_1 =
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo " GEN " $@;
-am__v_GEN_1 =
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 =
-DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CXXFLAGS) $(CXXFLAGS)
-AM_V_CXX = $(am__v_CXX_@AM_V@)
-am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
-am__v_CXX_0 = @echo " CXX " $@;
-am__v_CXX_1 =
-CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
-am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
-am__v_CXXLD_0 = @echo " CXXLD " $@;
-am__v_CXXLD_1 =
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_@AM_V@)
-am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo " CC " $@;
-am__v_CC_1 =
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_@AM_V@)
-am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo " CCLD " $@;
-am__v_CCLD_1 =
-SOURCES = $(libprotocol_la_SOURCES) $(nodist_libprotocol_la_SOURCES)
-DIST_SOURCES = $(libprotocol_la_SOURCES)
-am__can_run_installinfo = \
- case $$AM_UPDATE_INFO_DIR in \
- n|no|NO) false;; \
- *) (install-info --version) >/dev/null 2>&1;; \
- esac
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-# Read a list of newline-separated strings from the standard input,
-# and print each of them once, without duplicates. Input order is
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
- BEGIN { nonempty = 0; } \
- { items[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique. This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
- list='$(am__tagged_files)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BOOST_CHRONO_LDFLAGS = @BOOST_CHRONO_LDFLAGS@
-BOOST_CHRONO_LDPATH = @BOOST_CHRONO_LDPATH@
-BOOST_CHRONO_LIBS = @BOOST_CHRONO_LIBS@
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
-BOOST_FILESYSTEM_LDFLAGS = @BOOST_FILESYSTEM_LDFLAGS@
-BOOST_FILESYSTEM_LDPATH = @BOOST_FILESYSTEM_LDPATH@
-BOOST_FILESYSTEM_LIBS = @BOOST_FILESYSTEM_LIBS@
-BOOST_LDPATH = @BOOST_LDPATH@
-BOOST_ROOT = @BOOST_ROOT@
-BOOST_SYSTEM_LDFLAGS = @BOOST_SYSTEM_LDFLAGS@
-BOOST_SYSTEM_LDPATH = @BOOST_SYSTEM_LDPATH@
-BOOST_SYSTEM_LIBS = @BOOST_SYSTEM_LIBS@
-BOOST_THREAD_LDFLAGS = @BOOST_THREAD_LDFLAGS@
-BOOST_THREAD_LDPATH = @BOOST_THREAD_LDPATH@
-BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
-BOOST_THREAD_WIN32_LDFLAGS = @BOOST_THREAD_WIN32_LDFLAGS@
-BOOST_THREAD_WIN32_LDPATH = @BOOST_THREAD_WIN32_LDPATH@
-BOOST_THREAD_WIN32_LIBS = @BOOST_THREAD_WIN32_LIBS@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JDK_INCLUDE = @JDK_INCLUDE@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-AM_CPPFLAGS = -DHAM_ENABLE_REMOTE -I$(top_builddir)/include
-
-# INCLUDES =
-noinst_LTLIBRARIES = libprotocol.la
-nodist_libprotocol_la_SOURCES = messages.pb.cc
-libprotocol_la_SOURCES = protocol.h
-libprotocol_la_LIBADD = -lprotobuf
-EXTRA_DIST = messages.proto
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .cc .lo .o .obj
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/2protobuf/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/2protobuf/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-clean-noinstLTLIBRARIES:
- -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
- @list='$(noinst_LTLIBRARIES)'; \
- locs=`for p in $$list; do echo $$p; done | \
- sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
- sort -u`; \
- test -z "$$locs" || { \
- echo rm -f $${locs}; \
- rm -f $${locs}; \
- }
-
-libprotocol.la: $(libprotocol_la_OBJECTS) $(libprotocol_la_DEPENDENCIES) $(EXTRA_libprotocol_la_DEPENDENCIES)
- $(AM_V_CXXLD)$(CXXLINK) $(libprotocol_la_OBJECTS) $(libprotocol_la_LIBADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messages.pb.Plo@am__quote@
-
-.cc.o:
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
-@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
-@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
-
-.cc.obj:
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
-@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
-@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.cc.lo:
-@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
-@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
-@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-ID: $(am__tagged_files)
- $(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- set x; \
- here=`pwd`; \
- $(am__define_uniq_tagged_files); \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- $(am__define_uniq_tagged_files); \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
- list='$(am__tagged_files)'; \
- case "$(srcdir)" in \
- [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
- *) sdir=$(subdir)/$(srcdir) ;; \
- esac; \
- for i in $$list; do \
- if test -f "$$i"; then \
- echo "$(subdir)/$$i"; \
- else \
- echo "$$sdir/$$i"; \
- fi; \
- done >> $(top_builddir)/cscope.files
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LTLIBRARIES)
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- if test -z '$(STRIP)'; then \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- install; \
- else \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
- fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
- mostlyclean-am
-
-distclean: distclean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
- ctags-am distclean distclean-compile distclean-generic \
- distclean-libtool distclean-tags distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-man install-pdf install-pdf-am \
- install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags tags-am uninstall uninstall-am
-
-messages.pb.cc proto: $(srcdir)/messages.proto
- protoc $(srcdir)/messages.proto --cpp_out=.
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/messages.proto b/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/messages.proto
deleted file mode 100644
index f8ec8fdcb6..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/messages.proto
+++ /dev/null
@@ -1,457 +0,0 @@
-
-
-package hamsterdb;
-
-option optimize_for = LITE_RUNTIME;
-
-message ProtoWrapper {
- enum Type {
- CONNECT_REQUEST = 10;
- CONNECT_REPLY = 11;
- DISCONNECT_REQUEST = 12;
- DISCONNECT_REPLY = 13;
- ENV_RENAME_REQUEST = 20;
- ENV_RENAME_REPLY = 21;
- ENV_GET_PARAMETERS_REQUEST = 30;
- ENV_GET_PARAMETERS_REPLY = 31;
- ENV_GET_DATABASE_NAMES_REQUEST = 40;
- ENV_GET_DATABASE_NAMES_REPLY = 41;
- ENV_FLUSH_REQUEST = 50;
- ENV_FLUSH_REPLY = 51;
- ENV_CREATE_DB_REQUEST = 60;
- ENV_CREATE_DB_REPLY = 61;
- ENV_OPEN_DB_REQUEST = 70;
- ENV_OPEN_DB_REPLY = 71;
- ENV_ERASE_DB_REQUEST = 80;
- ENV_ERASE_DB_REPLY = 81;
- DB_CLOSE_REQUEST = 90;
- DB_CLOSE_REPLY = 91;
- DB_GET_PARAMETERS_REQUEST = 100;
- DB_GET_PARAMETERS_REPLY = 101;
- // DB_FLUSH_REQUEST = 110;
- // DB_FLUSH_REPLY = 111;
- TXN_BEGIN_REQUEST = 120;
- TXN_BEGIN_REPLY = 121;
- TXN_COMMIT_REQUEST = 130;
- TXN_COMMIT_REPLY = 131;
- TXN_ABORT_REQUEST = 140;
- TXN_ABORT_REPLY = 141;
- DB_CHECK_INTEGRITY_REQUEST = 150;
- DB_CHECK_INTEGRITY_REPLY = 151;
- DB_GET_KEY_COUNT_REQUEST = 160;
- DB_GET_KEY_COUNT_REPLY = 161;
- DB_INSERT_REQUEST = 170;
- DB_INSERT_REPLY = 171;
- DB_ERASE_REQUEST = 180;
- DB_ERASE_REPLY = 181;
- DB_FIND_REQUEST = 190;
- DB_FIND_REPLY = 191;
- CURSOR_CREATE_REQUEST = 200;
- CURSOR_CREATE_REPLY = 201;
- CURSOR_CLONE_REQUEST = 210;
- CURSOR_CLONE_REPLY = 211;
- CURSOR_CLOSE_REQUEST = 220;
- CURSOR_CLOSE_REPLY = 221;
- CURSOR_INSERT_REQUEST = 230;
- CURSOR_INSERT_REPLY = 231;
- CURSOR_ERASE_REQUEST = 240;
- CURSOR_ERASE_REPLY = 241;
- CURSOR_GET_RECORD_COUNT_REQUEST = 260;
- CURSOR_GET_RECORD_COUNT_REPLY = 261;
- CURSOR_GET_DUPLICATE_POSITION_REQUEST = 262;
- CURSOR_GET_DUPLICATE_POSITION_REPLY = 263;
- CURSOR_GET_RECORD_SIZE_REQUEST = 264;
- CURSOR_GET_RECORD_SIZE_REPLY = 265;
- CURSOR_OVERWRITE_REQUEST = 270;
- CURSOR_OVERWRITE_REPLY = 271;
- CURSOR_MOVE_REQUEST = 280;
- CURSOR_MOVE_REPLY = 281;
- }
-
- required Type type = 1;
-
- optional ConnectRequest connect_request = 10;
- optional ConnectReply connect_reply = 11;
- optional DisconnectRequest disconnect_request = 12;
- optional DisconnectReply disconnect_reply = 13;
- optional EnvRenameRequest env_rename_request = 20;
- optional EnvRenameReply env_rename_reply = 21;
- optional EnvGetParametersRequest env_get_parameters_request = 30;
- optional EnvGetParametersReply env_get_parameters_reply = 31;
- optional EnvGetDatabaseNamesRequest env_get_database_names_request = 40;
- optional EnvGetDatabaseNamesReply env_get_database_names_reply = 41;
- optional EnvFlushRequest env_flush_request = 50;
- optional EnvFlushReply env_flush_reply = 51;
- optional EnvCreateDbRequest env_create_db_request = 60;
- optional EnvCreateDbReply env_create_db_reply = 61;
- optional EnvOpenDbRequest env_open_db_request = 70;
- optional EnvOpenDbReply env_open_db_reply = 71;
- optional EnvEraseDbRequest env_erase_db_request = 80;
- optional EnvEraseDbReply env_erase_db_reply = 81;
- optional DbCloseRequest db_close_request = 90;
- optional DbCloseReply db_close_reply = 91;
- optional DbGetParametersRequest db_get_parameters_request = 100;
- optional DbGetParametersReply db_get_parameters_reply = 101;
- optional TxnBeginRequest txn_begin_request = 120;
- optional TxnBeginReply txn_begin_reply = 121;
- optional TxnCommitRequest txn_commit_request = 130;
- optional TxnCommitReply txn_commit_reply = 131;
- optional TxnAbortRequest txn_abort_request = 140;
- optional TxnAbortReply txn_abort_reply = 141;
- optional DbCheckIntegrityRequest db_check_integrity_request = 150;
- optional DbCheckIntegrityReply db_check_integrity_reply = 151;
- optional DbCountRequest db_count_request = 160;
- optional DbCountReply db_count_reply = 161;
- optional DbInsertRequest db_insert_request = 170;
- optional DbInsertReply db_insert_reply = 171;
- optional DbEraseRequest db_erase_request = 180;
- optional DbEraseReply db_erase_reply = 181;
- optional DbFindRequest db_find_request = 190;
- optional DbFindReply db_find_reply = 191;
- optional CursorCreateRequest cursor_create_request = 200;
- optional CursorCreateReply cursor_create_reply = 201;
- optional CursorCloneRequest cursor_clone_request = 210;
- optional CursorCloneReply cursor_clone_reply = 211;
- optional CursorCloseRequest cursor_close_request = 220;
- optional CursorCloseReply cursor_close_reply = 221;
- optional CursorInsertRequest cursor_insert_request = 230;
- optional CursorInsertReply cursor_insert_reply = 231;
- optional CursorEraseRequest cursor_erase_request = 240;
- optional CursorEraseReply cursor_erase_reply = 241;
- optional CursorGetRecordCountRequest cursor_get_record_count_request = 260;
- optional CursorGetRecordCountReply cursor_get_record_count_reply = 261;
- optional CursorGetDuplicatePositionRequest cursor_get_duplicate_position_request = 262;
- optional CursorGetDuplicatePositionReply cursor_get_duplicate_position_reply = 263;
- optional CursorGetRecordSizeRequest cursor_get_record_size_request = 264;
- optional CursorGetRecordSizeReply cursor_get_record_size_reply = 265;
- optional CursorOverwriteRequest cursor_overwrite_request = 270;
- optional CursorOverwriteReply cursor_overwrite_reply = 271;
- optional CursorMoveRequest cursor_move_request = 280;
- optional CursorMoveReply cursor_move_reply = 281;
-}
-
-message ConnectRequest {
- required string path = 1;
-}
-
-message ConnectReply {
- required sint32 status = 1;
- optional uint32 env_flags = 2;
- optional uint64 env_handle = 3;
-}
-
-message DisconnectRequest {
- required uint64 env_handle = 1;
-}
-
-message DisconnectReply {
- required sint32 status = 1;
-}
-
-message EnvGetParametersRequest {
- required uint64 env_handle = 1;
- repeated uint32 names = 2;
-}
-
-message EnvGetParametersReply {
- required sint32 status = 1;
- optional uint32 cache_size = 2;
- optional uint32 page_size = 3;
- optional uint32 max_env_databases = 4;
- optional uint32 flags = 5;
- optional uint32 filemode = 6;
- optional string filename = 7;
-};
-
-message EnvGetDatabaseNamesRequest {
- required uint64 env_handle = 1;
-}
-
-message EnvGetDatabaseNamesReply {
- required sint32 status = 1;
- repeated uint32 names = 2;
-}
-
-message EnvRenameRequest {
- required uint64 env_handle = 1;
- required uint32 oldname = 2;
- required uint32 newname = 3;
- required uint32 flags = 4;
-}
-
-message EnvRenameReply {
- required sint32 status = 1;
-};
-
-message EnvFlushRequest {
- required uint64 env_handle = 1;
- required uint32 flags = 2;
-}
-
-message EnvFlushReply {
- required sint32 status = 1;
-};
-
-message EnvCreateDbRequest {
- required uint64 env_handle = 1;
- required uint32 dbname = 2;
- required uint32 flags = 3;
- repeated uint32 param_names = 4;
- repeated uint64 param_values = 5;
-}
-
-message EnvCreateDbReply {
- required sint32 status = 1;
- optional uint64 db_handle = 2;
- optional uint32 db_flags = 3;
-};
-
-message EnvOpenDbRequest {
- required uint64 env_handle = 1;
- required uint32 dbname = 2;
- required uint32 flags = 3;
- repeated uint32 param_names = 4;
- repeated uint64 param_values = 5;
-}
-
-message EnvOpenDbReply {
- required sint32 status = 1;
- optional uint64 db_handle = 2;
- optional uint32 db_flags = 3;
-};
-
-message EnvEraseDbRequest {
- required uint64 env_handle = 1;
- required uint32 name = 2;
- required uint32 flags = 3;
-}
-
-message EnvEraseDbReply {
- required sint32 status = 1;
-};
-
-message DbCloseRequest {
- required uint64 db_handle = 1;
- required uint32 flags = 2;
-}
-
-message DbCloseReply {
- required sint32 status = 1;
-};
-
-message DbGetParametersRequest {
- required uint64 db_handle = 1;
- repeated uint32 names = 2;
-}
-
-message DbGetParametersReply {
- required sint32 status = 1;
- optional uint32 max_env_databases = 2;
- optional uint32 flags = 3;
- optional uint32 key_size = 4;
- optional uint32 dbname = 5;
- optional uint32 keys_per_page = 6;
- optional uint32 key_type = 7;
- optional uint32 record_size = 8;
-};
-
-message TxnBeginRequest {
- required uint64 env_handle = 1;
- required uint32 flags = 2;
- optional string name = 3;
-}
-
-message TxnBeginReply {
- required sint32 status = 1;
- required uint64 txn_handle = 2;
-};
-
-message TxnCommitRequest {
- required uint64 txn_handle = 1;
- required uint32 flags = 2;
-}
-
-message TxnCommitReply {
- required sint32 status = 1;
-};
-
-message TxnAbortRequest {
- required uint64 txn_handle = 1;
- required uint32 flags = 2;
-}
-
-message TxnAbortReply {
- required sint32 status = 1;
-};
-
-message DbCheckIntegrityRequest {
- required uint64 db_handle = 1;
- required uint32 flags = 2;
-}
-
-message DbCheckIntegrityReply {
- required sint32 status = 1;
-};
-
-message DbCountRequest {
- required uint64 db_handle = 1;
- required uint64 txn_handle = 2;
- required bool distinct = 3;
-};
-
-message DbCountReply {
- required sint32 status = 1;
- required uint64 keycount = 2;
-};
-
-message Key {
- optional bytes data = 1;
- required uint32 flags = 2;
- required uint32 intflags = 3;
-}
-
-message Record {
- optional bytes data = 1;
- required uint32 flags = 2;
- required uint32 partial_offset = 3;
- required uint32 partial_size = 4;
-}
-
-message DbInsertRequest {
- required uint64 db_handle = 1;
- required uint64 txn_handle = 2;
- optional Key key = 3;
- optional Record record = 4;
- required uint32 flags = 5;
-};
-
-message DbInsertReply {
- required sint32 status = 1;
- optional Key key = 2;
-};
-
-message DbEraseRequest {
- required uint64 db_handle = 1;
- required uint64 txn_handle = 2;
- required Key key = 3;
- required uint32 flags = 4;
-};
-
-message DbEraseReply {
- required sint32 status = 1;
-};
-
-message DbFindRequest {
- required uint64 db_handle = 1;
- required uint64 txn_handle = 2;
- required uint64 cursor_handle = 3;
- required Key key = 4;
- optional Record record = 5;
- required uint32 flags = 6;
-};
-
-message DbFindReply {
- required sint32 status = 1;
- required Record record = 2;
- optional Key key = 3;
-};
-
-message CursorCreateRequest {
- required uint64 db_handle = 1;
- required uint64 txn_handle = 2;
- required uint32 flags = 3;
-};
-
-message CursorCreateReply {
- required sint32 status = 1;
- required uint64 cursor_handle = 2;
-};
-
-message CursorCloneRequest {
- required uint64 cursor_handle = 1;
-};
-
-message CursorCloneReply {
- required sint32 status = 1;
- required uint64 cursor_handle = 2;
-};
-
-message CursorCloseRequest {
- required uint64 cursor_handle = 1;
-};
-
-message CursorCloseReply {
- required sint32 status = 1;
-};
-
-message CursorInsertRequest {
- required uint64 cursor_handle = 1;
- optional Key key = 2;
- optional Record record = 3;
- required uint32 flags = 4;
-};
-
-message CursorInsertReply {
- required sint32 status = 1;
- optional Key key = 2;
-};
-
-message CursorEraseRequest {
- required uint64 cursor_handle = 1;
- required uint32 flags = 2;
-};
-
-message CursorEraseReply {
- required sint32 status = 1;
-};
-
-message CursorGetRecordCountRequest {
- required uint64 cursor_handle = 1;
- required uint32 flags = 2;
-};
-
-message CursorGetRecordCountReply {
- required sint32 status = 1;
- required uint32 count = 2;
-};
-
-message CursorGetRecordSizeRequest {
- required uint64 cursor_handle = 1;
-};
-
-message CursorGetRecordSizeReply {
- required sint32 status = 1;
- required uint64 size = 2;
-};
-
-message CursorGetDuplicatePositionRequest {
- required uint64 cursor_handle = 1;
-};
-
-message CursorGetDuplicatePositionReply {
- required sint32 status = 1;
- required uint32 position = 2;
-};
-
-message CursorOverwriteRequest {
- required uint64 cursor_handle = 1;
- required Record record = 2;
- required uint32 flags = 3;
-};
-
-message CursorOverwriteReply {
- required sint32 status = 1;
-};
-
-message CursorMoveRequest {
- required uint64 cursor_handle = 1;
- optional Key key = 2;
- optional Record record = 3;
- required uint32 flags = 4;
-};
-
-message CursorMoveReply {
- required sint32 status = 1;
- optional Key key = 2;
- optional Record record = 3;
-};
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/protocol.h b/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/protocol.h
deleted file mode 100644
index 8a2ab9d49f..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2protobuf/protocol.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Abstraction layer for the remote protocol
- *
- * @exception_safe: no
- * @thread_safe: no
- */
-
-#ifndef HAM_PROTOCOL_H
-#define HAM_PROTOCOL_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1mem/mem.h"
-#include "1base/error.h"
-#include "1base/dynamic_array.h"
-#include "2protobuf/messages.pb.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-/** a magic and version indicator for the remote protocol */
-#define HAM_TRANSFER_MAGIC_V1 (('h'<<24)|('a'<<16)|('m'<<8)|'1')
-
-/**
- * the Protocol class maps a single message that is exchanged between
- * client and server
- */
-class Protocol : public hamsterdb::ProtoWrapper
-{
- public:
- Protocol() { }
-
- /** constructor - assigns a type */
- Protocol(hamsterdb::ProtoWrapper_Type type) {
- set_type(type);
- }
-
- /** helper function which copies a ham_key_t into a ProtoBuf key */
- static void assign_key(hamsterdb::Key *protokey, ham_key_t *hamkey,
- bool deep_copy = true) {
- if (deep_copy)
- protokey->set_data(hamkey->data, hamkey->size);
- protokey->set_flags(hamkey->flags);
- protokey->set_intflags(hamkey->_flags);
- }
-
- /** helper function which copies a ham_record_t into a ProtoBuf record */
- static void assign_record(hamsterdb::Record *protorec,
- ham_record_t *hamrec, bool deep_copy = true) {
- if (deep_copy)
- protorec->set_data(hamrec->data, hamrec->size);
- protorec->set_flags(hamrec->flags);
- protorec->set_partial_offset(hamrec->partial_offset);
- protorec->set_partial_size(hamrec->partial_size);
- }
-
- /**
- * Factory function; creates a new Protocol structure from a serialized
- * buffer
- */
- static Protocol *unpack(const uint8_t *buf, uint32_t size) {
- if (*(uint32_t *)&buf[0] != HAM_TRANSFER_MAGIC_V1) {
- ham_trace(("invalid protocol version"));
- return (0);
- }
-
- Protocol *p = new Protocol;
- if (!p->ParseFromArray(buf + 8, size - 8)) {
- delete p;
- return (0);
- }
- return (p);
- }
-
- /*
- * Packs the Protocol structure into a memory buffer and returns
- * a pointer to the buffer and the buffer size
- */
- bool pack(uint8_t **data, uint32_t *size) {
- uint32_t packed_size = ByteSize();
- /* we need 8 more bytes for magic and size */
- uint8_t *p = Memory::allocate<uint8_t>(packed_size + 8);
- if (!p)
- return (false);
-
- /* write the magic and the payload size of the packed structure */
- *(uint32_t *)&p[0] = HAM_TRANSFER_MAGIC_V1;
- *(uint32_t *)&p[4] = packed_size;
-
- /* now write the packed structure */
- if (!SerializeToArray(&p[8], packed_size)) {
- Memory::release(p);
- return (false);
- }
-
- *data = p;
- *size = packed_size + 8;
- return (true);
- }
-
- /*
- * Packs the Protocol structure into a ByteArray
- */
- bool pack(ByteArray *barray) {
- uint32_t packed_size = ByteSize();
- /* we need 8 more bytes for magic and size */
- uint8_t *p = (uint8_t *)barray->resize(packed_size + 8);
- if (!p)
- return (false);
-
- /* write the magic and the payload size of the packed structure */
- *(uint32_t *)&p[0] = HAM_TRANSFER_MAGIC_V1;
- *(uint32_t *)&p[4] = packed_size;
-
- /* now write the packed structure */
- return (SerializeToArray(&p[8], packed_size));
- }
-
- /**
- * shutdown/free globally allocated memory
- */
- static void shutdown() {
- google::protobuf::ShutdownProtobufLibrary();
- }
-};
-
-#endif /* HAM_PROTOCOL_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/Makefile.am b/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/Makefile.am
deleted file mode 100644
index cf5a3fb3ec..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-
-EXTRA_DIST = messages.h messages.proto
-
-gen proto:
- cat messages.proto | ../../bin/genserializer.pl > messages.h
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/Makefile.in b/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/Makefile.in
deleted file mode 100644
index da966a01d3..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/Makefile.in
+++ /dev/null
@@ -1,451 +0,0 @@
-# Makefile.in generated by automake 1.14.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2013 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-VPATH = @srcdir@
-am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
-am__make_running_with_option = \
- case $${target_option-} in \
- ?) ;; \
- *) echo "am__make_running_with_option: internal error: invalid" \
- "target option '$${target_option-}' specified" >&2; \
- exit 1;; \
- esac; \
- has_opt=no; \
- sane_makeflags=$$MAKEFLAGS; \
- if $(am__is_gnu_make); then \
- sane_makeflags=$$MFLAGS; \
- else \
- case $$MAKEFLAGS in \
- *\\[\ \ ]*) \
- bs=\\; \
- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
- esac; \
- fi; \
- skip_next=no; \
- strip_trailopt () \
- { \
- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
- }; \
- for flg in $$sane_makeflags; do \
- test $$skip_next = yes && { skip_next=no; continue; }; \
- case $$flg in \
- *=*|--*) continue;; \
- -*I) strip_trailopt 'I'; skip_next=yes;; \
- -*I?*) strip_trailopt 'I';; \
- -*O) strip_trailopt 'O'; skip_next=yes;; \
- -*O?*) strip_trailopt 'O';; \
- -*l) strip_trailopt 'l'; skip_next=yes;; \
- -*l?*) strip_trailopt 'l';; \
- -[dEDm]) skip_next=yes;; \
- -[JT]) skip_next=yes;; \
- esac; \
- case $$flg in \
- *$$target_option*) has_opt=yes; break;; \
- esac; \
- done; \
- test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/2protoserde
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
- $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
- $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
- $(top_srcdir)/m4/ax_cxx_gcc_abi_demangle.m4 \
- $(top_srcdir)/m4/boost.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo " GEN " $@;
-am__v_GEN_1 =
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 =
-SOURCES =
-DIST_SOURCES =
-am__can_run_installinfo = \
- case $$AM_UPDATE_INFO_DIR in \
- n|no|NO) false;; \
- *) (install-info --version) >/dev/null 2>&1;; \
- esac
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BOOST_CHRONO_LDFLAGS = @BOOST_CHRONO_LDFLAGS@
-BOOST_CHRONO_LDPATH = @BOOST_CHRONO_LDPATH@
-BOOST_CHRONO_LIBS = @BOOST_CHRONO_LIBS@
-BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
-BOOST_FILESYSTEM_LDFLAGS = @BOOST_FILESYSTEM_LDFLAGS@
-BOOST_FILESYSTEM_LDPATH = @BOOST_FILESYSTEM_LDPATH@
-BOOST_FILESYSTEM_LIBS = @BOOST_FILESYSTEM_LIBS@
-BOOST_LDPATH = @BOOST_LDPATH@
-BOOST_ROOT = @BOOST_ROOT@
-BOOST_SYSTEM_LDFLAGS = @BOOST_SYSTEM_LDFLAGS@
-BOOST_SYSTEM_LDPATH = @BOOST_SYSTEM_LDPATH@
-BOOST_SYSTEM_LIBS = @BOOST_SYSTEM_LIBS@
-BOOST_THREAD_LDFLAGS = @BOOST_THREAD_LDFLAGS@
-BOOST_THREAD_LDPATH = @BOOST_THREAD_LDPATH@
-BOOST_THREAD_LIBS = @BOOST_THREAD_LIBS@
-BOOST_THREAD_WIN32_LDFLAGS = @BOOST_THREAD_WIN32_LDFLAGS@
-BOOST_THREAD_WIN32_LDPATH = @BOOST_THREAD_WIN32_LDPATH@
-BOOST_THREAD_WIN32_LIBS = @BOOST_THREAD_WIN32_LIBS@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-JDK_INCLUDE = @JDK_INCLUDE@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIPO = @LIPO@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-NM = @NM@
-NMEDIT = @NMEDIT@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-EXTRA_DIST = messages.h messages.proto
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/2protoserde/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/2protoserde/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-tags TAGS:
-
-ctags CTAGS:
-
-cscope cscopelist:
-
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- if test -z '$(STRIP)'; then \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- install; \
- else \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
- fi
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic clean-libtool \
- cscopelist-am ctags-am distclean distclean-generic \
- distclean-libtool distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am install-man \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags-am uninstall uninstall-am
-
-
-gen proto:
- cat messages.proto | ../../bin/genserializer.pl > messages.h
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/messages.h b/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/messages.h
deleted file mode 100644
index 38d091dd8f..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/messages.h
+++ /dev/null
@@ -1,1839 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_MESSAGES_H
-#define HAM_MESSAGES_H
-
-#include "0root/root.h"
-
-#include <assert.h>
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-/** a magic and version indicator for the remote protocol */
-#define HAM_TRANSFER_MAGIC_V2 (('h'<<24)|('a'<<16)|('m'<<8)|'2')
-
-namespace hamsterdb {
-
-enum {
- kTxnBeginRequest,
- kTxnBeginReply,
- kTxnCommitRequest,
- kTxnCommitReply,
- kTxnAbortRequest,
- kTxnAbortReply,
- kDbGetKeyCountRequest,
- kDbGetKeyCountReply,
- kDbInsertRequest,
- kDbInsertReply,
- kDbEraseRequest,
- kDbEraseReply,
- kDbFindRequest,
- kDbFindReply,
- kCursorCreateRequest,
- kCursorCreateReply,
- kCursorCloneRequest,
- kCursorCloneReply,
- kCursorCloseRequest,
- kCursorCloseReply,
- kCursorInsertRequest,
- kCursorInsertReply,
- kCursorEraseRequest,
- kCursorEraseReply,
- kCursorGetRecordCountRequest,
- kCursorGetRecordCountReply,
- kCursorGetRecordSizeRequest,
- kCursorGetRecordSizeReply,
- kCursorGetDuplicatePositionRequest,
- kCursorGetDuplicatePositionReply,
- kCursorOverwriteRequest,
- kCursorOverwriteReply,
- kCursorMoveRequest,
- kCursorMoveReply
-};
-
-template<typename Ex, typename In>
-struct Serialized_Base {
- Ex value;
-
- Serialized_Base() {
- clear();
- }
-
- Serialized_Base(const Ex &t)
- : value((In)t) {
- }
-
- operator Ex() {
- return (value);
- }
-
- void clear() {
- value = (Ex)0;
- }
-
- size_t get_size() const {
- return (sizeof(In));
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- *(In *)*pptr = (In)value;
- *pptr += sizeof(In);
- *psize -= sizeof(In);
- assert(*psize >= 0);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- value = (Ex) *(In *)*pptr;
- *pptr += sizeof(In);
- *psize -= sizeof(In);
- assert(*psize >= 0);
- }
-};
-
-struct SerializedBytes {
- uint8_t *value;
- uint32_t size;
-
- SerializedBytes() {
- clear();
- }
-
- size_t align(size_t s) const {
- if (s % 4) return (s + 4 - (s % 4));
- return (s);
- }
-
- void clear() {
- value = 0; size = 0;
- }
-
- size_t get_size() const {
- return (sizeof(uint32_t) + align(size)); // align to 32bits
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- *(uint32_t *)*pptr = size;
- *pptr += sizeof(uint32_t);
- *psize -= sizeof(uint32_t);
- if (size) {
- memcpy(*pptr, value, size);
- *pptr += align(size); // align to 32bits
- *psize -= align(size);
- assert(*psize >= 0);
- }
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- size = *(uint32_t *)*pptr;
- *pptr += sizeof(uint32_t);
- *psize -= sizeof(uint32_t);
- if (size) {
- value = *pptr;
- *pptr += align(size); // align to 32bits
- *psize -= align(size);
- assert(*psize >= 0);
- }
- else
- value = 0;
- }
-};
-
-typedef Serialized_Base<bool, uint32_t> SerializedBool;
-typedef Serialized_Base<uint8_t, uint32_t> SerializedUint8;
-typedef Serialized_Base<uint16_t, uint32_t> SerializedUint16;
-typedef Serialized_Base<uint32_t, uint32_t> SerializedUint32;
-typedef Serialized_Base<int8_t, int32_t> SerializedSint8;
-typedef Serialized_Base<int16_t, int32_t> SerializedSint16;
-typedef Serialized_Base<int32_t, int32_t> SerializedSint32;
-typedef Serialized_Base<uint64_t, uint64_t> SerializedUint64;
-typedef Serialized_Base<int64_t, int64_t> SerializedSint64;
-
-
-struct SerializedKey {
- SerializedBool has_data;
- SerializedBytes data;
- SerializedUint32 flags;
- SerializedUint32 intflags;
-
- SerializedKey() {
- clear();
- }
-
- size_t get_size() const {
- return (
- has_data.get_size() +
- (has_data.value ? data.get_size() : 0) +
- flags.get_size() +
- intflags.get_size() +
- 0);
- }
-
- void clear() {
- has_data = false;
- data.clear();
- flags.clear();
- intflags.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- has_data.serialize(pptr, psize);
- if (has_data.value) data.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- intflags.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- has_data.deserialize(pptr, psize);
- if (has_data.value) data.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- intflags.deserialize(pptr, psize);
- }
-};
-
-struct SerializedRecord {
- SerializedBool has_data;
- SerializedBytes data;
- SerializedUint32 flags;
- SerializedUint32 partial_offset;
- SerializedUint32 partial_size;
-
- SerializedRecord() {
- clear();
- }
-
- size_t get_size() const {
- return (
- has_data.get_size() +
- (has_data.value ? data.get_size() : 0) +
- flags.get_size() +
- partial_offset.get_size() +
- partial_size.get_size() +
- 0);
- }
-
- void clear() {
- has_data = false;
- data.clear();
- flags.clear();
- partial_offset.clear();
- partial_size.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- has_data.serialize(pptr, psize);
- if (has_data.value) data.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- partial_offset.serialize(pptr, psize);
- partial_size.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- has_data.deserialize(pptr, psize);
- if (has_data.value) data.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- partial_offset.deserialize(pptr, psize);
- partial_size.deserialize(pptr, psize);
- }
-};
-
-struct SerializedConnectRequest {
- SerializedBytes path;
-
- SerializedConnectRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- path.get_size() +
- 0);
- }
-
- void clear() {
- path.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- path.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- path.deserialize(pptr, psize);
- }
-};
-
-struct SerializedConnectReply {
- SerializedSint32 status;
- SerializedUint32 env_flags;
- SerializedUint64 env_handle;
-
- SerializedConnectReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- env_flags.get_size() +
- env_handle.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- env_flags.clear();
- env_handle.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- env_flags.serialize(pptr, psize);
- env_handle.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- env_flags.deserialize(pptr, psize);
- env_handle.deserialize(pptr, psize);
- }
-};
-
-struct SerializedTxnBeginRequest {
- SerializedUint64 env_handle;
- SerializedUint32 flags;
- SerializedBytes name;
-
- SerializedTxnBeginRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- env_handle.get_size() +
- flags.get_size() +
- name.get_size() +
- 0);
- }
-
- void clear() {
- env_handle.clear();
- flags.clear();
- name.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- env_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- name.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- env_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- name.deserialize(pptr, psize);
- }
-};
-
-struct SerializedTxnBeginReply {
- SerializedSint32 status;
- SerializedUint64 txn_handle;
-
- SerializedTxnBeginReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- txn_handle.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- txn_handle.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- txn_handle.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- txn_handle.deserialize(pptr, psize);
- }
-};
-
-struct SerializedTxnCommitRequest {
- SerializedUint64 txn_handle;
- SerializedUint32 flags;
-
- SerializedTxnCommitRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- txn_handle.get_size() +
- flags.get_size() +
- 0);
- }
-
- void clear() {
- txn_handle.clear();
- flags.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- txn_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- txn_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- }
-};
-
-struct SerializedTxnCommitReply {
- SerializedSint32 status;
-
- SerializedTxnCommitReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- }
-};
-
-struct SerializedTxnAbortRequest {
- SerializedUint64 txn_handle;
- SerializedUint32 flags;
-
- SerializedTxnAbortRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- txn_handle.get_size() +
- flags.get_size() +
- 0);
- }
-
- void clear() {
- txn_handle.clear();
- flags.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- txn_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- txn_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- }
-};
-
-struct SerializedTxnAbortReply {
- SerializedSint32 status;
-
- SerializedTxnAbortReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- }
-};
-
-struct SerializedDbGetKeyCountRequest {
- SerializedUint64 db_handle;
- SerializedUint64 txn_handle;
- SerializedBool distinct;
-
- SerializedDbGetKeyCountRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- db_handle.get_size() +
- txn_handle.get_size() +
- distinct.get_size() +
- 0);
- }
-
- void clear() {
- db_handle.clear();
- txn_handle.clear();
- distinct.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- db_handle.serialize(pptr, psize);
- txn_handle.serialize(pptr, psize);
- distinct.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- db_handle.deserialize(pptr, psize);
- txn_handle.deserialize(pptr, psize);
- distinct.deserialize(pptr, psize);
- }
-};
-
-struct SerializedDbGetKeyCountReply {
- SerializedSint32 status;
- SerializedUint64 keycount;
-
- SerializedDbGetKeyCountReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- keycount.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- keycount.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- keycount.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- keycount.deserialize(pptr, psize);
- }
-};
-
-struct SerializedDbInsertRequest {
- SerializedUint64 db_handle;
- SerializedUint64 txn_handle;
- SerializedUint32 flags;
- SerializedBool has_key;
- SerializedKey key;
- SerializedBool has_record;
- SerializedRecord record;
-
- SerializedDbInsertRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- db_handle.get_size() +
- txn_handle.get_size() +
- flags.get_size() +
- has_key.get_size() +
- (has_key.value ? key.get_size() : 0) +
- has_record.get_size() +
- (has_record.value ? record.get_size() : 0) +
- 0);
- }
-
- void clear() {
- db_handle.clear();
- txn_handle.clear();
- flags.clear();
- has_key = false;
- key.clear();
- has_record = false;
- record.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- db_handle.serialize(pptr, psize);
- txn_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- has_key.serialize(pptr, psize);
- if (has_key.value) key.serialize(pptr, psize);
- has_record.serialize(pptr, psize);
- if (has_record.value) record.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- db_handle.deserialize(pptr, psize);
- txn_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- has_key.deserialize(pptr, psize);
- if (has_key.value) key.deserialize(pptr, psize);
- has_record.deserialize(pptr, psize);
- if (has_record.value) record.deserialize(pptr, psize);
- }
-};
-
-struct SerializedDbInsertReply {
- SerializedSint32 status;
- SerializedBool has_key;
- SerializedKey key;
-
- SerializedDbInsertReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- has_key.get_size() +
- (has_key.value ? key.get_size() : 0) +
- 0);
- }
-
- void clear() {
- status.clear();
- has_key = false;
- key.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- has_key.serialize(pptr, psize);
- if (has_key.value) key.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- has_key.deserialize(pptr, psize);
- if (has_key.value) key.deserialize(pptr, psize);
- }
-};
-
-struct SerializedDbEraseRequest {
- SerializedUint64 db_handle;
- SerializedUint64 txn_handle;
- SerializedKey key;
- SerializedUint32 flags;
-
- SerializedDbEraseRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- db_handle.get_size() +
- txn_handle.get_size() +
- key.get_size() +
- flags.get_size() +
- 0);
- }
-
- void clear() {
- db_handle.clear();
- txn_handle.clear();
- key.clear();
- flags.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- db_handle.serialize(pptr, psize);
- txn_handle.serialize(pptr, psize);
- key.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- db_handle.deserialize(pptr, psize);
- txn_handle.deserialize(pptr, psize);
- key.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- }
-};
-
-struct SerializedDbEraseReply {
- SerializedSint32 status;
-
- SerializedDbEraseReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- }
-};
-
-struct SerializedDbFindRequest {
- SerializedUint64 db_handle;
- SerializedUint64 txn_handle;
- SerializedUint64 cursor_handle;
- SerializedUint32 flags;
- SerializedKey key;
- SerializedBool has_record;
- SerializedRecord record;
-
- SerializedDbFindRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- db_handle.get_size() +
- txn_handle.get_size() +
- cursor_handle.get_size() +
- flags.get_size() +
- key.get_size() +
- has_record.get_size() +
- (has_record.value ? record.get_size() : 0) +
- 0);
- }
-
- void clear() {
- db_handle.clear();
- txn_handle.clear();
- cursor_handle.clear();
- flags.clear();
- key.clear();
- has_record = false;
- record.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- db_handle.serialize(pptr, psize);
- txn_handle.serialize(pptr, psize);
- cursor_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- key.serialize(pptr, psize);
- has_record.serialize(pptr, psize);
- if (has_record.value) record.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- db_handle.deserialize(pptr, psize);
- txn_handle.deserialize(pptr, psize);
- cursor_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- key.deserialize(pptr, psize);
- has_record.deserialize(pptr, psize);
- if (has_record.value) record.deserialize(pptr, psize);
- }
-};
-
-struct SerializedDbFindReply {
- SerializedSint32 status;
- SerializedBool has_key;
- SerializedKey key;
- SerializedBool has_record;
- SerializedRecord record;
-
- SerializedDbFindReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- has_key.get_size() +
- (has_key.value ? key.get_size() : 0) +
- has_record.get_size() +
- (has_record.value ? record.get_size() : 0) +
- 0);
- }
-
- void clear() {
- status.clear();
- has_key = false;
- key.clear();
- has_record = false;
- record.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- has_key.serialize(pptr, psize);
- if (has_key.value) key.serialize(pptr, psize);
- has_record.serialize(pptr, psize);
- if (has_record.value) record.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- has_key.deserialize(pptr, psize);
- if (has_key.value) key.deserialize(pptr, psize);
- has_record.deserialize(pptr, psize);
- if (has_record.value) record.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorCreateRequest {
- SerializedUint64 db_handle;
- SerializedUint64 txn_handle;
- SerializedUint32 flags;
-
- SerializedCursorCreateRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- db_handle.get_size() +
- txn_handle.get_size() +
- flags.get_size() +
- 0);
- }
-
- void clear() {
- db_handle.clear();
- txn_handle.clear();
- flags.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- db_handle.serialize(pptr, psize);
- txn_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- db_handle.deserialize(pptr, psize);
- txn_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorCreateReply {
- SerializedSint32 status;
- SerializedUint64 cursor_handle;
-
- SerializedCursorCreateReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- cursor_handle.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- cursor_handle.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- cursor_handle.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- cursor_handle.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorCloneRequest {
- SerializedUint64 cursor_handle;
-
- SerializedCursorCloneRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorCloneReply {
- SerializedSint32 status;
- SerializedUint64 cursor_handle;
-
- SerializedCursorCloneReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- cursor_handle.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- cursor_handle.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- cursor_handle.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- cursor_handle.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorCloseRequest {
- SerializedUint64 cursor_handle;
-
- SerializedCursorCloseRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorCloseReply {
- SerializedSint32 status;
-
- SerializedCursorCloseReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorInsertRequest {
- SerializedUint64 cursor_handle;
- SerializedUint32 flags;
- SerializedBool has_key;
- SerializedKey key;
- SerializedBool has_record;
- SerializedRecord record;
-
- SerializedCursorInsertRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- flags.get_size() +
- has_key.get_size() +
- (has_key.value ? key.get_size() : 0) +
- has_record.get_size() +
- (has_record.value ? record.get_size() : 0) +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- flags.clear();
- has_key = false;
- key.clear();
- has_record = false;
- record.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- has_key.serialize(pptr, psize);
- if (has_key.value) key.serialize(pptr, psize);
- has_record.serialize(pptr, psize);
- if (has_record.value) record.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- has_key.deserialize(pptr, psize);
- if (has_key.value) key.deserialize(pptr, psize);
- has_record.deserialize(pptr, psize);
- if (has_record.value) record.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorInsertReply {
- SerializedSint32 status;
- SerializedBool has_key;
- SerializedKey key;
-
- SerializedCursorInsertReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- has_key.get_size() +
- (has_key.value ? key.get_size() : 0) +
- 0);
- }
-
- void clear() {
- status.clear();
- has_key = false;
- key.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- has_key.serialize(pptr, psize);
- if (has_key.value) key.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- has_key.deserialize(pptr, psize);
- if (has_key.value) key.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorEraseRequest {
- SerializedUint64 cursor_handle;
- SerializedUint32 flags;
-
- SerializedCursorEraseRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- flags.get_size() +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- flags.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorEraseReply {
- SerializedSint32 status;
-
- SerializedCursorEraseReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorGetRecordCountRequest {
- SerializedUint64 cursor_handle;
- SerializedUint32 flags;
-
- SerializedCursorGetRecordCountRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- flags.get_size() +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- flags.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorGetRecordCountReply {
- SerializedSint32 status;
- SerializedUint32 count;
-
- SerializedCursorGetRecordCountReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- count.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- count.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- count.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- count.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorGetRecordSizeRequest {
- SerializedUint64 cursor_handle;
-
- SerializedCursorGetRecordSizeRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorGetRecordSizeReply {
- SerializedSint32 status;
- SerializedUint64 size;
-
- SerializedCursorGetRecordSizeReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- size.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- size.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- size.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- size.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorGetDuplicatePositionRequest {
- SerializedUint64 cursor_handle;
-
- SerializedCursorGetDuplicatePositionRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorGetDuplicatePositionReply {
- SerializedSint32 status;
- SerializedUint32 position;
-
- SerializedCursorGetDuplicatePositionReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- position.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- position.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- position.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- position.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorOverwriteRequest {
- SerializedUint64 cursor_handle;
- SerializedRecord record;
- SerializedUint32 flags;
-
- SerializedCursorOverwriteRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- record.get_size() +
- flags.get_size() +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- record.clear();
- flags.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- record.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- record.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorOverwriteReply {
- SerializedSint32 status;
-
- SerializedCursorOverwriteReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorMoveRequest {
- SerializedUint64 cursor_handle;
- SerializedUint32 flags;
- SerializedBool has_key;
- SerializedKey key;
- SerializedBool has_record;
- SerializedRecord record;
-
- SerializedCursorMoveRequest() {
- clear();
- }
-
- size_t get_size() const {
- return (
- cursor_handle.get_size() +
- flags.get_size() +
- has_key.get_size() +
- (has_key.value ? key.get_size() : 0) +
- has_record.get_size() +
- (has_record.value ? record.get_size() : 0) +
- 0);
- }
-
- void clear() {
- cursor_handle.clear();
- flags.clear();
- has_key = false;
- key.clear();
- has_record = false;
- record.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- cursor_handle.serialize(pptr, psize);
- flags.serialize(pptr, psize);
- has_key.serialize(pptr, psize);
- if (has_key.value) key.serialize(pptr, psize);
- has_record.serialize(pptr, psize);
- if (has_record.value) record.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- cursor_handle.deserialize(pptr, psize);
- flags.deserialize(pptr, psize);
- has_key.deserialize(pptr, psize);
- if (has_key.value) key.deserialize(pptr, psize);
- has_record.deserialize(pptr, psize);
- if (has_record.value) record.deserialize(pptr, psize);
- }
-};
-
-struct SerializedCursorMoveReply {
- SerializedSint32 status;
- SerializedKey key;
- SerializedRecord record;
-
- SerializedCursorMoveReply() {
- clear();
- }
-
- size_t get_size() const {
- return (
- status.get_size() +
- key.get_size() +
- record.get_size() +
- 0);
- }
-
- void clear() {
- status.clear();
- key.clear();
- record.clear();
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- status.serialize(pptr, psize);
- key.serialize(pptr, psize);
- record.serialize(pptr, psize);
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- status.deserialize(pptr, psize);
- key.deserialize(pptr, psize);
- record.deserialize(pptr, psize);
- }
-};
-
-struct SerializedWrapper {
- SerializedUint32 magic;
- SerializedUint32 size;
- SerializedUint32 id;
- SerializedTxnBeginRequest txn_begin_request;
- SerializedTxnBeginReply txn_begin_reply;
- SerializedTxnCommitRequest txn_commit_request;
- SerializedTxnCommitReply txn_commit_reply;
- SerializedTxnAbortRequest txn_abort_request;
- SerializedTxnAbortReply txn_abort_reply;
- SerializedDbGetKeyCountRequest db_count_request;
- SerializedDbGetKeyCountReply db_count_reply;
- SerializedDbInsertRequest db_insert_request;
- SerializedDbInsertReply db_insert_reply;
- SerializedDbEraseRequest db_erase_request;
- SerializedDbEraseReply db_erase_reply;
- SerializedDbFindRequest db_find_request;
- SerializedDbFindReply db_find_reply;
- SerializedCursorCreateRequest cursor_create_request;
- SerializedCursorCreateReply cursor_create_reply;
- SerializedCursorCloneRequest cursor_clone_request;
- SerializedCursorCloneReply cursor_clone_reply;
- SerializedCursorCloseRequest cursor_close_request;
- SerializedCursorCloseReply cursor_close_reply;
- SerializedCursorInsertRequest cursor_insert_request;
- SerializedCursorInsertReply cursor_insert_reply;
- SerializedCursorEraseRequest cursor_erase_request;
- SerializedCursorEraseReply cursor_erase_reply;
- SerializedCursorGetRecordCountRequest cursor_get_record_count_request;
- SerializedCursorGetRecordCountReply cursor_get_record_count_reply;
- SerializedCursorGetRecordSizeRequest cursor_get_record_size_request;
- SerializedCursorGetRecordSizeReply cursor_get_record_size_reply;
- SerializedCursorGetDuplicatePositionRequest cursor_get_duplicate_position_request;
- SerializedCursorGetDuplicatePositionReply cursor_get_duplicate_position_reply;
- SerializedCursorOverwriteRequest cursor_overwrite_request;
- SerializedCursorOverwriteReply cursor_overwrite_reply;
- SerializedCursorMoveRequest cursor_move_request;
- SerializedCursorMoveReply cursor_move_reply;
-
- SerializedWrapper() {
- clear();
- }
-
- // the methods in here have a custom implementation, otherwise we would
- // generate many bools for the "optional" fields, and they would
- // unnecessarily increase the structure size
- void clear() {
- magic = 0;
- size = 0;
- id = 0;
- }
-
- size_t get_size() const {
- size_t s = magic.get_size() + size.get_size() + id.get_size();
- switch (id.value) {
- case kTxnBeginRequest:
- return (s + txn_begin_request.get_size());
- case kTxnBeginReply:
- return (s + txn_begin_reply.get_size());
- case kTxnCommitRequest:
- return (s + txn_commit_request.get_size());
- case kTxnCommitReply:
- return (s + txn_commit_reply.get_size());
- case kTxnAbortRequest:
- return (s + txn_abort_request.get_size());
- case kTxnAbortReply:
- return (s + txn_abort_reply.get_size());
- case kDbGetKeyCountRequest:
- return (s + db_count_request.get_size());
- case kDbGetKeyCountReply:
- return (s + db_count_reply.get_size());
- case kDbInsertRequest:
- return (s + db_insert_request.get_size());
- case kDbInsertReply:
- return (s + db_insert_reply.get_size());
- case kDbEraseRequest:
- return (s + db_erase_request.get_size());
- case kDbEraseReply:
- return (s + db_erase_reply.get_size());
- case kDbFindRequest:
- return (s + db_find_request.get_size());
- case kDbFindReply:
- return (s + db_find_reply.get_size());
- case kCursorCreateRequest:
- return (s + cursor_create_request.get_size());
- case kCursorCreateReply:
- return (s + cursor_create_reply.get_size());
- case kCursorCloneRequest:
- return (s + cursor_clone_request.get_size());
- case kCursorCloneReply:
- return (s + cursor_clone_reply.get_size());
- case kCursorCloseRequest:
- return (s + cursor_close_request.get_size());
- case kCursorCloseReply:
- return (s + cursor_close_reply.get_size());
- case kCursorInsertRequest:
- return (s + cursor_insert_request.get_size());
- case kCursorInsertReply:
- return (s + cursor_insert_reply.get_size());
- case kCursorEraseRequest:
- return (s + cursor_erase_request.get_size());
- case kCursorEraseReply:
- return (s + cursor_erase_reply.get_size());
- case kCursorGetRecordCountRequest:
- return (s + cursor_get_record_count_request.get_size());
- case kCursorGetRecordCountReply:
- return (s + cursor_get_record_count_reply.get_size());
- case kCursorGetRecordSizeRequest:
- return (s + cursor_get_record_size_request.get_size());
- case kCursorGetRecordSizeReply:
- return (s + cursor_get_record_size_reply.get_size());
- case kCursorGetDuplicatePositionRequest:
- return (s + cursor_get_duplicate_position_request.get_size());
- case kCursorGetDuplicatePositionReply:
- return (s + cursor_get_duplicate_position_reply.get_size());
- case kCursorOverwriteRequest:
- return (s + cursor_overwrite_request.get_size());
- case kCursorOverwriteReply:
- return (s + cursor_overwrite_reply.get_size());
- case kCursorMoveRequest:
- return (s + cursor_move_request.get_size());
- case kCursorMoveReply:
- return (s + cursor_move_reply.get_size());
- default:
- assert(!"shouldn't be here");
- return (0);
- }
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- magic.serialize(pptr, psize);
- size.serialize(pptr, psize);
- id.serialize(pptr, psize);
-
- switch (id.value) {
- case kTxnBeginRequest:
- txn_begin_request.serialize(pptr, psize);
- break;
- case kTxnBeginReply:
- txn_begin_reply.serialize(pptr, psize);
- break;
- case kTxnCommitRequest:
- txn_commit_request.serialize(pptr, psize);
- break;
- case kTxnCommitReply:
- txn_commit_reply.serialize(pptr, psize);
- break;
- case kTxnAbortRequest:
- txn_abort_request.serialize(pptr, psize);
- break;
- case kTxnAbortReply:
- txn_abort_reply.serialize(pptr, psize);
- break;
- case kDbGetKeyCountRequest:
- db_count_request.serialize(pptr, psize);
- break;
- case kDbGetKeyCountReply:
- db_count_reply.serialize(pptr, psize);
- break;
- case kDbInsertRequest:
- db_insert_request.serialize(pptr, psize);
- break;
- case kDbInsertReply:
- db_insert_reply.serialize(pptr, psize);
- break;
- case kDbEraseRequest:
- db_erase_request.serialize(pptr, psize);
- break;
- case kDbEraseReply:
- db_erase_reply.serialize(pptr, psize);
- break;
- case kDbFindRequest:
- db_find_request.serialize(pptr, psize);
- break;
- case kDbFindReply:
- db_find_reply.serialize(pptr, psize);
- break;
- case kCursorCreateRequest:
- cursor_create_request.serialize(pptr, psize);
- break;
- case kCursorCreateReply:
- cursor_create_reply.serialize(pptr, psize);
- break;
- case kCursorCloneRequest:
- cursor_clone_request.serialize(pptr, psize);
- break;
- case kCursorCloneReply:
- cursor_clone_reply.serialize(pptr, psize);
- break;
- case kCursorCloseRequest:
- cursor_close_request.serialize(pptr, psize);
- break;
- case kCursorCloseReply:
- cursor_close_reply.serialize(pptr, psize);
- break;
- case kCursorInsertRequest:
- cursor_insert_request.serialize(pptr, psize);
- break;
- case kCursorInsertReply:
- cursor_insert_reply.serialize(pptr, psize);
- break;
- case kCursorEraseRequest:
- cursor_erase_request.serialize(pptr, psize);
- break;
- case kCursorEraseReply:
- cursor_erase_reply.serialize(pptr, psize);
- break;
- case kCursorGetRecordCountRequest:
- cursor_get_record_count_request.serialize(pptr, psize);
- break;
- case kCursorGetRecordCountReply:
- cursor_get_record_count_reply.serialize(pptr, psize);
- break;
- case kCursorGetRecordSizeRequest:
- cursor_get_record_size_request.serialize(pptr, psize);
- break;
- case kCursorGetRecordSizeReply:
- cursor_get_record_size_reply.serialize(pptr, psize);
- break;
- case kCursorGetDuplicatePositionRequest:
- cursor_get_duplicate_position_request.serialize(pptr, psize);
- break;
- case kCursorGetDuplicatePositionReply:
- cursor_get_duplicate_position_reply.serialize(pptr, psize);
- break;
- case kCursorOverwriteRequest:
- cursor_overwrite_request.serialize(pptr, psize);
- break;
- case kCursorOverwriteReply:
- cursor_overwrite_reply.serialize(pptr, psize);
- break;
- case kCursorMoveRequest:
- cursor_move_request.serialize(pptr, psize);
- break;
- case kCursorMoveReply:
- cursor_move_reply.serialize(pptr, psize);
- break;
- default:
- assert(!"shouldn't be here");
- }
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- magic.deserialize(pptr, psize);
- size.deserialize(pptr, psize);
- id.deserialize(pptr, psize);
-
- switch (id.value) {
- case kTxnBeginRequest:
- txn_begin_request.deserialize(pptr, psize);
- break;
- case kTxnBeginReply:
- txn_begin_reply.deserialize(pptr, psize);
- break;
- case kTxnCommitRequest:
- txn_commit_request.deserialize(pptr, psize);
- break;
- case kTxnCommitReply:
- txn_commit_reply.deserialize(pptr, psize);
- break;
- case kTxnAbortRequest:
- txn_abort_request.deserialize(pptr, psize);
- break;
- case kTxnAbortReply:
- txn_abort_reply.deserialize(pptr, psize);
- break;
- case kDbGetKeyCountRequest:
- db_count_request.deserialize(pptr, psize);
- break;
- case kDbGetKeyCountReply:
- db_count_reply.deserialize(pptr, psize);
- break;
- case kDbInsertRequest:
- db_insert_request.deserialize(pptr, psize);
- break;
- case kDbInsertReply:
- db_insert_reply.deserialize(pptr, psize);
- break;
- case kDbEraseRequest:
- db_erase_request.deserialize(pptr, psize);
- break;
- case kDbEraseReply:
- db_erase_reply.deserialize(pptr, psize);
- break;
- case kDbFindRequest:
- db_find_request.deserialize(pptr, psize);
- break;
- case kDbFindReply:
- db_find_reply.deserialize(pptr, psize);
- break;
- case kCursorCreateRequest:
- cursor_create_request.deserialize(pptr, psize);
- break;
- case kCursorCreateReply:
- cursor_create_reply.deserialize(pptr, psize);
- break;
- case kCursorCloneRequest:
- cursor_clone_request.deserialize(pptr, psize);
- break;
- case kCursorCloneReply:
- cursor_clone_reply.deserialize(pptr, psize);
- break;
- case kCursorCloseRequest:
- cursor_close_request.deserialize(pptr, psize);
- break;
- case kCursorCloseReply:
- cursor_close_reply.deserialize(pptr, psize);
- break;
- case kCursorInsertRequest:
- cursor_insert_request.deserialize(pptr, psize);
- break;
- case kCursorInsertReply:
- cursor_insert_reply.deserialize(pptr, psize);
- break;
- case kCursorEraseRequest:
- cursor_erase_request.deserialize(pptr, psize);
- break;
- case kCursorEraseReply:
- cursor_erase_reply.deserialize(pptr, psize);
- break;
- case kCursorGetRecordCountRequest:
- cursor_get_record_count_request.deserialize(pptr, psize);
- break;
- case kCursorGetRecordCountReply:
- cursor_get_record_count_reply.deserialize(pptr, psize);
- break;
- case kCursorGetRecordSizeRequest:
- cursor_get_record_size_request.deserialize(pptr, psize);
- break;
- case kCursorGetRecordSizeReply:
- cursor_get_record_size_reply.deserialize(pptr, psize);
- break;
- case kCursorGetDuplicatePositionRequest:
- cursor_get_duplicate_position_request.deserialize(pptr, psize);
- break;
- case kCursorGetDuplicatePositionReply:
- cursor_get_duplicate_position_reply.deserialize(pptr, psize);
- break;
- case kCursorOverwriteRequest:
- cursor_overwrite_request.deserialize(pptr, psize);
- break;
- case kCursorOverwriteReply:
- cursor_overwrite_reply.serialize(pptr, psize);
- break;
- case kCursorMoveRequest:
- cursor_move_request.deserialize(pptr, psize);
- break;
- case kCursorMoveReply:
- cursor_move_reply.deserialize(pptr, psize);
- break;
- default:
- assert(!"shouldn't be here");
- }
- }
-};
-
-
-} // namespace hamsterdb
-#endif // HAM_MESSAGES_H
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/messages.proto b/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/messages.proto
deleted file mode 100644
index cbd68bf655..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2protoserde/messages.proto
+++ /dev/null
@@ -1,646 +0,0 @@
-SET_OPTION(prefix, Serialized)
-
-PROLOGUE_BEGIN
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_MESSAGES_H
-#define HAM_MESSAGES_H
-
-#include "0root/root.h"
-
-#include <assert.h>
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-/** a magic and version indicator for the remote protocol */
-#define HAM_TRANSFER_MAGIC_V2 (('h'<<24)|('a'<<16)|('m'<<8)|'2')
-
-namespace hamsterdb {
-
-enum {
- kTxnBeginRequest,
- kTxnBeginReply,
- kTxnCommitRequest,
- kTxnCommitReply,
- kTxnAbortRequest,
- kTxnAbortReply,
- kDbGetKeyCountRequest,
- kDbGetKeyCountReply,
- kDbInsertRequest,
- kDbInsertReply,
- kDbEraseRequest,
- kDbEraseReply,
- kDbFindRequest,
- kDbFindReply,
- kCursorCreateRequest,
- kCursorCreateReply,
- kCursorCloneRequest,
- kCursorCloneReply,
- kCursorCloseRequest,
- kCursorCloseReply,
- kCursorInsertRequest,
- kCursorInsertReply,
- kCursorEraseRequest,
- kCursorEraseReply,
- kCursorGetRecordCountRequest,
- kCursorGetRecordCountReply,
- kCursorGetRecordSizeRequest,
- kCursorGetRecordSizeReply,
- kCursorGetDuplicatePositionRequest,
- kCursorGetDuplicatePositionReply,
- kCursorOverwriteRequest,
- kCursorOverwriteReply,
- kCursorMoveRequest,
- kCursorMoveReply
-};
-
-PROLOGUE_END
-
-MESSAGE_BEGIN(Key)
- optional bytes data;
- uint32 flags;
- uint32 intflags;
-MESSAGE_END
-
-MESSAGE_BEGIN(Record)
- optional bytes data;
- uint32 flags;
- uint32 partial_offset;
- uint32 partial_size;
-MESSAGE_END
-
-MESSAGE_BEGIN(ConnectRequest)
- bytes path;
-MESSAGE_END
-
-MESSAGE_BEGIN(ConnectReply)
- sint32 status;
- uint32 env_flags;
- uint64 env_handle;
-MESSAGE_END
-
-MESSAGE_BEGIN(TxnBeginRequest)
- uint64 env_handle;
- uint32 flags;
- bytes name;
-MESSAGE_END
-
-MESSAGE_BEGIN(TxnBeginReply)
- sint32 status;
- uint64 txn_handle;
-MESSAGE_END
-
-MESSAGE_BEGIN(TxnCommitRequest)
- uint64 txn_handle;
- uint32 flags;
-MESSAGE_END
-
-MESSAGE_BEGIN(TxnCommitReply)
- sint32 status;
-MESSAGE_END
-
-MESSAGE_BEGIN(TxnAbortRequest)
- uint64 txn_handle;
- uint32 flags;
-MESSAGE_END
-
-MESSAGE_BEGIN(TxnAbortReply)
- sint32 status;
-MESSAGE_END
-
-MESSAGE_BEGIN(DbGetKeyCountRequest)
- uint64 db_handle;
- uint64 txn_handle;
- bool distinct;
-MESSAGE_END
-
-MESSAGE_BEGIN(DbGetKeyCountReply)
- sint32 status;
- uint64 keycount;
-MESSAGE_END
-
-MESSAGE_BEGIN(DbInsertRequest)
- uint64 db_handle;
- uint64 txn_handle;
- uint32 flags;
- optional Key key;
- optional Record record;
-MESSAGE_END
-
-MESSAGE_BEGIN(DbInsertReply)
- sint32 status;
- optional Key key;
-MESSAGE_END
-
-MESSAGE_BEGIN(DbEraseRequest)
- uint64 db_handle;
- uint64 txn_handle;
- Key key;
- uint32 flags;
-MESSAGE_END
-
-MESSAGE_BEGIN(DbEraseReply)
- sint32 status;
-MESSAGE_END
-
-MESSAGE_BEGIN(DbFindRequest)
- uint64 db_handle;
- uint64 txn_handle;
- uint64 cursor_handle;
- uint32 flags;
- Key key;
- optional Record record;
-MESSAGE_END
-
-MESSAGE_BEGIN(DbFindReply)
- sint32 status;
- optional Key key;
- optional Record record;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorCreateRequest)
- uint64 db_handle;
- uint64 txn_handle;
- uint32 flags;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorCreateReply)
- sint32 status;
- uint64 cursor_handle;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorCloneRequest)
- uint64 cursor_handle;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorCloneReply)
- sint32 status;
- uint64 cursor_handle;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorCloseRequest)
- uint64 cursor_handle;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorCloseReply)
- sint32 status;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorInsertRequest)
- uint64 cursor_handle;
- uint32 flags;
- optional Key key;
- optional Record record;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorInsertReply)
- sint32 status;
- optional Key key;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorEraseRequest)
- uint64 cursor_handle;
- uint32 flags;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorEraseReply)
- sint32 status;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorGetRecordCountRequest)
- uint64 cursor_handle;
- uint32 flags;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorGetRecordCountReply)
- sint32 status;
- uint32 count;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorGetRecordSizeRequest)
- uint64 cursor_handle;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorGetRecordSizeReply)
- sint32 status;
- uint64 size;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorGetDuplicatePositionRequest)
- uint64 cursor_handle;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorGetDuplicatePositionReply)
- sint32 status;
- uint32 position;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorOverwriteRequest)
- uint64 cursor_handle;
- Record record;
- uint32 flags;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorOverwriteReply)
- sint32 status;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorMoveRequest)
- uint64 cursor_handle;
- uint32 flags;
- optional Key key;
- optional Record record;
-MESSAGE_END
-
-MESSAGE_BEGIN(CursorMoveReply)
- sint32 status;
- Key key;
- Record record;
-MESSAGE_END
-
-MESSAGE_BEGIN(Wrapper)
- uint32 magic;
- uint32 size;
- uint32 id;
- TxnBeginRequest txn_begin_request;
- TxnBeginReply txn_begin_reply;
- TxnCommitRequest txn_commit_request;
- TxnCommitReply txn_commit_reply;
- TxnAbortRequest txn_abort_request;
- TxnAbortReply txn_abort_reply;
- DbGetKeyCountRequest db_count_request;
- DbGetKeyCountReply db_count_reply;
- DbInsertRequest db_insert_request;
- DbInsertReply db_insert_reply;
- DbEraseRequest db_erase_request;
- DbEraseReply db_erase_reply;
- DbFindRequest db_find_request;
- DbFindReply db_find_reply;
- CursorCreateRequest cursor_create_request;
- CursorCreateReply cursor_create_reply;
- CursorCloneRequest cursor_clone_request;
- CursorCloneReply cursor_clone_reply;
- CursorCloseRequest cursor_close_request;
- CursorCloseReply cursor_close_reply;
- CursorInsertRequest cursor_insert_request;
- CursorInsertReply cursor_insert_reply;
- CursorEraseRequest cursor_erase_request;
- CursorEraseReply cursor_erase_reply;
- CursorGetRecordCountRequest cursor_get_record_count_request;
- CursorGetRecordCountReply cursor_get_record_count_reply;
- CursorGetRecordSizeRequest cursor_get_record_size_request;
- CursorGetRecordSizeReply cursor_get_record_size_reply;
- CursorGetDuplicatePositionRequest cursor_get_duplicate_position_request;
- CursorGetDuplicatePositionReply cursor_get_duplicate_position_reply;
- CursorOverwriteRequest cursor_overwrite_request;
- CursorOverwriteReply cursor_overwrite_reply;
- CursorMoveRequest cursor_move_request;
- CursorMoveReply cursor_move_reply;
-
- CUSTOM_IMPLEMENTATION_BEGIN
- // the methods in here have a custom implementation, otherwise we would
- // generate many bools for the "optional" fields, and they would
- // unnecessarily increase the structure size
- void clear() {
- magic = 0;
- size = 0;
- id = 0;
- }
-
- size_t get_size() const {
- size_t s = magic.get_size() + size.get_size() + id.get_size();
- switch (id.value) {
- case kTxnBeginRequest:
- return (s + txn_begin_request.get_size());
- case kTxnBeginReply:
- return (s + txn_begin_reply.get_size());
- case kTxnCommitRequest:
- return (s + txn_commit_request.get_size());
- case kTxnCommitReply:
- return (s + txn_commit_reply.get_size());
- case kTxnAbortRequest:
- return (s + txn_abort_request.get_size());
- case kTxnAbortReply:
- return (s + txn_abort_reply.get_size());
- case kDbGetKeyCountRequest:
- return (s + db_count_request.get_size());
- case kDbGetKeyCountReply:
- return (s + db_count_reply.get_size());
- case kDbInsertRequest:
- return (s + db_insert_request.get_size());
- case kDbInsertReply:
- return (s + db_insert_reply.get_size());
- case kDbEraseRequest:
- return (s + db_erase_request.get_size());
- case kDbEraseReply:
- return (s + db_erase_reply.get_size());
- case kDbFindRequest:
- return (s + db_find_request.get_size());
- case kDbFindReply:
- return (s + db_find_reply.get_size());
- case kCursorCreateRequest:
- return (s + cursor_create_request.get_size());
- case kCursorCreateReply:
- return (s + cursor_create_reply.get_size());
- case kCursorCloneRequest:
- return (s + cursor_clone_request.get_size());
- case kCursorCloneReply:
- return (s + cursor_clone_reply.get_size());
- case kCursorCloseRequest:
- return (s + cursor_close_request.get_size());
- case kCursorCloseReply:
- return (s + cursor_close_reply.get_size());
- case kCursorInsertRequest:
- return (s + cursor_insert_request.get_size());
- case kCursorInsertReply:
- return (s + cursor_insert_reply.get_size());
- case kCursorEraseRequest:
- return (s + cursor_erase_request.get_size());
- case kCursorEraseReply:
- return (s + cursor_erase_reply.get_size());
- case kCursorGetRecordCountRequest:
- return (s + cursor_get_record_count_request.get_size());
- case kCursorGetRecordCountReply:
- return (s + cursor_get_record_count_reply.get_size());
- case kCursorGetRecordSizeRequest:
- return (s + cursor_get_record_size_request.get_size());
- case kCursorGetRecordSizeReply:
- return (s + cursor_get_record_size_reply.get_size());
- case kCursorGetDuplicatePositionRequest:
- return (s + cursor_get_duplicate_position_request.get_size());
- case kCursorGetDuplicatePositionReply:
- return (s + cursor_get_duplicate_position_reply.get_size());
- case kCursorOverwriteRequest:
- return (s + cursor_overwrite_request.get_size());
- case kCursorOverwriteReply:
- return (s + cursor_overwrite_reply.get_size());
- case kCursorMoveRequest:
- return (s + cursor_move_request.get_size());
- case kCursorMoveReply:
- return (s + cursor_move_reply.get_size());
- default:
- assert(!"shouldn't be here");
- return (0);
- }
- }
-
- void serialize(unsigned char **pptr, int *psize) const {
- magic.serialize(pptr, psize);
- size.serialize(pptr, psize);
- id.serialize(pptr, psize);
-
- switch (id.value) {
- case kTxnBeginRequest:
- txn_begin_request.serialize(pptr, psize);
- break;
- case kTxnBeginReply:
- txn_begin_reply.serialize(pptr, psize);
- break;
- case kTxnCommitRequest:
- txn_commit_request.serialize(pptr, psize);
- break;
- case kTxnCommitReply:
- txn_commit_reply.serialize(pptr, psize);
- break;
- case kTxnAbortRequest:
- txn_abort_request.serialize(pptr, psize);
- break;
- case kTxnAbortReply:
- txn_abort_reply.serialize(pptr, psize);
- break;
- case kDbGetKeyCountRequest:
- db_count_request.serialize(pptr, psize);
- break;
- case kDbGetKeyCountReply:
- db_count_reply.serialize(pptr, psize);
- break;
- case kDbInsertRequest:
- db_insert_request.serialize(pptr, psize);
- break;
- case kDbInsertReply:
- db_insert_reply.serialize(pptr, psize);
- break;
- case kDbEraseRequest:
- db_erase_request.serialize(pptr, psize);
- break;
- case kDbEraseReply:
- db_erase_reply.serialize(pptr, psize);
- break;
- case kDbFindRequest:
- db_find_request.serialize(pptr, psize);
- break;
- case kDbFindReply:
- db_find_reply.serialize(pptr, psize);
- break;
- case kCursorCreateRequest:
- cursor_create_request.serialize(pptr, psize);
- break;
- case kCursorCreateReply:
- cursor_create_reply.serialize(pptr, psize);
- break;
- case kCursorCloneRequest:
- cursor_clone_request.serialize(pptr, psize);
- break;
- case kCursorCloneReply:
- cursor_clone_reply.serialize(pptr, psize);
- break;
- case kCursorCloseRequest:
- cursor_close_request.serialize(pptr, psize);
- break;
- case kCursorCloseReply:
- cursor_close_reply.serialize(pptr, psize);
- break;
- case kCursorInsertRequest:
- cursor_insert_request.serialize(pptr, psize);
- break;
- case kCursorInsertReply:
- cursor_insert_reply.serialize(pptr, psize);
- break;
- case kCursorEraseRequest:
- cursor_erase_request.serialize(pptr, psize);
- break;
- case kCursorEraseReply:
- cursor_erase_reply.serialize(pptr, psize);
- break;
- case kCursorGetRecordCountRequest:
- cursor_get_record_count_request.serialize(pptr, psize);
- break;
- case kCursorGetRecordCountReply:
- cursor_get_record_count_reply.serialize(pptr, psize);
- break;
- case kCursorGetRecordSizeRequest:
- cursor_get_record_size_request.serialize(pptr, psize);
- break;
- case kCursorGetRecordSizeReply:
- cursor_get_record_size_reply.serialize(pptr, psize);
- break;
- case kCursorGetDuplicatePositionRequest:
- cursor_get_duplicate_position_request.serialize(pptr, psize);
- break;
- case kCursorGetDuplicatePositionReply:
- cursor_get_duplicate_position_reply.serialize(pptr, psize);
- break;
- case kCursorOverwriteRequest:
- cursor_overwrite_request.serialize(pptr, psize);
- break;
- case kCursorOverwriteReply:
- cursor_overwrite_reply.serialize(pptr, psize);
- break;
- case kCursorMoveRequest:
- cursor_move_request.serialize(pptr, psize);
- break;
- case kCursorMoveReply:
- cursor_move_reply.serialize(pptr, psize);
- break;
- default:
- assert(!"shouldn't be here");
- }
- }
-
- void deserialize(unsigned char **pptr, int *psize) {
- magic.deserialize(pptr, psize);
- size.deserialize(pptr, psize);
- id.deserialize(pptr, psize);
-
- switch (id.value) {
- case kTxnBeginRequest:
- txn_begin_request.deserialize(pptr, psize);
- break;
- case kTxnBeginReply:
- txn_begin_reply.deserialize(pptr, psize);
- break;
- case kTxnCommitRequest:
- txn_commit_request.deserialize(pptr, psize);
- break;
- case kTxnCommitReply:
- txn_commit_reply.deserialize(pptr, psize);
- break;
- case kTxnAbortRequest:
- txn_abort_request.deserialize(pptr, psize);
- break;
- case kTxnAbortReply:
- txn_abort_reply.deserialize(pptr, psize);
- break;
- case kDbGetKeyCountRequest:
- db_count_request.deserialize(pptr, psize);
- break;
- case kDbGetKeyCountReply:
- db_count_reply.deserialize(pptr, psize);
- break;
- case kDbInsertRequest:
- db_insert_request.deserialize(pptr, psize);
- break;
- case kDbInsertReply:
- db_insert_reply.deserialize(pptr, psize);
- break;
- case kDbEraseRequest:
- db_erase_request.deserialize(pptr, psize);
- break;
- case kDbEraseReply:
- db_erase_reply.deserialize(pptr, psize);
- break;
- case kDbFindRequest:
- db_find_request.deserialize(pptr, psize);
- break;
- case kDbFindReply:
- db_find_reply.deserialize(pptr, psize);
- break;
- case kCursorCreateRequest:
- cursor_create_request.deserialize(pptr, psize);
- break;
- case kCursorCreateReply:
- cursor_create_reply.deserialize(pptr, psize);
- break;
- case kCursorCloneRequest:
- cursor_clone_request.deserialize(pptr, psize);
- break;
- case kCursorCloneReply:
- cursor_clone_reply.deserialize(pptr, psize);
- break;
- case kCursorCloseRequest:
- cursor_close_request.deserialize(pptr, psize);
- break;
- case kCursorCloseReply:
- cursor_close_reply.deserialize(pptr, psize);
- break;
- case kCursorInsertRequest:
- cursor_insert_request.deserialize(pptr, psize);
- break;
- case kCursorInsertReply:
- cursor_insert_reply.deserialize(pptr, psize);
- break;
- case kCursorEraseRequest:
- cursor_erase_request.deserialize(pptr, psize);
- break;
- case kCursorEraseReply:
- cursor_erase_reply.deserialize(pptr, psize);
- break;
- case kCursorGetRecordCountRequest:
- cursor_get_record_count_request.deserialize(pptr, psize);
- break;
- case kCursorGetRecordCountReply:
- cursor_get_record_count_reply.deserialize(pptr, psize);
- break;
- case kCursorGetRecordSizeRequest:
- cursor_get_record_size_request.deserialize(pptr, psize);
- break;
- case kCursorGetRecordSizeReply:
- cursor_get_record_size_reply.deserialize(pptr, psize);
- break;
- case kCursorGetDuplicatePositionRequest:
- cursor_get_duplicate_position_request.deserialize(pptr, psize);
- break;
- case kCursorGetDuplicatePositionReply:
- cursor_get_duplicate_position_reply.deserialize(pptr, psize);
- break;
- case kCursorOverwriteRequest:
- cursor_overwrite_request.deserialize(pptr, psize);
- break;
- case kCursorOverwriteReply:
- cursor_overwrite_reply.serialize(pptr, psize);
- break;
- case kCursorMoveRequest:
- cursor_move_request.deserialize(pptr, psize);
- break;
- case kCursorMoveReply:
- cursor_move_reply.deserialize(pptr, psize);
- break;
- default:
- assert(!"shouldn't be here");
- }
- }
- CUSTOM_IMPLEMENTATION_END
-MESSAGE_END
-
-
-EPILOGUE_BEGIN
-
-} // namespace hamsterdb
-#endif // HAM_MESSAGES_H
-
-EPILOGUE_END
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2queue/queue.h b/plugins/Dbx_kv/src/hamsterdb/src/2queue/queue.h
deleted file mode 100644
index a45d45dfa2..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2queue/queue.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A thread-safe message queue. Producers can insert at the front, Consumers
- * pick messages from the tail.
- *
- * The queue uses a Spinlock for synchronization, but locks it only very,
- * very briefly.
- */
-
-#ifndef HAM_QUEUE_H
-#define HAM_QUEUE_H
-
-#include "0root/root.h"
-
-#include <ham/types.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/spinlock.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-// The Message. Other messages can derive from it and append their own
-// payload.
-struct MessageBase
-{
- // Message flags
- enum {
- // Message is mandatory and must not be skipped
- kIsMandatory = 0
- };
-
- MessageBase(int type_, int flags_)
- : type(type_), flags(flags_), previous(0), next(0) {
- }
-
- virtual ~MessageBase() {
- }
-
- int type;
- int flags;
- MessageBase *previous;
- MessageBase *next;
-};
-
-
-class Queue
-{
- public:
- template<typename T>
- struct Message : public MessageBase
- {
- Message(int type, int flags)
- : MessageBase(type, flags) {
- }
-
- T payload;
- };
-
- Queue()
- : m_head(0), m_tail(0) {
- }
-
- // Pushes a |message| object to the queue
- void push(MessageBase *message) {
- ScopedSpinlock lock(m_mutex);
- if (!m_tail) {
- ham_assert(m_head == 0);
- m_head = m_tail = message;
- }
- else if (m_tail == m_head) {
- m_tail->previous = message;
- message->next = m_tail;
- m_head = message;
- }
- else {
- message->next = m_head;
- m_head->previous = message;
- m_head = message;
- }
- }
-
- // Pops a message from the tail of the queue. Returns null if the queue
- // is empty.
- MessageBase *pop() {
- ScopedSpinlock lock(m_mutex);
- if (!m_tail) {
- ham_assert(m_head == 0);
- return (0);
- }
-
- MessageBase *msg = m_tail;
- if (m_tail == m_head)
- m_head = m_tail = 0;
- else
- m_tail = m_tail->previous;
- return (msg);
- }
-
- private:
- // For synchronization
- Spinlock m_mutex;
-
- // The head of the linked list (and newest MessageBase)
- MessageBase *m_head;
-
- // The tail of the linked list (and oldest MessageBase)
- MessageBase *m_tail;
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_QUEUE_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/2worker/worker.h b/plugins/Dbx_kv/src/hamsterdb/src/2worker/worker.h
deleted file mode 100644
index 2f6798b32c..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/2worker/worker.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The worker thread. Asynchronously purges the cache. Thread will start as
- * soon as it's constructed.
- */
-
-#ifndef HAM_WORKER_H
-#define HAM_WORKER_H
-
-#include "0root/root.h"
-
-#include <boost/thread.hpp>
-
-// Always verify that a file of level N does not include headers > N!
-#include "2queue/queue.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Worker
-{
- public:
- Worker()
- : m_stop_requested(false), m_thread(&Worker::run, this) {
- }
-
- void add_to_queue(MessageBase *message) {
- m_queue.push(message);
-
- ScopedLock lock(m_mutex);
- m_cond.notify_one();
- }
-
- void stop_and_join() {
- {
- ScopedLock lock(m_mutex);
- m_stop_requested = true;
- m_cond.notify_one();
- }
- m_thread.join();
- }
-
- private:
- // The thread function
- void run() {
- while (true) {
- MessageBase *message = 0;
- {
- ScopedLock lock(m_mutex);
- if (m_stop_requested)
- return;
- message = m_queue.pop();
- if (!message) {
- m_cond.wait(lock); // will unlock m_mutex while waiting
- message = m_queue.pop();
- }
- }
-
- if (message) {
- handle_message(message);
- delete message;
- }
- }
- }
-
- // The message handler - has to be overridden
- virtual void handle_message(MessageBase *message) = 0;
-
- // A queue for storing messages
- Queue m_queue;
-
- // true if the Environment is closed
- bool m_stop_requested;
-
- // A mutex for protecting |m_cond|
- boost::mutex m_mutex;
-
- // A condition to wait for
- boost::condition_variable m_cond;
-
- // The actual thread
- boost::thread m_thread;
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_WORKER_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager.cc b/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager.cc
deleted file mode 100644
index d0c075cdec..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "blob_manager.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-uint64_t
-BlobManager::allocate(Context *context, ham_record_t *record,
- uint32_t flags)
-{
- // PARTIAL WRITE
- //
- // if offset+partial_size equals the full record size, then we won't
- // have any gaps. In this case we just write the full record and ignore
- // the partial parameters.
- if (flags & HAM_PARTIAL) {
- if (record->partial_offset == 0 && record->partial_size == record->size)
- flags &= ~HAM_PARTIAL;
- }
-
- m_metric_total_allocated++;
-
- return (do_allocate(context, record, flags));
-}
-
-void
-BlobManager::read(Context *context, uint64_t blobid, ham_record_t *record,
- uint32_t flags, ByteArray *arena)
-{
- m_metric_total_read++;
-
- return (do_read(context, blobid, record, flags, arena));
-}
-
-uint64_t
-BlobManager::overwrite(Context *context, uint64_t old_blobid,
- ham_record_t *record, uint32_t flags)
-{
- // PARTIAL WRITE
- //
- // if offset+partial_size equals the full record size, then we won't
- // have any gaps. In this case we just write the full record and ignore
- // the partial parameters.
- if (flags & HAM_PARTIAL) {
- if (record->partial_offset == 0 && record->partial_size == record->size)
- flags &= ~HAM_PARTIAL;
- }
-
- return (do_overwrite(context, old_blobid, record, flags));
-}
-
-uint64_t
-BlobManager::get_blob_size(Context *context, uint64_t blob_id)
-{
- return (do_get_blob_size(context, blob_id));
-}
-
-void
-BlobManager::erase(Context *context, uint64_t blob_id, Page *page,
- uint32_t flags)
-{
- return (do_erase(context, blob_id, page, flags));
-}
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager.h b/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager.h
deleted file mode 100644
index 208345e2ed..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @brief functions for reading/writing/allocating blobs (memory chunks of
- * arbitrary size)
- *
- */
-
-#ifndef HAM_BLOB_MANAGER_H
-#define HAM_BLOB_MANAGER_H
-
-#include "0root/root.h"
-
-#include "ham/hamsterdb_int.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-class LocalEnvironment;
-
-#include "1base/packstart.h"
-
-// A blob header structure
-//
-// This header is prepended to the blob's payload. It holds the blob size and
-// the blob's address (which is not required but useful for error checking.)
-HAM_PACK_0 class HAM_PACK_1 PBlobHeader
-{
- public:
- PBlobHeader() {
- memset(this, 0, sizeof(PBlobHeader));
- }
-
- // Returns a PBlobHeader from a file address
- static PBlobHeader *from_page(Page *page, uint64_t address) {
- uint32_t readstart = (uint32_t)(address - page->get_address());
- return (PBlobHeader *)&page->get_raw_payload()[readstart];
- }
-
- // Returns the blob flags
- uint32_t get_flags() const {
- return (m_flags);
- }
-
- // Sets the blob's flags
- void set_flags(uint32_t flags) {
- m_flags = flags;
- }
-
- // Returns the absolute address of the blob
- uint64_t get_self() const {
- return (m_blobid);
- }
-
- // Sets the absolute address of the blob
- void set_self(uint64_t id) {
- m_blobid = id;
- }
-
- // Returns the payload size of the blob
- uint64_t get_size() const {
- return (m_size);
- }
-
- // Sets the payload size of the blob
- void set_size(uint64_t size) {
- m_size = size;
- }
-
- // Returns the allocated size of the blob (includes padding)
- uint64_t get_alloc_size() const {
- return (m_allocated_size);
- }
-
- // Sets the allocated size of a blob (includes padding)
- void set_alloc_size(uint64_t size) {
- m_allocated_size = size;
- }
-
- private:
- // Flags; currently only used in hamsterdb-pro to store compression
- // information
- uint32_t m_flags;
-
- // The blob ID - which is the absolute address/offset of this
- //* structure in the file
- uint64_t m_blobid;
-
- // The allocated size of the blob; this is the size, which is used
- // by the blob and it's header and maybe additional padding
- uint64_t m_allocated_size;
-
- // The "real" size of the blob (excluding the header)
- uint64_t m_size;
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-// The BlobManager manages blobs (not a surprise)
-//
-// This is an abstract baseclass, derived for In-Memory- and Disk-based
-// Environments.
-class BlobManager
-{
- protected:
- // Flags for the PBlobHeader structure
- enum {
- // Blob is compressed
- kIsCompressed = 1
- };
-
- public:
- // Flags for allocate(); make sure that they do not conflict with
- // the flags for ham_db_insert()
- enum {
- // Do not compress the blob, even if compression is enabled
- kDisableCompression = 0x10000000
- };
-
- BlobManager(LocalEnvironment *env)
- : m_env(env), m_metric_before_compression(0),
- m_metric_after_compression(0), m_metric_total_allocated(0),
- m_metric_total_read(0) {
- }
-
- virtual ~BlobManager() { }
-
- // Allocates/create a new blob.
- // This function returns the blob-id (the start address of the blob
- // header)
- //
- // |flags| can be HAM_PARTIAL, kDisableCompression
- uint64_t allocate(Context *context, ham_record_t *record, uint32_t flags);
-
- // Reads a blob and stores the data in @a record.
- // @ref flags: either 0 or HAM_DIRECT_ACCESS
- void read(Context *context, uint64_t blob_id, ham_record_t *record,
- uint32_t flags, ByteArray *arena);
-
- // Retrieves the size of a blob
- uint64_t get_blob_size(Context *context, uint64_t blob_id);
-
- // Overwrites an existing blob
- //
- // Will return an error if the blob does not exist. Returns the blob-id
- // (the start address of the blob header)
- uint64_t overwrite(Context *context, uint64_t old_blob_id,
- ham_record_t *record, uint32_t flags);
-
- // Deletes an existing blob
- void erase(Context *context, uint64_t blob_id, Page *page = 0,
- uint32_t flags = 0);
-
- // Fills in the current metrics
- void fill_metrics(ham_env_metrics_t *metrics) const {
- metrics->blob_total_allocated = m_metric_total_allocated;
- metrics->blob_total_read = m_metric_total_read;
- metrics->record_bytes_before_compression = m_metric_before_compression;
- metrics->record_bytes_after_compression = m_metric_after_compression;
- }
-
- protected:
- // Allocates/create a new blob.
- // This function returns the blob-id (the start address of the blob
- // header)
- virtual uint64_t do_allocate(Context *context, ham_record_t *record,
- uint32_t flags) = 0;
-
- // Reads a blob and stores the data in @a record.
- // @ref flags: either 0 or HAM_DIRECT_ACCESS
- virtual void do_read(Context *context, uint64_t blob_id,
- ham_record_t *record, uint32_t flags,
- ByteArray *arena) = 0;
-
- // Retrieves the size of a blob
- virtual uint64_t do_get_blob_size(Context *context,
- uint64_t blob_id) = 0;
-
- // Overwrites an existing blob
- //
- // Will return an error if the blob does not exist. Returns the blob-id
- // (the start address of the blob header)
- virtual uint64_t do_overwrite(Context *context, uint64_t old_blob_id,
- ham_record_t *record, uint32_t flags) = 0;
-
- // Deletes an existing blob
- virtual void do_erase(Context *context, uint64_t blob_id,
- Page *page = 0, uint32_t flags = 0) = 0;
-
- // The Environment which created this BlobManager
- LocalEnvironment *m_env;
-
- // Usage tracking - number of bytes before compression
- uint64_t m_metric_before_compression;
-
- // Usage tracking - number of bytes after compression
- uint64_t m_metric_after_compression;
-
- private:
- // Usage tracking - number of blobs allocated
- uint64_t m_metric_total_allocated;
-
- // Usage tracking - number of blobs read
- uint64_t m_metric_total_read;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BLOB_MANAGER_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_disk.cc b/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_disk.cc
deleted file mode 100644
index 231789774b..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_disk.cc
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <algorithm>
-#include <vector>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1base/dynamic_array.h"
-#include "2device/device.h"
-#include "3blob_manager/blob_manager_disk.h"
-#include "3page_manager/page_manager.h"
-#include "4db/db_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-uint64_t
-DiskBlobManager::do_allocate(Context *context, ham_record_t *record,
- uint32_t flags)
-{
- uint8_t *chunk_data[2];
- uint32_t chunk_size[2];
- uint32_t page_size = m_env->config().page_size_bytes;
-
- PBlobHeader blob_header;
- uint32_t alloc_size = sizeof(PBlobHeader) + record->size;
-
- // first check if we can add another blob to the last used page
- Page *page = m_env->page_manager()->get_last_blob_page(context);
-
- PBlobPageHeader *header = 0;
- uint64_t address = 0;
- if (page) {
- header = PBlobPageHeader::from_page(page);
- // allocate space for the blob
- if (!alloc_from_freelist(header, alloc_size, &address))
- page = 0;
- else
- address += page->get_address();
- }
-
- if (!address) {
- // Allocate a new page. If the blob exceeds a page then allocate multiple
- // pages that are directly next to each other.
- uint32_t required_size = alloc_size + kPageOverhead;
- uint32_t num_pages = required_size / page_size;
- if (num_pages * page_size < required_size)
- num_pages++;
-
- // |page| now points to the first page that was allocated, and
- // the only one which has a header and a freelist
- page = m_env->page_manager()->alloc_multiple_blob_pages(context, num_pages);
- ham_assert(page->is_without_header() == false);
-
- // initialize the PBlobPageHeader
- header = PBlobPageHeader::from_page(page);
- header->initialize();
- header->set_num_pages(num_pages);
- header->set_free_bytes((num_pages * page_size) - kPageOverhead);
-
- // and move the remaining space to the freelist, unless we span multiple
- // pages (then the rest will be discarded) - TODO can we reuse it somehow?
- if (num_pages == 1
- && kPageOverhead + alloc_size > 0
- && header->get_free_bytes() - alloc_size > 0) {
- header->set_freelist_offset(0, kPageOverhead + alloc_size);
- header->set_freelist_size(0, header->get_free_bytes() - alloc_size);
- }
-
- address = page->get_address() + kPageOverhead;
- ham_assert(check_integrity(header));
- }
-
- // addjust "free bytes" counter
- ham_assert(header->get_free_bytes() >= alloc_size);
- header->set_free_bytes(header->get_free_bytes() - alloc_size);
-
- // store the page id if it still has space left
- if (header->get_free_bytes())
- m_env->page_manager()->set_last_blob_page(page);
- else
- m_env->page_manager()->set_last_blob_page(0);
-
- // initialize the blob header
- blob_header.set_alloc_size(alloc_size);
- blob_header.set_size(record->size);
- blob_header.set_self(address);
-
- // PARTIAL WRITE
- //
- // Are there gaps at the beginning? If yes, then we'll fill with zeros
- ByteArray zeroes;
- if ((flags & HAM_PARTIAL) && (record->partial_offset > 0)) {
- uint32_t gapsize = record->partial_offset;
-
- // first: write the header
- chunk_data[0] = (uint8_t *)&blob_header;
- chunk_size[0] = sizeof(blob_header);
- write_chunks(context, page, address, chunk_data, chunk_size, 1);
-
- address += sizeof(blob_header);
-
- // now fill the gap; if the gap is bigger than a pagesize we'll
- // split the gap into smaller chunks
- while (gapsize) {
- uint32_t size = gapsize >= page_size
- ? page_size
- : gapsize;
- chunk_data[0] = (uint8_t *)zeroes.resize(size, 0);
- chunk_size[0] = size;
- write_chunks(context, page, address, chunk_data, chunk_size, 1);
- gapsize -= size;
- address += size;
- }
-
- // now write the "real" data
- chunk_data[0] = (uint8_t *)record->data;
- chunk_size[0] = record->partial_size;
-
- write_chunks(context, page, address, chunk_data, chunk_size, 1);
- address += record->partial_size;
- }
- else {
- // not writing partially: write header and data, then we're done
- chunk_data[0] = (uint8_t *)&blob_header;
- chunk_size[0] = sizeof(blob_header);
- chunk_data[1] = (uint8_t *)record->data;
- chunk_size[1] = (flags & HAM_PARTIAL)
- ? record->partial_size
- : record->size;
-
- write_chunks(context, page, address, chunk_data, chunk_size, 2);
- address += chunk_size[0] + chunk_size[1];
- }
-
- // store the blobid; it will be returned to the caller
- uint64_t blobid = blob_header.get_self();
-
- // PARTIAL WRITES:
- //
- // if we have gaps at the end of the blob: just append more chunks to
- // fill these gaps. Since they can be pretty large we split them into
- // smaller chunks if necessary.
- if (flags & HAM_PARTIAL) {
- if (record->partial_offset + record->partial_size < record->size) {
- uint32_t gapsize = record->size
- - (record->partial_offset + record->partial_size);
-
- // now fill the gap; if the gap is bigger than a pagesize we'll
- // split the gap into smaller chunks
- //
- // we split this loop in two - the outer loop will allocate the
- // memory buffer, thus saving some allocations
- while (gapsize) {
- uint32_t size = gapsize > page_size
- ? page_size
- : gapsize;
- chunk_data[0] = (uint8_t *)zeroes.resize(size, 0);
- chunk_size[0] = size;
- write_chunks(context, page, address, chunk_data, chunk_size, 1);
- gapsize -= size;
- address += size;
- }
- }
- }
-
- ham_assert(check_integrity(header));
-
- return (blobid);
-}
-
-void
-DiskBlobManager::do_read(Context *context, uint64_t blobid,
- ham_record_t *record, uint32_t flags, ByteArray *arena)
-{
- Page *page;
-
- // first step: read the blob header
- PBlobHeader *blob_header = (PBlobHeader *)read_chunk(context, 0, &page,
- blobid, true);
-
- // sanity check
- if (blob_header->get_self() != blobid) {
- ham_log(("blob %lld not found", blobid));
- throw Exception(HAM_BLOB_NOT_FOUND);
- }
-
- uint32_t blobsize = (uint32_t)blob_header->get_size();
- record->size = blobsize;
-
- if (flags & HAM_PARTIAL) {
- if (record->partial_offset > blobsize) {
- ham_trace(("partial offset is greater than the total record size"));
- throw Exception(HAM_INV_PARAMETER);
- }
- if (record->partial_offset + record->partial_size > blobsize)
- record->partial_size = blobsize = blobsize - record->partial_offset;
- else
- blobsize = record->partial_size;
- }
-
- // empty blob?
- if (!blobsize) {
- record->data = 0;
- record->size = 0;
- return;
- }
-
- // if the blob is in memory-mapped storage (and the user does not require
- // a copy of the data): simply return a pointer
- if ((flags & HAM_FORCE_DEEP_COPY) == 0
- && m_env->device()->is_mapped(blobid, blobsize)
- && !(record->flags & HAM_RECORD_USER_ALLOC)) {
- record->data = read_chunk(context, page, 0,
- blobid + sizeof(PBlobHeader) + (flags & HAM_PARTIAL
- ? record->partial_offset
- : 0), true);
- }
- // otherwise resize the blob buffer and copy the blob data into the buffer
- else {
- if (!(record->flags & HAM_RECORD_USER_ALLOC)) {
- arena->resize(blobsize);
- record->data = arena->get_ptr();
- }
-
- copy_chunk(context, page, 0,
- blobid + sizeof(PBlobHeader) + (flags & HAM_PARTIAL
- ? record->partial_offset
- : 0),
- (uint8_t *)record->data, blobsize, true);
- }
-}
-
-uint64_t
-DiskBlobManager::do_get_blob_size(Context *context, uint64_t blobid)
-{
- // read the blob header
- PBlobHeader *blob_header = (PBlobHeader *)read_chunk(context, 0, 0, blobid,
- true);
-
- if (blob_header->get_self() != blobid)
- throw Exception(HAM_BLOB_NOT_FOUND);
-
- return (blob_header->get_size());
-}
-
-uint64_t
-DiskBlobManager::do_overwrite(Context *context, uint64_t old_blobid,
- ham_record_t *record, uint32_t flags)
-{
- PBlobHeader *old_blob_header, new_blob_header;
- Page *page;
-
- uint32_t alloc_size = sizeof(PBlobHeader) + record->size;
-
- // first, read the blob header; if the new blob fits into the
- // old blob, we overwrite the old blob (and add the remaining
- // space to the freelist, if there is any)
- old_blob_header = (PBlobHeader *)read_chunk(context, 0, &page,
- old_blobid, false);
-
- // sanity check
- ham_assert(old_blob_header->get_self() == old_blobid);
- if (old_blob_header->get_self() != old_blobid)
- throw Exception(HAM_BLOB_NOT_FOUND);
-
- // now compare the sizes; does the new data fit in the old allocated
- // space?
- if (alloc_size <= old_blob_header->get_alloc_size()) {
- uint8_t *chunk_data[2];
- uint32_t chunk_size[2];
-
- // setup the new blob header
- new_blob_header.set_self(old_blob_header->get_self());
- new_blob_header.set_size(record->size);
- new_blob_header.set_alloc_size(alloc_size);
- new_blob_header.set_flags(0); // disable compression, just in case...
-
- // PARTIAL WRITE
- //
- // if we have a gap at the beginning, then we have to write the
- // blob header and the blob data in two steps; otherwise we can
- // write both immediately
- if ((flags & HAM_PARTIAL) && (record->partial_offset)) {
- chunk_data[0] = (uint8_t *)&new_blob_header;
- chunk_size[0] = sizeof(new_blob_header);
- write_chunks(context, page, new_blob_header.get_self(),
- chunk_data, chunk_size, 1);
-
- chunk_data[0] = (uint8_t *)record->data;
- chunk_size[0] = record->partial_size;
- write_chunks(context, page, new_blob_header.get_self()
- + sizeof(new_blob_header) + record->partial_offset,
- chunk_data, chunk_size, 1);
- }
- else {
- chunk_data[0] = (uint8_t *)&new_blob_header;
- chunk_size[0] = sizeof(new_blob_header);
- chunk_data[1] = (uint8_t *)record->data;
- chunk_size[1] = (flags & HAM_PARTIAL)
- ? record->partial_size
- : record->size;
-
- write_chunks(context, page, new_blob_header.get_self(),
- chunk_data, chunk_size, 2);
- }
-
- // move remaining data to the freelist
- if (alloc_size < old_blob_header->get_alloc_size()) {
- PBlobPageHeader *header = PBlobPageHeader::from_page(page);
- header->set_free_bytes(header->get_free_bytes()
- + (uint32_t)(old_blob_header->get_alloc_size() - alloc_size));
- add_to_freelist(header,
- (uint32_t)(old_blobid + alloc_size) - page->get_address(),
- (uint32_t)old_blob_header->get_alloc_size() - alloc_size);
- }
-
- // the old rid is the new rid
- return (new_blob_header.get_self());
- }
-
- // if the new data is larger: allocate a fresh space for it
- // and discard the old; 'overwrite' has become (delete + insert) now.
- uint64_t new_blobid = allocate(context, record, flags);
- erase(context, old_blobid, 0, 0);
-
- return (new_blobid);
-}
-
-void
-DiskBlobManager::do_erase(Context *context, uint64_t blobid, Page *page,
- uint32_t flags)
-{
- // fetch the blob header
- PBlobHeader *blob_header = (PBlobHeader *)read_chunk(context, 0, &page,
- blobid, false);
-
- // sanity check
- ham_verify(blob_header->get_self() == blobid);
- if (blob_header->get_self() != blobid)
- throw Exception(HAM_BLOB_NOT_FOUND);
-
- // update the "free bytes" counter in the blob page header
- PBlobPageHeader *header = PBlobPageHeader::from_page(page);
- header->set_free_bytes(header->get_free_bytes()
- + blob_header->get_alloc_size());
-
- // if the page is now completely empty (all blobs were erased) then move
- // it to the freelist
- if (header->get_free_bytes() == (header->get_num_pages()
- * m_env->config().page_size_bytes) - kPageOverhead) {
- m_env->page_manager()->set_last_blob_page(0);
- m_env->page_manager()->del(context, page, header->get_num_pages());
- header->initialize();
- return;
- }
-
- // otherwise move the blob to the freelist
- add_to_freelist(header, (uint32_t)(blobid - page->get_address()),
- (uint32_t)blob_header->get_alloc_size());
-}
-
-bool
-DiskBlobManager::alloc_from_freelist(PBlobPageHeader *header, uint32_t size,
- uint64_t *poffset)
-{
- ham_assert(check_integrity(header));
-
- // freelist is not used if this is a multi-page blob
- if (header->get_num_pages() > 1)
- return (false);
-
- uint32_t count = header->get_freelist_entries();
-
- for (uint32_t i = 0; i < count; i++) {
- // exact match
- if (header->get_freelist_size(i) == size) {
- *poffset = header->get_freelist_offset(i);
- header->set_freelist_offset(i, 0);
- header->set_freelist_size(i, 0);
- ham_assert(check_integrity(header));
- return (true);
- }
- // space in freelist is larger than what we need? return this space,
- // make sure the remaining gap stays in the freelist
- if (header->get_freelist_size(i) > size) {
- *poffset = header->get_freelist_offset(i);
- header->set_freelist_offset(i, (uint32_t)(*poffset + size));
- header->set_freelist_size(i, header->get_freelist_size(i) - size);
- ham_assert(check_integrity(header));
- return (true);
- }
- }
-
- // there was no gap large enough for the blob
- return (false);
-}
-
-void
-DiskBlobManager::add_to_freelist(PBlobPageHeader *header,
- uint32_t offset, uint32_t size)
-{
- ham_assert(check_integrity(header));
-
- // freelist is not used if this is a multi-page blob
- if (header->get_num_pages() > 1)
- return;
-
- uint32_t count = header->get_freelist_entries();
-
- // first try to collapse the blobs
- for (uint32_t i = 0; i < count; i++) {
- if (offset + size == header->get_freelist_offset(i)) {
- header->set_freelist_offset(i, offset);
- header->set_freelist_size(i, header->get_freelist_size(i) + size);
- ham_assert(check_integrity(header));
- return;
- }
- if (header->get_freelist_offset(i) + header->get_freelist_size(i)
- == offset) {
- header->set_freelist_size(i, header->get_freelist_size(i) + size);
- ham_assert(check_integrity(header));
- return;
- }
- }
-
- // otherwise store the blob in a new slot, if available
- uint32_t smallest = 0;
- for (uint32_t i = 0; i < count; i++) {
- // slot is empty
- if (header->get_freelist_size(i) == 0) {
- header->set_freelist_offset(i, offset);
- header->set_freelist_size(i, size);
- ham_assert(check_integrity(header));
- return;
- }
- // otherwise look for the smallest entry
- if (header->get_freelist_size(i) < header->get_freelist_size(smallest)) {
- smallest = i;
- continue;
- }
- }
-
- // overwrite the smallest entry?
- if (size > header->get_freelist_size(smallest)) {
- header->set_freelist_offset(smallest, offset);
- header->set_freelist_size(smallest, size);
- }
-
- ham_assert(check_integrity(header));
-}
-
-bool
-DiskBlobManager::check_integrity(PBlobPageHeader *header) const
-{
- ham_assert(header->get_num_pages() > 0);
-
- if (header->get_free_bytes() + kPageOverhead
- > (m_env->config().page_size_bytes * header->get_num_pages())) {
- ham_trace(("integrity violated: free bytes exceeds page boundary"));
- return (false);
- }
-
- // freelist is not used if this is a multi-page blob
- if (header->get_num_pages() > 1)
- return (true);
-
- uint32_t count = header->get_freelist_entries();
- uint32_t total_sizes = 0;
- typedef std::pair<uint32_t, uint32_t> Range;
- typedef std::vector<Range> RangeVec;
- RangeVec ranges;
-
- for (uint32_t i = 0; i < count - 1; i++) {
- if (header->get_freelist_size(i) == 0) {
- ham_assert(header->get_freelist_offset(i) == 0);
- continue;
- }
- total_sizes += header->get_freelist_size(i);
- ranges.push_back(std::make_pair(header->get_freelist_offset(i),
- header->get_freelist_size(i)));
- }
-
- // the sum of freelist chunks must not exceed total number of free bytes
- if (total_sizes > header->get_free_bytes()) {
- ham_trace(("integrity violated: total freelist slots exceed free bytes"));
- return (false);
- }
-
- std::sort(ranges.begin(), ranges.end());
-
- if (!ranges.empty()) {
- for (uint32_t i = 0; i < ranges.size() - 1; i++) {
- if (ranges[i].first + ranges[i].second
- > m_env->config().page_size_bytes * header->get_num_pages()) {
- ham_trace(("integrity violated: freelist slot %u/%u exceeds page",
- ranges[i].first, ranges[i].second));
- return (false);
- }
- if (ranges[i].first + ranges[i].second > ranges[i + 1].first) {
- ham_trace(("integrity violated: freelist slot %u/%u overlaps with %lu",
- ranges[i].first, ranges[i].second,
- ranges[i + 1].first));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- }
- }
-
- return (true);
-}
-
-void
-DiskBlobManager::write_chunks(Context *context, Page *page,
- uint64_t address, uint8_t **chunk_data, uint32_t *chunk_size,
- uint32_t chunks)
-{
- uint32_t page_size = m_env->config().page_size_bytes;
-
- // for each chunk...
- for (uint32_t i = 0; i < chunks; i++) {
- uint32_t size = chunk_size[i];
- uint8_t *data = chunk_data[i];
-
- while (size) {
- // get the page-id from this chunk
- uint64_t pageid = address - (address % page_size);
-
- // is this the current page? if yes then continue working with this page,
- // otherwise fetch the page
- if (page && page->get_address() != pageid)
- page = 0;
- if (!page)
- page = m_env->page_manager()->fetch(context, pageid,
- PageManager::kNoHeader);
-
- uint32_t write_start = (uint32_t)(address - page->get_address());
- uint32_t write_size = (uint32_t)(page_size - write_start);
-
- // now write the data
- if (write_size > size)
- write_size = size;
- memcpy(&page->get_raw_payload()[write_start], data, write_size);
- page->set_dirty(true);
- address += write_size;
- data += write_size;
- size -= write_size;
- }
- }
-}
-
-void
-DiskBlobManager::copy_chunk(Context *context, Page *page, Page **ppage,
- uint64_t address, uint8_t *data, uint32_t size,
- bool fetch_read_only)
-{
- uint32_t page_size = m_env->config().page_size_bytes;
- bool first_page = true;
-
- while (size) {
- // get the page-id from this chunk
- uint64_t pageid = address - (address % page_size);
-
- // is this the current page? if yes then continue working with this page,
- // otherwise fetch the page
- if (page && page->get_address() != pageid)
- page = 0;
-
- if (!page) {
- uint32_t flags = 0;
- if (fetch_read_only)
- flags |= PageManager::kReadOnly;
- if (!first_page)
- flags |= PageManager::kNoHeader;
- page = m_env->page_manager()->fetch(context, pageid, flags);
- }
-
- // now read the data from the page
- uint32_t read_start = (uint32_t)(address - page->get_address());
- uint32_t read_size = (uint32_t)(page_size - read_start);
- if (read_size > size)
- read_size = size;
- memcpy(data, &page->get_raw_payload()[read_start], read_size);
- address += read_size;
- data += read_size;
- size -= read_size;
-
- first_page = false;
- }
-
- if (ppage)
- *ppage = page;
-}
-
-uint8_t *
-DiskBlobManager::read_chunk(Context *context, Page *page, Page **ppage,
- uint64_t address, bool fetch_read_only)
-{
- // get the page-id from this chunk
- uint32_t page_size = m_env->config().page_size_bytes;
- uint64_t pageid = address - (address % page_size);
-
- // is this the current page? if yes then continue working with this page,
- // otherwise fetch the page
- if (page && page->get_address() != pageid)
- page = 0;
-
- if (!page) {
- uint32_t flags = 0;
- if (fetch_read_only)
- flags |= PageManager::kReadOnly;
- page = m_env->page_manager()->fetch(context, pageid, flags);
- if (ppage)
- *ppage = page;
- }
-
- uint32_t read_start = (uint32_t)(address - page->get_address());
- return (&page->get_raw_payload()[read_start]);
-}
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_disk.h b/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_disk.h
deleted file mode 100644
index 7ec8b67d95..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_disk.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef HAM_BLOB_MANAGER_DISK_H
-#define HAM_BLOB_MANAGER_DISK_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "3blob_manager/blob_manager.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-#include "1base/packstart.h"
-
-/*
- * The header of a blob page
- *
- * Contains a fixed length freelist and a couter for the number of free
- * bytes
- */
-HAM_PACK_0 class HAM_PACK_1 PBlobPageHeader
-{
- public:
- void initialize() {
- memset(this, 0, sizeof(PBlobPageHeader));
- }
-
- // Returns a PBlobPageHeader from a page
- static PBlobPageHeader *from_page(Page *page) {
- return (PBlobPageHeader *)&page->get_payload()[0];
- }
-
- // Returns the number of pages which are all managed by this header
- uint32_t get_num_pages() const {
- return (m_num_pages);
- }
-
- // Sets the number of pages which are all managed by this header
- void set_num_pages(uint32_t num_pages) {
- m_num_pages = num_pages;
- }
-
- // Returns the "free bytes" counter
- uint32_t get_free_bytes() const {
- return (m_free_bytes);
- }
-
- // Sets the "free bytes" counter
- void set_free_bytes(uint32_t free_bytes) {
- m_free_bytes = free_bytes;
- }
-
- // Returns the total number of freelist entries
- uint8_t get_freelist_entries() const {
- return (32);
- }
-
- // Returns the offset of freelist entry |i|
- uint32_t get_freelist_offset(uint32_t i) const {
- return (m_freelist[i].offset);
- }
-
- // Sets the offset of freelist entry |i|
- void set_freelist_offset(uint32_t i, uint32_t offset) {
- m_freelist[i].offset = offset;
- }
-
- // Returns the size of freelist entry |i|
- uint32_t get_freelist_size(uint32_t i) const {
- return (m_freelist[i].size);
- }
-
- // Sets the size of freelist entry |i|
- void set_freelist_size(uint32_t i, uint32_t size) {
- m_freelist[i].size = size;
- }
-
- private:
- // Number of "regular" pages for this blob; used for blobs exceeding
- // a page size
- uint32_t m_num_pages;
-
- // Number of free bytes in this page
- uint32_t m_free_bytes;
-
- struct FreelistEntry {
- uint32_t offset;
- uint32_t size;
- };
-
- // The freelist - offset/size pairs in this page
- FreelistEntry m_freelist[32];
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-
-/*
- * A BlobManager for disk-based databases
- */
-class DiskBlobManager : public BlobManager
-{
- enum {
- // Overhead per page
- kPageOverhead = Page::kSizeofPersistentHeader + sizeof(PBlobPageHeader)
- };
-
- public:
- DiskBlobManager(LocalEnvironment *env)
- : BlobManager(env) {
- }
-
- protected:
- // allocate/create a blob
- // returns the blob-id (the start address of the blob header)
- virtual uint64_t do_allocate(Context *context, ham_record_t *record,
- uint32_t flags);
-
- // reads a blob and stores the data in |record|. The pointer |record.data|
- // is backed by the |arena|, unless |HAM_RECORD_USER_ALLOC| is set.
- // flags: either 0 or HAM_DIRECT_ACCESS
- virtual void do_read(Context *context, uint64_t blobid,
- ham_record_t *record, uint32_t flags,
- ByteArray *arena);
-
- // retrieves the size of a blob
- virtual uint64_t do_get_blob_size(Context *context, uint64_t blobid);
-
- // overwrite an existing blob
- //
- // will return an error if the blob does not exist
- // returns the blob-id (the start address of the blob header) in |blobid|
- virtual uint64_t do_overwrite(Context *context, uint64_t old_blobid,
- ham_record_t *record, uint32_t flags);
-
- // delete an existing blob
- virtual void do_erase(Context *context, uint64_t blobid,
- Page *page = 0, uint32_t flags = 0);
-
- private:
- friend class DuplicateManager;
- friend struct BlobManagerFixture;
-
- // write a series of data chunks to storage at file offset 'addr'.
- //
- // The chunks are assumed to be stored in sequential order, adjacent
- // to each other, i.e. as one long data strip.
- void write_chunks(Context *context, Page *page, uint64_t addr,
- uint8_t **chunk_data, uint32_t *chunk_size,
- uint32_t chunks);
-
- // Same as above, but for reading chunks from the file. The data
- // is copied to |data|.
- void copy_chunk(Context *context, Page *page, Page **fpage,
- uint64_t addr, uint8_t *data, uint32_t size,
- bool fetch_read_only);
-
- // Same as |copy_chunk|, but does not copy the data
- uint8_t *read_chunk(Context *context, Page *page, Page **fpage,
- uint64_t addr, bool fetch_read_only);
-
- // adds a free chunk to the freelist
- void add_to_freelist(PBlobPageHeader *header, uint32_t offset,
- uint32_t size);
-
- // searches the freelist for a free chunk; if available, returns |true|
- // and stores the offset in |poffset|.
- bool alloc_from_freelist(PBlobPageHeader *header, uint32_t size,
- uint64_t *poffset);
-
- // verifies the integrity of the freelist
- bool check_integrity(PBlobPageHeader *header) const;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BLOB_MANAGER_DISK_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_factory.h b/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_factory.h
deleted file mode 100644
index 129849c7ad..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_factory.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef HAM_BLOB_MANAGER_FACTORY_H
-#define HAM_BLOB_MANAGER_FACTORY_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "3blob_manager/blob_manager_disk.h"
-#include "3blob_manager/blob_manager_inmem.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct BlobManagerFactory {
- // creates a new BlobManager instance depending on the flags
- static BlobManager *create(LocalEnvironment *env, uint32_t flags) {
- if (flags & HAM_IN_MEMORY)
- return (new InMemoryBlobManager(env));
- else
- return (new DiskBlobManager(env));
- }
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BLOB_MANAGER_FACTORY_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_inmem.cc b/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_inmem.cc
deleted file mode 100644
index 1044d815c5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_inmem.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/dynamic_array.h"
-#include "2device/device_inmem.h"
-#include "3blob_manager/blob_manager_inmem.h"
-#include "4db/db_local.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-uint64_t
-InMemoryBlobManager::do_allocate(Context *context, ham_record_t *record,
- uint32_t flags)
-{
- // in-memory-database: the blobid is actually a pointer to the memory
- // buffer, in which the blob (with the blob-header) is stored
- uint8_t *p = (uint8_t *)m_env->device()->alloc(record->size
- + sizeof(PBlobHeader));
-
- // initialize the header
- PBlobHeader *blob_header = (PBlobHeader *)p;
- memset(blob_header, 0, sizeof(*blob_header));
- blob_header->set_self((uint64_t)PTR_TO_U64(p));
- blob_header->set_alloc_size(record->size + sizeof(PBlobHeader));
- blob_header->set_size(record->size);
-
- // do we have gaps? if yes, fill them with zeroes
- if (flags & HAM_PARTIAL) {
- uint8_t *s = p + sizeof(PBlobHeader);
- if (record->partial_offset)
- memset(s, 0, record->partial_offset);
- memcpy(s + record->partial_offset, record->data, record->partial_size);
- if (record->partial_offset + record->partial_size < record->size)
- memset(s + record->partial_offset + record->partial_size, 0,
- record->size - (record->partial_offset + record->partial_size));
- }
- else {
- memcpy(p + sizeof(PBlobHeader), record->data, record->size);
- }
-
- return ((uint64_t)PTR_TO_U64(p));
-}
-
-void
-InMemoryBlobManager::do_read(Context *context, uint64_t blobid,
- ham_record_t *record, uint32_t flags,
- ByteArray *arena)
-{
- // in-memory-database: the blobid is actually a pointer to the memory
- // buffer, in which the blob is stored
- PBlobHeader *blob_header = (PBlobHeader *)U64_TO_PTR(blobid);
- uint8_t *data = (uint8_t *)(U64_TO_PTR(blobid)) + sizeof(PBlobHeader);
-
- // when the database is closing, the header is already deleted
- if (!blob_header) {
- record->size = 0;
- return;
- }
-
- uint32_t blobsize = (uint32_t)blob_header->get_size();
- record->size = blobsize;
-
- if (flags & HAM_PARTIAL) {
- if (record->partial_offset > blobsize) {
- ham_trace(("partial offset is greater than the total record size"));
- throw Exception(HAM_INV_PARAMETER);
- }
- if (record->partial_offset + record->partial_size > blobsize)
- record->partial_size = blobsize = blobsize - record->partial_offset;
- else
- blobsize = record->partial_size;
- }
-
- // empty blob?
- if (!blobsize) {
- record->data = 0;
- record->size = 0;
- }
- else {
- uint8_t *d = data;
- if (flags & HAM_PARTIAL)
- d += record->partial_offset;
-
- if ((flags & HAM_DIRECT_ACCESS)
- && !(record->flags & HAM_RECORD_USER_ALLOC)) {
- record->data = d;
- }
- else {
- // resize buffer if necessary
- if (!(record->flags & HAM_RECORD_USER_ALLOC)) {
- arena->resize(blobsize);
- record->data = arena->get_ptr();
- }
- // and copy the data
- memcpy(record->data, d, blobsize);
- }
- }
-}
-
-uint64_t
-InMemoryBlobManager::do_overwrite(Context *context, uint64_t old_blobid,
- ham_record_t *record, uint32_t flags)
-{
- // free the old blob, allocate a new blob (but if both sizes are equal,
- // just overwrite the data)
- PBlobHeader *phdr = (PBlobHeader *)U64_TO_PTR(old_blobid);
-
- if (phdr->get_size() == record->size) {
- uint8_t *p = (uint8_t *)phdr;
- if (flags & HAM_PARTIAL) {
- memmove(p + sizeof(PBlobHeader) + record->partial_offset,
- record->data, record->partial_size);
- }
- else {
- memmove(p + sizeof(PBlobHeader), record->data, record->size);
- }
- return ((uint64_t)PTR_TO_U64(phdr));
- }
- else {
- uint64_t new_blobid = allocate(context, record, flags);
-
- InMemoryDevice *dev = (InMemoryDevice *)m_env->device();
- dev->release(phdr, (size_t)phdr->get_alloc_size());
- return (new_blobid);
- }
-}
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_inmem.h b/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_inmem.h
deleted file mode 100644
index 3c5b19a9fa..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3blob_manager/blob_manager_inmem.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef HAM_BLOB_MANAGER_INMEM_H
-#define HAM_BLOB_MANAGER_INMEM_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "3blob_manager/blob_manager.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/**
- * A BlobManager for in-memory blobs
- */
-class InMemoryBlobManager : public BlobManager {
- public:
- InMemoryBlobManager(LocalEnvironment *env)
- : BlobManager(env) {
- }
-
- protected:
- // Allocates/create a new blob
- // This function returns the blob-id (the start address of the blob
- // header)
- virtual uint64_t do_allocate(Context *context, ham_record_t *record,
- uint32_t flags);
-
- // Reads a blob and stores the data in |record|
- // |flags|: either 0 or HAM_DIRECT_ACCESS
- virtual void do_read(Context *context, uint64_t blobid,
- ham_record_t *record, uint32_t flags,
- ByteArray *arena);
-
- // Retrieves the size of a blob
- virtual uint64_t do_get_blob_size(Context *context, uint64_t blobid) {
- PBlobHeader *blob_header = (PBlobHeader *)U64_TO_PTR(blobid);
- return ((uint32_t)blob_header->get_size());
- }
-
- // Overwrites an existing blob
- //
- // Will return an error if the blob does not exist. Returns the blob-id
- // (the start address of the blob header)
- virtual uint64_t do_overwrite(Context *context, uint64_t old_blobid,
- ham_record_t *record, uint32_t flags);
-
- // Deletes an existing blob
- virtual void do_erase(Context *context, uint64_t blobid,
- Page *page = 0, uint32_t flags = 0) {
- Memory::release((void *)U64_TO_PTR(blobid));
- }
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BLOB_MANAGER_INMEM_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_check.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_check.cc
deleted file mode 100644
index 73098ce3e1..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_check.cc
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * btree verification
- */
-
-#include "0root/root.h"
-
-#include <set>
-#include <string.h>
-#include <stdio.h>
-#if HAM_DEBUG
-# include <sstream>
-# include <fstream>
-#endif
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "2page/page.h"
-#include "3page_manager/page_manager.h"
-#include "3page_manager/page_manager_test.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_node_proxy.h"
-#include "4db/db.h"
-#include "4env/env.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class BtreeCheckAction
-{
- public:
- // Constructor
- BtreeCheckAction(BtreeIndex *btree, Context *context, uint32_t flags)
- : m_btree(btree), m_context(context), m_flags(flags) {
- }
-
- // This is the main method; it starts the verification.
- void run() {
- Page *page, *parent = 0;
- uint32_t level = 0;
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
-
- ham_assert(m_btree->get_root_address() != 0);
-
- // get the root page of the tree
- page = env->page_manager()->fetch(m_context, m_btree->get_root_address(),
- PageManager::kReadOnly);
-
-#if HAM_DEBUG
- if (m_flags & HAM_PRINT_GRAPH) {
- m_graph << "digraph g {" << std::endl
- << " graph [" << std::endl
- << " rankdir = \"TD\"" << std::endl
- << " ];" << std::endl
- << " node [" << std::endl
- << " fontsize = \"8\"" << std::endl
- << " shape = \"ellipse\"" << std::endl
- << " ];" << std::endl
- << " edge [" << std::endl
- << " ];" << std::endl;
- }
-#endif
-
- // for each level...
- while (page) {
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
- uint64_t ptr_down = node->get_ptr_down();
-
- // verify the page and all its siblings
- verify_level(parent, page, level);
- parent = page;
-
- // follow the pointer to the smallest child
- if (ptr_down)
- page = env->page_manager()->fetch(m_context, ptr_down,
- PageManager::kReadOnly);
- else
- page = 0;
-
- ++level;
- }
-
-#if HAM_DEBUG
- if (m_flags & HAM_PRINT_GRAPH) {
- m_graph << "}" << std::endl;
-
- std::ofstream file;
- file.open("graph.dot");
- file << m_graph.str();
- }
-#endif
- }
-
- private:
- // Verifies a whole level in the tree - start with "page" and traverse
- // the linked list of all the siblings
- void verify_level(Page *parent, Page *page, uint32_t level) {
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
- Page *child, *leftsib = 0;
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
-
- // assert that the parent page's smallest item (item 0) is bigger
- // than the largest item in this page
- if (parent && node->get_left()) {
- int cmp = compare_keys(db, page, 0, node->get_count() - 1);
- if (cmp <= 0) {
- ham_log(("integrity check failed in page 0x%llx: parent item "
- "#0 <= item #%d\n", page->get_address(),
- node->get_count() - 1));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- }
-
- m_children.clear();
-
- while (page) {
- // verify the page
- verify_page(parent, leftsib, page, level);
-
- // follow the right sibling
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
- if (node->get_right())
- child = env->page_manager()->fetch(m_context,
- node->get_right(), PageManager::kReadOnly);
- else
- child = 0;
-
- if (leftsib) {
- BtreeNodeProxy *leftnode = m_btree->get_node_from_page(leftsib);
- ham_assert(leftnode->is_leaf() == node->is_leaf());
- }
-
- leftsib = page;
- page = child;
- }
- }
-
- // Verifies a single page
- void verify_page(Page *parent, Page *leftsib, Page *page, uint32_t level) {
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
-
-#if HAM_DEBUG
- if (m_flags & HAM_PRINT_GRAPH) {
- std::stringstream ss;
- ss << "node" << page->get_address();
- m_graph << " \"" << ss.str() << "\" [" << std::endl
- << " label = \"";
- m_graph << "<fl>L|<fd>D|";
- for (uint32_t i = 0; i < node->get_count(); i++) {
- m_graph << "<f" << i << ">" << i << "|";
- }
- m_graph << "<fr>R\"" << std::endl
- << " shape = \"record\"" << std::endl
- << " ];" << std::endl;
-#if 0
- // edge to the left sibling
- if (node->get_left())
- m_graph << "\"" << ss.str() << "\":fl -> \"node"
- << node->get_left() << "\":fr [" << std::endl
- << " ];" << std::endl;
- // to the right sibling
- if (node->get_right())
- m_graph << " \"" << ss.str() << "\":fr -> \"node"
- << node->get_right() << "\":fl [" << std::endl
- << " ];" << std::endl;
-#endif
- // to ptr_down
- if (node->get_ptr_down())
- m_graph << " \"" << ss.str() << "\":fd -> \"node"
- << node->get_ptr_down() << "\":fd [" << std::endl
- << " ];" << std::endl;
- // to all children
- if (!node->is_leaf()) {
- for (uint32_t i = 0; i < node->get_count(); i++) {
- m_graph << " \"" << ss.str() << "\":f" << i << " -> \"node"
- << node->get_record_id(m_context, i) << "\":fd ["
- << std::endl << " ];" << std::endl;
- }
- }
- }
-#endif
-
- if (node->get_count() == 0) {
- // a rootpage can be empty! check if this page is the rootpage
- if (page->get_address() == m_btree->get_root_address())
- return;
-
- // for internal nodes: ptr_down HAS to be set!
- if (!node->is_leaf() && node->get_ptr_down() == 0) {
- ham_log(("integrity check failed in page 0x%llx: empty page!\n",
- page->get_address()));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- }
-
- // check if the largest item of the left sibling is smaller than
- // the smallest item of this page
- if (leftsib) {
- BtreeNodeProxy *sibnode = m_btree->get_node_from_page(leftsib);
- ham_key_t key1 = {0};
- ham_key_t key2 = {0};
-
- node->check_integrity(m_context);
-
- if (node->get_count() > 0 && sibnode->get_count() > 0) {
- sibnode->get_key(m_context, sibnode->get_count() - 1,
- &m_barray1, &key1);
- node->get_key(m_context, 0, &m_barray2, &key2);
-
- int cmp = node->compare(&key1, &key2);
- if (cmp >= 0) {
- ham_log(("integrity check failed in page 0x%llx: item #0 "
- "< left sibling item #%d\n", page->get_address(),
- sibnode->get_count() - 1));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- }
- }
-
- if (node->get_count() == 1)
- return;
-
- node->check_integrity(m_context);
-
- if (node->get_count() > 0) {
- for (uint32_t i = 0; i < node->get_count() - 1; i++) {
- int cmp = compare_keys(db, page, (uint32_t)i, (uint32_t)(i + 1));
- if (cmp >= 0) {
- ham_log(("integrity check failed in page 0x%llx: item #%d "
- "< item #%d", page->get_address(), i, i + 1));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- }
- }
-
- // internal nodes: make sure that all record IDs are unique
- if (!node->is_leaf()) {
- if (m_children.find(node->get_ptr_down()) != m_children.end()) {
- ham_log(("integrity check failed in page 0x%llx: record of item "
- "-1 is not unique", page->get_address()));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- m_children.insert(node->get_ptr_down());
-
- for (uint32_t i = 0; i < node->get_count(); i++) {
- uint64_t child_id = node->get_record_id(m_context, i);
- if (m_children.find(child_id) != m_children.end()) {
- ham_log(("integrity check failed in page 0x%llx: record of item "
- "#%d is not unique", page->get_address(), i));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- PageManagerTest test = env->page_manager()->test();
- if (test.is_page_free(child_id)) {
- ham_log(("integrity check failed in page 0x%llx: record of item "
- "#%d is in freelist", page->get_address(), i));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- m_children.insert(child_id);
- }
- }
- }
-
- int compare_keys(LocalDatabase *db, Page *page, int lhs, int rhs) {
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
- ham_key_t key1 = {0};
- ham_key_t key2 = {0};
-
- node->get_key(m_context, lhs, &m_barray1, &key1);
- node->get_key(m_context, rhs, &m_barray2, &key2);
-
- return (node->compare(&key1, &key2));
- }
-
- // The BtreeIndex on which we operate
- BtreeIndex *m_btree;
-
- // The current Context
- Context *m_context;
-
- // The flags as specified when calling ham_db_check_integrity
- uint32_t m_flags;
-
- // ByteArrays to avoid frequent memory allocations
- ByteArray m_barray1;
- ByteArray m_barray2;
-
- // For checking uniqueness of record IDs on an internal level
- std::set<uint64_t> m_children;
-
-#if HAM_DEBUG
- // For printing the graph
- std::ostringstream m_graph;
-#endif
-};
-
-void
-BtreeIndex::check_integrity(Context *context, uint32_t flags)
-{
- BtreeCheckAction bta(this, context, flags);
- bta.run();
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_cursor.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_cursor.cc
deleted file mode 100644
index b66b58c645..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_cursor.cc
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "2page/page.h"
-#include "3page_manager/page_manager.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_cursor.h"
-#include "3btree/btree_node_proxy.h"
-#include "4cursor/cursor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-BtreeCursor::BtreeCursor(Cursor *parent)
- : m_parent(parent), m_state(0), m_duplicate_index(0),
- m_coupled_page(0), m_coupled_index(0), m_next_in_page(0),
- m_previous_in_page(0)
-{
- memset(&m_uncoupled_key, 0, sizeof(m_uncoupled_key));
- m_btree = parent->get_db()->btree_index();
-}
-
-void
-BtreeCursor::set_to_nil()
-{
- // uncoupled cursor: free the cached pointer
- if (m_state == kStateUncoupled)
- memset(&m_uncoupled_key, 0, sizeof(m_uncoupled_key));
- // coupled cursor: remove from page
- else if (m_state == kStateCoupled)
- remove_cursor_from_page(m_coupled_page);
-
- m_state = BtreeCursor::kStateNil;
- m_duplicate_index = 0;
-}
-
-void
-BtreeCursor::uncouple_from_page(Context *context)
-{
- if (m_state == kStateUncoupled || m_state == kStateNil)
- return;
-
- ham_assert(m_coupled_page != 0);
-
- // get the btree-entry of this key
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
- ham_assert(node->is_leaf());
- node->get_key(context, m_coupled_index, &m_uncoupled_arena, &m_uncoupled_key);
-
- // uncouple the page
- remove_cursor_from_page(m_coupled_page);
-
- // set the state and the uncoupled key
- m_state = BtreeCursor::kStateUncoupled;
-}
-
-void
-BtreeCursor::clone(BtreeCursor *other)
-{
- m_duplicate_index = other->m_duplicate_index;
-
- // if the old cursor is coupled: couple the new cursor, too
- if (other->m_state == kStateCoupled) {
- couple_to_page(other->m_coupled_page, other->m_coupled_index);
- }
- // otherwise, if the src cursor is uncoupled: copy the key
- else if (other->m_state == kStateUncoupled) {
- memset(&m_uncoupled_key, 0, sizeof(m_uncoupled_key));
-
- m_uncoupled_arena.copy(other->m_uncoupled_arena.get_ptr(),
- other->m_uncoupled_arena.get_size());
- m_uncoupled_key.data = m_uncoupled_arena.get_ptr();
- m_uncoupled_key.size = m_uncoupled_arena.get_size();
- m_state = kStateUncoupled;
- }
- else {
- set_to_nil();
- }
-}
-
-void
-BtreeCursor::overwrite(Context *context, ham_record_t *record, uint32_t flags)
-{
- // uncoupled cursor: couple it
- if (m_state == kStateUncoupled)
- couple(context);
- else if (m_state != kStateCoupled)
- throw Exception(HAM_CURSOR_IS_NIL);
-
- // copy the key flags, and remove all flags concerning the key size
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
- node->set_record(context, m_coupled_index, record, m_duplicate_index,
- flags | HAM_OVERWRITE, 0);
-
- m_coupled_page->set_dirty(true);
-}
-
-ham_status_t
-BtreeCursor::move(Context *context, ham_key_t *key, ByteArray *key_arena,
- ham_record_t *record, ByteArray *record_arena, uint32_t flags)
-{
- ham_status_t st = 0;
-
- if (flags & HAM_CURSOR_FIRST)
- st = move_first(context, flags);
- else if (flags & HAM_CURSOR_LAST)
- st = move_last(context, flags);
- else if (flags & HAM_CURSOR_NEXT)
- st = move_next(context, flags);
- else if (flags & HAM_CURSOR_PREVIOUS)
- st = move_previous(context, flags);
- // no move, but cursor is nil? return error
- else if (m_state == kStateNil) {
- if (key || record)
- return (HAM_CURSOR_IS_NIL);
- else
- return (0);
- }
- // no move, but cursor is not coupled? couple it
- else if (m_state == kStateUncoupled)
- couple(context);
-
- if (st)
- return (st);
-
- ham_assert(m_state == kStateCoupled);
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
- ham_assert(node->is_leaf());
-
- if (key)
- node->get_key(context, m_coupled_index, key_arena, key);
-
- if (record)
- node->get_record(context, m_coupled_index, record_arena, record,
- flags, m_duplicate_index);
-
- return (0);
-}
-
-ham_status_t
-BtreeCursor::find(Context *context, ham_key_t *key, ByteArray *key_arena,
- ham_record_t *record, ByteArray *record_arena, uint32_t flags)
-{
- set_to_nil();
-
- return (m_btree->find(context, m_parent, key, key_arena, record,
- record_arena, flags));
-}
-
-bool
-BtreeCursor::points_to(Context *context, Page *page, int slot)
-{
- if (m_state == kStateUncoupled)
- couple(context);
-
- if (m_state == kStateCoupled)
- return (m_coupled_page == page && m_coupled_index == slot);
-
- return (false);
-}
-
-bool
-BtreeCursor::points_to(Context *context, ham_key_t *key)
-{
- if (m_state == kStateUncoupled) {
- if (m_uncoupled_key.size != key->size)
- return (false);
- return (0 == m_btree->compare_keys(key, &m_uncoupled_key));
- }
-
- if (m_state == kStateCoupled) {
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
- return (node->equals(context, key, m_coupled_index));
- }
-
- ham_assert(!"shouldn't be here");
- return (false);
-}
-
-ham_status_t
-BtreeCursor::move_to_next_page(Context *context)
-{
- LocalEnvironment *env = m_parent->get_db()->lenv();
-
- // uncoupled cursor: couple it
- if (m_state == kStateUncoupled)
- couple(context);
- else if (m_state != kStateCoupled)
- return (HAM_CURSOR_IS_NIL);
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
- // if there is no right sibling then couple the cursor to the right-most
- // key in the last page and return KEY_NOT_FOUND
- if (!node->get_right()) {
- couple_to_page(m_coupled_page, node->get_count() - 1, 0);
- return (HAM_KEY_NOT_FOUND);
- }
-
- Page *page = env->page_manager()->fetch(context, node->get_right(),
- PageManager::kReadOnly);
- couple_to_page(page, 0, 0);
- return (0);
-}
-
-int
-BtreeCursor::get_record_count(Context *context, uint32_t flags)
-{
- // uncoupled cursor: couple it
- if (m_state == kStateUncoupled)
- couple(context);
- else if (m_state != kStateCoupled)
- throw Exception(HAM_CURSOR_IS_NIL);
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
- return (node->get_record_count(context, m_coupled_index));
-}
-
-uint64_t
-BtreeCursor::get_record_size(Context *context)
-{
- // uncoupled cursor: couple it
- if (m_state == kStateUncoupled)
- couple(context);
- else if (m_state != kStateCoupled)
- throw Exception(HAM_CURSOR_IS_NIL);
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
- return (node->get_record_size(context, m_coupled_index, m_duplicate_index));
-}
-
-void
-BtreeCursor::couple(Context *context)
-{
- ham_assert(m_state == kStateUncoupled);
-
- /*
- * Make a 'find' on the cached key; if we succeed, the cursor
- * is automatically coupled. Since |find()| overwrites and modifies
- * the cursor's state, keep a backup and restore it afterwards.
- */
- int duplicate_index = m_duplicate_index;
- ByteArray uncoupled_arena = m_uncoupled_arena;
- ham_key_t uncoupled_key = m_uncoupled_key;
- m_uncoupled_arena = ByteArray();
-
- find(context, &uncoupled_key, 0, 0, 0, 0);
-
- m_duplicate_index = duplicate_index;
- m_uncoupled_key = uncoupled_key;
- m_uncoupled_arena = uncoupled_arena;
- uncoupled_arena.disown(); // do not free when going out of scope
-}
-
-ham_status_t
-BtreeCursor::move_first(Context *context, uint32_t flags)
-{
- LocalDatabase *db = m_parent->get_db();
- LocalEnvironment *env = db->lenv();
-
- // get a NIL cursor
- set_to_nil();
-
- // get the root page
- Page *page = env->page_manager()->fetch(context,
- m_btree->get_root_address(), PageManager::kReadOnly);
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
-
- // traverse down to the leafs
- while (!node->is_leaf()) {
- page = env->page_manager()->fetch(context, node->get_ptr_down(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
- }
-
- // and to the next page that is NOT empty
- while (node->get_count() == 0) {
- if (node->get_right() == 0)
- return (HAM_KEY_NOT_FOUND);
- page = env->page_manager()->fetch(context, node->get_right(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
- }
-
- // couple this cursor to the smallest key in this page
- couple_to_page(page, 0, 0);
-
- return (0);
-}
-
-ham_status_t
-BtreeCursor::move_next(Context *context, uint32_t flags)
-{
- LocalDatabase *db = m_parent->get_db();
- LocalEnvironment *env = db->lenv();
-
- // uncoupled cursor: couple it
- if (m_state == kStateUncoupled)
- couple(context);
- else if (m_state != kStateCoupled)
- return (HAM_CURSOR_IS_NIL);
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
-
- // if this key has duplicates: get the next duplicate; otherwise
- // (and if there's no duplicate): fall through
- if (!(flags & HAM_SKIP_DUPLICATES)) {
- if (m_duplicate_index
- < node->get_record_count(context, m_coupled_index) - 1) {
- m_duplicate_index++;
- return (0);
- }
- }
-
- // don't continue if ONLY_DUPLICATES is set
- if (flags & HAM_ONLY_DUPLICATES)
- return (HAM_KEY_NOT_FOUND);
-
- // if the index+1 is still in the coupled page, just increment the index
- if (m_coupled_index + 1 < (int)node->get_count()) {
- couple_to_page(m_coupled_page, m_coupled_index + 1, 0);
- return (0);
- }
-
- // otherwise uncouple the cursor and load the right sibling page
- if (!node->get_right())
- return (HAM_KEY_NOT_FOUND);
-
- Page *page = env->page_manager()->fetch(context, node->get_right(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
-
- // if the right node is empty then continue searching for the next
- // non-empty page
- while (node->get_count() == 0) {
- if (!node->get_right())
- return (HAM_KEY_NOT_FOUND);
- page = env->page_manager()->fetch(context, node->get_right(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
- }
-
- // couple this cursor to the smallest key in this page
- couple_to_page(page, 0, 0);
-
- return (0);
-}
-
-ham_status_t
-BtreeCursor::move_previous(Context *context, uint32_t flags)
-{
- LocalDatabase *db = m_parent->get_db();
- LocalEnvironment *env = db->lenv();
-
- // uncoupled cursor: couple it
- if (m_state == kStateUncoupled)
- couple(context);
- else if (m_state != kStateCoupled)
- return (HAM_CURSOR_IS_NIL);
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(m_coupled_page);
-
- // if this key has duplicates: get the previous duplicate; otherwise
- // (and if there's no duplicate): fall through
- if (!(flags & HAM_SKIP_DUPLICATES) && m_duplicate_index > 0) {
- m_duplicate_index--;
- return (0);
- }
-
- // don't continue if ONLY_DUPLICATES is set
- if (flags & HAM_ONLY_DUPLICATES)
- return (HAM_KEY_NOT_FOUND);
-
- // if the index-1 is till in the coupled page, just decrement the index
- if (m_coupled_index != 0) {
- couple_to_page(m_coupled_page, m_coupled_index - 1);
- }
- // otherwise load the left sibling page
- else {
- if (!node->get_left())
- return (HAM_KEY_NOT_FOUND);
-
- Page *page = env->page_manager()->fetch(context, node->get_left(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
-
- // if the left node is empty then continue searching for the next
- // non-empty page
- while (node->get_count() == 0) {
- if (!node->get_left())
- return (HAM_KEY_NOT_FOUND);
- page = env->page_manager()->fetch(context, node->get_left(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
- }
-
- // couple this cursor to the highest key in this page
- couple_to_page(page, node->get_count() - 1);
- }
- m_duplicate_index = 0;
-
- // if duplicates are enabled: move to the end of the duplicate-list
- if (!(flags & HAM_SKIP_DUPLICATES))
- m_duplicate_index = node->get_record_count(context, m_coupled_index) - 1;
-
- return (0);
-}
-
-ham_status_t
-BtreeCursor::move_last(Context *context, uint32_t flags)
-{
- LocalDatabase *db = m_parent->get_db();
- LocalEnvironment *env = db->lenv();
-
- // get a NIL cursor
- set_to_nil();
-
- // get the root page
- if (!m_btree->get_root_address())
- return (HAM_KEY_NOT_FOUND);
-
- Page *page = env->page_manager()->fetch(context,
- m_btree->get_root_address(), PageManager::kReadOnly);
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
-
- // traverse down to the leafs
- while (!node->is_leaf()) {
- if (node->get_count() == 0)
- page = env->page_manager()->fetch(context, node->get_ptr_down(),
- PageManager::kReadOnly);
- else
- page = env->page_manager()->fetch(context,
- node->get_record_id(context, node->get_count() - 1),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
- }
-
- // and to the last page that is NOT empty
- while (node->get_count() == 0) {
- if (node->get_left() == 0)
- return (HAM_KEY_NOT_FOUND);
- page = env->page_manager()->fetch(context, node->get_left(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
- }
-
- // couple this cursor to the largest key in this page
- couple_to_page(page, node->get_count() - 1, 0);
-
- // if duplicates are enabled: move to the end of the duplicate-list
- if (!(flags & HAM_SKIP_DUPLICATES))
- m_duplicate_index = node->get_record_count(context, m_coupled_index) - 1;
-
- return (0);
-}
-
-void
-BtreeCursor::couple_to_page(Page *page, uint32_t index)
-{
- ham_assert(page != 0);
-
- if (m_state == kStateCoupled && m_coupled_page != page)
- remove_cursor_from_page(m_coupled_page);
-
- m_coupled_index = index;
- m_state = kStateCoupled;
- if (m_coupled_page == page)
- return;
-
- m_coupled_page = page;
-
- // add the cursor to the page
- if (page->cursor_list()) {
- m_next_in_page = page->cursor_list();
- m_previous_in_page = 0;
- page->cursor_list()->m_previous_in_page = this;
- }
- page->set_cursor_list(this);
-}
-
-void
-BtreeCursor::remove_cursor_from_page(Page *page)
-{
- BtreeCursor *n, *p;
-
- if (this == page->cursor_list()) {
- n = m_next_in_page;
- if (n)
- n->m_previous_in_page = 0;
- page->set_cursor_list(n);
- }
- else {
- n = m_next_in_page;
- p = m_previous_in_page;
- if (p)
- p->m_next_in_page = n;
- if (n)
- n->m_previous_in_page = p;
- }
-
- m_coupled_page = 0;
- m_next_in_page = 0;
- m_previous_in_page = 0;
-}
-
-void
-BtreeCursor::uncouple_all_cursors(Context *context, Page *page, int start)
-{
- bool skipped = false;
- Cursor *cursors = page->cursor_list()
- ? page->cursor_list()->get_parent()
- : 0;
-
- while (cursors) {
- BtreeCursor *btc = cursors->get_btree_cursor();
- BtreeCursor *next = btc->m_next_in_page;
-
- // ignore all cursors which are already uncoupled or which are
- // coupled to a key in the Transaction
- if (btc->m_state == kStateCoupled) {
- // skip this cursor if its position is < start
- if (btc->m_coupled_index < start) {
- cursors = next ? next->m_parent : 0;
- skipped = true;
- continue;
- }
-
- // otherwise: uncouple the cursor from the page
- btc->uncouple_from_page(context);
- }
-
- cursors = next ? next->m_parent : 0;
- }
-
- if (!skipped)
- page->set_cursor_list(0);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_cursor.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_cursor.h
deleted file mode 100644
index 1754371875..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_cursor.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * btree cursors
- *
- * A Btree-Cursor is an object which is used to traverse a Btree.
- * It is a random access iterator.
- *
- * Btree-Cursors are used in Cursor structures as defined in cursor.h. But
- * some routines use them directly, mostly for performance reasons. Over
- * time these layers will be cleaned up and the separation will be improved.
- *
- * The cursor implementation is very fast. Most of the operations (i.e.
- * move previous/next) will not cause any disk access but are O(1) and
- * in-memory only. That's because a cursor is directly "coupled" to a
- * btree page (Page) that resides in memory. If the page is removed
- * from memory (i.e. because the cache decides that it needs to purge the
- * cache, or if there's a page split) then the cursor is "uncoupled", and a
- * copy of the current key is stored in the cursor. On first access, the
- * cursor is "coupled" again and basically performs a normal lookup of the key.
- *
- * The three states of a BtreeCursor("nil", "coupled", "uncoupled") can be
- * retrieved with the method get_state(), and can be modified with
- * set_to_nil(), couple_to_page() and uncouple_from_page().
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_CURSORS_H
-#define HAM_BTREE_CURSORS_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/dynamic_array.h"
-#include "1base/error.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-class Cursor;
-class BtreeIndex;
-class Page;
-
-//
-// The Cursor structure for a b+tree cursor
-//
-class BtreeCursor
-{
- public:
- enum {
- // Cursor does not point to any key
- kStateNil = 0,
- // Cursor flag: the cursor is coupled
- kStateCoupled = 1,
- // Cursor flag: the cursor is uncoupled
- kStateUncoupled = 2
- };
-
- // Constructor
- BtreeCursor(Cursor *parent = 0);
-
- // Destructor; asserts that the cursor is nil
- ~BtreeCursor() {
- ham_assert(m_state == kStateNil);
- }
-
- // Returns the parent cursor
- // TODO this should be private
- Cursor *get_parent() {
- return (m_parent);
- }
-
- // Clones another BtreeCursor
- void clone(BtreeCursor *other);
-
- // Returns the cursor's state (kStateCoupled, kStateUncoupled, kStateNil)
- uint32_t get_state() const {
- return (m_state);
- }
-
- // Reset's the cursor's state and uninitializes it. After this call
- // the cursor no longer points to any key.
- void set_to_nil();
-
- // Returns the page, index in this page and the duplicate index that this
- // cursor is coupled to. This is used by Btree functions to optimize
- // certain algorithms, i.e. when erasing the current key.
- // Asserts that the cursor is coupled.
- void get_coupled_key(Page **page, int *index = 0,
- int *duplicate_index = 0) const {
- ham_assert(m_state == kStateCoupled);
- if (page)
- *page = m_coupled_page;
- if (index)
- *index = m_coupled_index;
- if (duplicate_index)
- *duplicate_index = m_duplicate_index;
- }
-
- // Returns the uncoupled key of this cursor.
- // Asserts that the cursor is uncoupled.
- ham_key_t *get_uncoupled_key() {
- ham_assert(m_state == kStateUncoupled);
- return (&m_uncoupled_key);
- }
-
- // Couples the cursor to a key directly in a page. Also sets the
- // duplicate index.
- void couple_to_page(Page *page, uint32_t index,
- int duplicate_index) {
- couple_to_page(page, index);
- m_duplicate_index = duplicate_index;
- }
-
- // Returns the duplicate index that this cursor points to.
- int get_duplicate_index() const {
- return (m_duplicate_index);
- }
-
- // Sets the duplicate key we're pointing to
- void set_duplicate_index(int duplicate_index) {
- m_duplicate_index = duplicate_index;
- }
-
- // Uncouples the cursor
- void uncouple_from_page(Context *context);
-
- // Returns true if a cursor points to this btree key
- bool points_to(Context *context, Page *page, int slot);
-
- // Returns true if a cursor points to this external key
- bool points_to(Context *context, ham_key_t *key);
-
- // Moves the btree cursor to the next page
- ham_status_t move_to_next_page(Context *context);
-
- // Positions the cursor on a key and retrieves the record (if |record|
- // is a valid pointer)
- ham_status_t find(Context *context, ham_key_t *key, ByteArray *key_arena,
- ham_record_t *record, ByteArray *record_arena,
- uint32_t flags);
-
- // Moves the cursor to the first, last, next or previous element
- ham_status_t move(Context *context, ham_key_t *key, ByteArray *key_arena,
- ham_record_t *record, ByteArray *record_arena,
- uint32_t flags);
-
- // Returns the number of records of the referenced key
- int get_record_count(Context *context, uint32_t flags);
-
- // Overwrite the record of this cursor
- void overwrite(Context *context, ham_record_t *record, uint32_t flags);
-
- // retrieves the record size of the current record
- uint64_t get_record_size(Context *context);
-
- // Closes the cursor
- void close() {
- set_to_nil();
- }
-
- // Uncouples all cursors from a page
- // This method is called whenever the page is deleted or becomes invalid
- static void uncouple_all_cursors(Context *context, Page *page,
- int start = 0);
-
- private:
- // Sets the key we're pointing to - if the cursor is coupled. Also
- // links the Cursor with |page| (and vice versa).
- void couple_to_page(Page *page, uint32_t index);
-
- // Removes this cursor from a page
- void remove_cursor_from_page(Page *page);
-
- // Couples the cursor to the current page/key
- // Asserts that the cursor is uncoupled. After this call the cursor
- // will be coupled.
- void couple(Context *context);
-
- // move cursor to the very first key
- ham_status_t move_first(Context *context, uint32_t flags);
-
- // move cursor to the very last key
- ham_status_t move_last(Context *context, uint32_t flags);
-
- // move cursor to the next key
- ham_status_t move_next(Context *context, uint32_t flags);
-
- // move cursor to the previous key
- ham_status_t move_previous(Context *context, uint32_t flags);
-
- // the parent cursor
- Cursor *m_parent;
-
- // The BtreeIndex instance
- BtreeIndex *m_btree;
-
- // "coupled" or "uncoupled" states; coupled means that the
- // cursor points into a Page object, which is in
- // memory. "uncoupled" means that the cursor has a copy
- // of the key on which it points (i.e. because the coupled page was
- // flushed to disk and removed from the cache)
- int m_state;
-
- // the id of the duplicate key to which this cursor is coupled
- int m_duplicate_index;
-
- // for coupled cursors: the page we're pointing to
- Page *m_coupled_page;
-
- // ... and the index of the key in that page
- int m_coupled_index;
-
- // for uncoupled cursors: a copy of the key at which we're pointing
- ham_key_t m_uncoupled_key;
-
- // a ByteArray which backs |m_uncoupled_key.data|
- ByteArray m_uncoupled_arena;
-
- // Linked list of cursors which point to the same page
- BtreeCursor *m_next_in_page, *m_previous_in_page;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_CURSORS_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_erase.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_erase.cc
deleted file mode 100644
index 1222cac8fe..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_erase.cc
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3page_manager/page_manager.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_stats.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_update.h"
-#include "3btree/btree_node_proxy.h"
-#include "4db/db.h"
-#include "4cursor/cursor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/*
- * Erases key/value pairs from a btree
- */
-class BtreeEraseAction : public BtreeUpdateAction
-{
- public:
- BtreeEraseAction(BtreeIndex *btree, Context *context, Cursor *cursor,
- ham_key_t *key, int duplicate_index = 0, uint32_t flags = 0)
- : BtreeUpdateAction(btree, context, cursor
- ? cursor->get_btree_cursor()
- : 0, duplicate_index),
- m_key(key), m_flags(flags) {
- if (m_cursor)
- m_duplicate_index = m_cursor->get_duplicate_index() + 1;
- }
-
- // This is the entry point for the erase operation
- ham_status_t run() {
- // Coupled cursor: try to remove the key directly from the page
- if (m_cursor) {
- if (m_cursor->get_state() == BtreeCursor::kStateCoupled) {
- Page *coupled_page;
- int coupled_index;
- m_cursor->get_coupled_key(&coupled_page, &coupled_index);
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(coupled_page);
- ham_assert(node->is_leaf());
-
- // Now try to delete the key. This can require a page split if the
- // KeyList is not "delete-stable" (some compressed lists can
- // grow when keys are deleted).
- try {
- remove_entry(coupled_page, 0, coupled_index);
- }
- catch (Exception &ex) {
- if (ex.code != HAM_LIMITS_REACHED)
- throw ex;
- goto fall_through;
- }
- // TODO if the page is empty then ask the janitor to clean it up
- return (0);
-
-fall_through:
- m_cursor->uncouple_from_page(m_context);
- }
-
- if (m_cursor->get_state() == BtreeCursor::kStateUncoupled)
- m_key = m_cursor->get_uncoupled_key();
- }
-
- return (erase());
- }
-
- private:
- ham_status_t erase() {
- // traverse the tree to the leaf, splitting/merging nodes as required
- Page *parent;
- BtreeStatistics::InsertHints hints;
- Page *page = traverse_tree(m_key, hints, &parent);
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
-
- // we have reached the leaf; search the leaf for the key
- int slot = node->find_exact(m_context, m_key);
- if (slot < 0) {
- m_btree->get_statistics()->erase_failed();
- return (HAM_KEY_NOT_FOUND);
- }
-
- // remove the key from the leaf
- return (remove_entry(page, parent, slot));
- }
-
- ham_status_t remove_entry(Page *page, Page *parent, int slot) {
- LocalDatabase *db = m_btree->get_db();
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
-
- ham_assert(slot >= 0);
- ham_assert(slot < (int)node->get_count());
-
- // delete the record, but only on leaf nodes! internal nodes don't have
- // records; they point to pages instead, and we do not want to delete
- // those.
- bool has_duplicates_left = false;
- if (node->is_leaf()) {
- // only delete a duplicate?
- if (m_duplicate_index > 0)
- node->erase_record(m_context, slot, m_duplicate_index - 1, false,
- &has_duplicates_left);
- else
- node->erase_record(m_context, slot, 0, true, 0);
- }
-
- page->set_dirty(true);
-
- // still got duplicates left? then adjust all cursors
- if (node->is_leaf() && has_duplicates_left && db->cursor_list()) {
- Cursor *cursors = db->cursor_list();
- BtreeCursor *btcur = cursors->get_btree_cursor();
-
- int duplicate_index =
- m_cursor
- ? m_cursor->get_duplicate_index()
- : m_duplicate_index;
-
- while (btcur) {
- BtreeCursor *next = 0;
- if (cursors->get_next()) {
- cursors = cursors->get_next();
- next = cursors->get_btree_cursor();
- }
-
- if (btcur != m_cursor && btcur->points_to(m_context, page, slot)) {
- if (btcur->get_duplicate_index() == duplicate_index)
- btcur->set_to_nil();
- else if (btcur->get_duplicate_index() > duplicate_index)
- btcur->set_duplicate_index(btcur->get_duplicate_index() - 1);
- }
- btcur = next;
- }
- // all cursors were adjusted, the duplicate was deleted. return
- // to caller!
- return (0);
- }
-
- // no duplicates left, the key was deleted; all cursors pointing to
- // this key are set to nil, all cursors pointing to a key in the same
- // page are adjusted, if necessary
- if (node->is_leaf() && !has_duplicates_left && db->cursor_list()) {
- Cursor *cursors = db->cursor_list();
- BtreeCursor *btcur = cursors->get_btree_cursor();
-
- /* 'nil' every cursor which points to the deleted key, and adjust
- * other cursors attached to the same page */
- while (btcur) {
- BtreeCursor *cur = btcur;
- BtreeCursor *next = 0;
- if (cursors->get_next()) {
- cursors = cursors->get_next();
- next = cursors->get_btree_cursor();
- }
- if (btcur != m_cursor && cur->points_to(m_context, page, slot))
- cur->set_to_nil();
- else if (btcur != m_cursor
- && (cur->get_state() & BtreeCursor::kStateCoupled)) {
- Page *coupled_page;
- int coupled_slot;
- cur->get_coupled_key(&coupled_page, &coupled_slot);
- if (coupled_page == page && coupled_slot > slot)
- cur->uncouple_from_page(m_context);
- }
- btcur = next;
- }
- }
-
- if (has_duplicates_left)
- return (0);
-
- // We've reached the leaf; it's still possible that we have to
- // split the page, therefore this case has to be handled
- try {
- node->erase(m_context, slot);
- }
- catch (Exception &ex) {
- if (ex.code != HAM_LIMITS_REACHED)
- throw ex;
-
- // Split the page in the middle. This will invalidate the |node| pointer
- // and the |slot| of the key, therefore restart the whole operation
- BtreeStatistics::InsertHints hints = {0};
- split_page(page, parent, m_key, hints);
- return (erase());
- }
-
- return (0);
- }
-
- // the key that is retrieved
- ham_key_t *m_key;
-
- // flags of ham_db_erase()
- uint32_t m_flags;
-};
-
-ham_status_t
-BtreeIndex::erase(Context *context, Cursor *cursor, ham_key_t *key,
- int duplicate, uint32_t flags)
-{
- context->db = get_db();
-
- BtreeEraseAction bea(this, context, cursor, key, duplicate, flags);
- return (bea.run());
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_find.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_find.cc
deleted file mode 100644
index 05c99b5818..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_find.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * btree searching
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_cursor.h"
-#include "3btree/btree_stats.h"
-#include "3btree/btree_node_proxy.h"
-#include "3page_manager/page_manager.h"
-#include "4cursor/cursor.h"
-#include "4db/db.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class BtreeFindAction
-{
- public:
- BtreeFindAction(BtreeIndex *btree, Context *context, Cursor *cursor,
- ham_key_t *key, ByteArray *key_arena,
- ham_record_t *record, ByteArray *record_arena,
- uint32_t flags)
- : m_btree(btree), m_context(context), m_cursor(0), m_key(key),
- m_record(record), m_flags(flags), m_key_arena(key_arena),
- m_record_arena(record_arena) {
- if (cursor && cursor->get_btree_cursor()->get_parent())
- m_cursor = cursor->get_btree_cursor();
- }
-
- ham_status_t run() {
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
- Page *page = 0;
- int slot = -1;
- BtreeNodeProxy *node = 0;
-
- BtreeStatistics *stats = m_btree->get_statistics();
- BtreeStatistics::FindHints hints = stats->get_find_hints(m_flags);
-
- if (hints.try_fast_track) {
- /*
- * see if we get a sure hit within this btree leaf; if not, revert to
- * regular scan
- *
- * As this is a speed-improvement hint re-using recent material, the
- * page should still sit in the cache, or we're using old info, which
- * should be discarded.
- */
- page = env->page_manager()->fetch(m_context, hints.leaf_page_addr,
- PageManager::kOnlyFromCache
- | PageManager::kReadOnly);
- if (page) {
- node = m_btree->get_node_from_page(page);
- ham_assert(node->is_leaf());
-
- uint32_t approx_match;
- slot = m_btree->find_leaf(m_context, page, m_key, m_flags,
- &approx_match);
-
- /*
- * if we didn't hit a match OR a match at either edge, FAIL.
- * A match at one of the edges is very risky, as this can also
- * signal a match far away from the current node, so we need
- * the full tree traversal then.
- */
- if (approx_match || slot <= 0 || slot >= (int)node->get_count() - 1)
- slot = -1;
-
- /* fall through */
- }
- }
-
- uint32_t approx_match = 0;
-
- if (slot == -1) {
- /* load the root page */
- page = env->page_manager()->fetch(m_context,
- m_btree->get_root_address(), PageManager::kReadOnly);
-
- /* now traverse the root to the leaf nodes till we find a leaf */
- node = m_btree->get_node_from_page(page);
- while (!node->is_leaf()) {
- page = m_btree->find_child(m_context, page, m_key,
- PageManager::kReadOnly, 0);
- if (!page) {
- stats->find_failed();
- return (HAM_KEY_NOT_FOUND);
- }
-
- node = m_btree->get_node_from_page(page);
- }
-
- /* check the leaf page for the key (shortcut w/o approx. matching) */
- if (m_flags == 0) {
- slot = node->find_exact(m_context, m_key);
- if (slot == -1) {
- stats->find_failed();
- return (HAM_KEY_NOT_FOUND);
- }
- }
-
- /* check the leaf page for the key (long path w/ approx. matching),
- * then fall through */
- slot = m_btree->find_leaf(m_context, page, m_key, m_flags,
- &approx_match);
- }
-
- if (slot == -1) {
- // find the left sibling
- if (node->get_left() > 0) {
- page = env->page_manager()->fetch(m_context, node->get_left(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
- slot = node->get_count() - 1;
- approx_match = BtreeKey::kLower;
- }
- }
-
- else if (slot >= (int)node->get_count()) {
- // find the right sibling
- if (node->get_right() > 0) {
- page = env->page_manager()->fetch(m_context, node->get_right(),
- PageManager::kReadOnly);
- node = m_btree->get_node_from_page(page);
- slot = 0;
- approx_match = BtreeKey::kGreater;
- }
- else
- slot = -1;
- }
-
- if (slot < 0) {
- stats->find_failed();
- return (HAM_KEY_NOT_FOUND);
- }
-
- ham_assert(node->is_leaf());
-
- /* set the cursor-position to this key */
- if (m_cursor) {
- m_cursor->couple_to_page(page, slot, 0);
- }
-
- /* approx. match: patch the key flags */
- if (approx_match) {
- ham_key_set_intflags(m_key, approx_match);
- }
-
- /* no need to load the key if we have an exact match, or if KEY_DONT_LOAD
- * is set: */
- if (m_key && approx_match && !(m_flags & Cursor::kSyncDontLoadKey)) {
- node->get_key(m_context, slot, m_key_arena, m_key);
- }
-
- if (m_record) {
- node->get_record(m_context, slot, m_record_arena, m_record, m_flags);
- }
-
- return (0);
- }
-
- private:
- // the current btree
- BtreeIndex *m_btree;
-
- // The caller's Context
- Context *m_context;
-
- // the current cursor
- BtreeCursor *m_cursor;
-
- // the key that is retrieved
- ham_key_t *m_key;
-
- // the record that is retrieved
- ham_record_t *m_record;
-
- // flags of ham_db_find()
- uint32_t m_flags;
-
- // allocator for the key data
- ByteArray *m_key_arena;
-
- // allocator for the record data
- ByteArray *m_record_arena;
-};
-
-ham_status_t
-BtreeIndex::find(Context *context, Cursor *cursor, ham_key_t *key,
- ByteArray *key_arena, ham_record_t *record,
- ByteArray *record_arena, uint32_t flags)
-{
- BtreeFindAction bfa(this, context, cursor, key, key_arena, record,
- record_arena, flags);
- return (bfa.run());
-}
-
-} // namespace hamsterdb
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_flags.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_flags.h
deleted file mode 100644
index e0d77d8ae0..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_flags.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_FLAGS_H
-#define HAM_BTREE_FLAGS_H
-
-#include "0root/root.h"
-
-#include "ham/types.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// A helper class wrapping key-related constants into a common namespace.
-// This class does not contain any logic.
-//
-struct BtreeKey
-{
- // persisted btree key flags; also used in combination with ham_key_t._flags
- enum {
- // key is extended with overflow area
- kExtendedKey = 0x01,
-
- // PRO: key is compressed; the original size is stored in the payload
- kCompressed = 0x08
- };
-
- // flags used with the ham_key_t::_flags (note the underscore - this
- // field is for INTERNAL USE!)
- //
- // Note: these flags should NOT overlap with the persisted flags above!
- //
- // As these flags NEVER will be persisted, they should be located outside
- // the range of a uint16_t, i.e. outside the mask 0x0000ffff.
- enum {
- // Actual key is lower than the requested key
- kLower = 0x00010000,
-
- // Actual key is greater than the requested key
- kGreater = 0x00020000,
-
- // Actual key is an "approximate match"
- kApproximate = (kLower | kGreater)
- };
-};
-
-//
-// A helper class wrapping record-related constants into a common namespace.
-// This class does not contain any logic.
-//
-struct BtreeRecord
-{
- enum {
- // record size < 8; length is encoded at byte[7] of key->ptr
- kBlobSizeTiny = 0x01,
-
- // record size == 8; record is stored in key->ptr
- kBlobSizeSmall = 0x02,
-
- // record size == 0; key->ptr == 0
- kBlobSizeEmpty = 0x04,
-
- // key has duplicates in an overflow area; this is the msb of 1 byte;
- // the lower bits are the counter for the inline duplicate list
- kExtendedDuplicates = 0x80
- };
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_FLAGS_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_base.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_base.h
deleted file mode 100644
index d75d2a7be2..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_base.h
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Base class for btree node implementations
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_IMPL_BASE_H
-#define HAM_BTREE_IMPL_BASE_H
-
-#include "0root/root.h"
-
-#include <sstream>
-#include <iostream>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3btree/btree_node.h"
-#include "3btree/btree_keys_base.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-
-template<typename KeyList, typename RecordList>
-class BaseNodeImpl
-{
- public:
- // Constructor
- BaseNodeImpl(Page *page)
- : m_page(page), m_node(PBtreeNode::from_page(page)),
- m_estimated_capacity(0), m_keys(page->get_db()),
- m_records(page->get_db(), m_node) {
- }
-
- // Returns the estimated page's capacity
- size_t estimate_capacity() const {
- return (m_estimated_capacity);
- }
-
- // Checks this node's integrity
- virtual void check_integrity(Context *context) const {
- }
-
- // Returns a copy of a key and stores it in |dest|
- void get_key(Context *context, int slot, ByteArray *arena,
- ham_key_t *dest) {
- // copy (or assign) the key data
- m_keys.get_key(context, slot, arena, dest, true);
- }
-
- // Returns the record size of a key or one of its duplicates
- uint64_t get_record_size(Context *context, int slot, int duplicate_index) {
- return (m_records.get_record_size(context, slot, duplicate_index));
- }
-
- // Returns the record counter of a key
- int get_record_count(Context *context, int slot) {
- return (m_records.get_record_count(context, slot));
- }
-
- // Returns the full record and stores it in |dest|
- void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags, int duplicate_index) {
- // copy the record data
- m_records.get_record(context, slot, arena, record,
- flags, duplicate_index);
- }
-
- // Updates the record of a key
- void set_record(Context *context, int slot, ham_record_t *record,
- int duplicate_index, uint32_t flags,
- uint32_t *new_duplicate_index) {
- // automatically overwrite an existing key unless this is a
- // duplicate operation
- if ((flags & (HAM_DUPLICATE
- | HAM_DUPLICATE
- | HAM_DUPLICATE_INSERT_BEFORE
- | HAM_DUPLICATE_INSERT_AFTER
- | HAM_DUPLICATE_INSERT_FIRST
- | HAM_DUPLICATE_INSERT_LAST)) == 0)
- flags |= HAM_OVERWRITE;
-
- m_records.set_record(context, slot, duplicate_index, record, flags,
- new_duplicate_index);
- }
-
- // Erases the extended part of a key
- void erase_extended_key(Context *context, int slot) {
- m_keys.erase_extended_key(context, slot);
- }
-
- // Erases the record
- void erase_record(Context *context, int slot, int duplicate_index,
- bool all_duplicates) {
- m_records.erase_record(context, slot, duplicate_index, all_duplicates);
- }
-
- // Erases a key
- void erase(Context *context, int slot) {
- size_t node_count = m_node->get_count();
-
- m_keys.erase(context, node_count, slot);
- m_records.erase(context, node_count, slot);
- }
-
- // Inserts a new key
- //
- // Most KeyLists first calculate the slot of the new key, then insert
- // the key at this slot. Both operations are separate from each other.
- // However, compressed KeyLists can overwrite this behaviour and
- // combine both calls into one to save performance.
- template<typename Cmp>
- PBtreeNode::InsertResult insert(Context *context, ham_key_t *key,
- uint32_t flags, Cmp &comparator) {
- PBtreeNode::InsertResult result(0, 0);
- size_t node_count = m_node->get_count();
-
- if (node_count == 0)
- result.slot = 0;
- else if (flags & PBtreeNode::kInsertPrepend)
- result.slot = 0;
- else if (flags & PBtreeNode::kInsertAppend)
- result.slot = node_count;
- else {
- int cmp;
- result.slot = find_lowerbound_impl(context, key, comparator, &cmp);
-
- /* insert the new key at the beginning? */
- if (result.slot == -1) {
- result.slot = 0;
- ham_assert(cmp != 0);
- }
- /* key exists already */
- else if (cmp == 0) {
- result.status = HAM_DUPLICATE_KEY;
- return (result);
- }
- /* if the new key is > than the slot key: move to the next slot */
- else if (cmp > 0)
- result.slot++;
- }
-
- // Uncouple the cursors.
- //
- // for custom inserts we have to uncouple all cursors, because the
- // KeyList doesn't have access to the cursors in the page. In this
- // case result.slot is 0.
- if ((int)node_count > result.slot)
- BtreeCursor::uncouple_all_cursors(context, m_page, result.slot);
-
- // make space for 1 additional element.
- // only store the key data; flags and record IDs are set by the caller
- result = m_keys.insert(context, node_count, key, flags, comparator,
- result.slot);
- m_records.insert(context, node_count, result.slot);
- return (result);
- }
-
- // Compares two keys using the supplied comparator
- template<typename Cmp>
- int compare(Context *context, const ham_key_t *lhs,
- uint32_t rhs, Cmp &cmp) {
- if (KeyList::kHasSequentialData) {
- return (cmp(lhs->data, lhs->size, m_keys.get_key_data(rhs),
- m_keys.get_key_size(rhs)));
- }
- else {
- ham_key_t tmp = {0};
- m_keys.get_key(context, rhs, &m_arena, &tmp, false);
- return (cmp(lhs->data, lhs->size, tmp.data, tmp.size));
- }
- }
-
- // Searches the node for the key and returns the slot of this key
- template<typename Cmp>
- int find_child(Context *context, ham_key_t *key, Cmp &comparator,
- uint64_t *precord_id, int *pcmp) {
- int slot = find_lowerbound_impl(context, key, comparator, pcmp);
- if (precord_id) {
- if (slot == -1)
- *precord_id = m_node->get_ptr_down();
- else
- *precord_id = m_records.get_record_id(slot);
- }
- return (slot);
- }
-
- // Searches the node for the key and returns the slot of this key
- // - only for exact matches!
- template<typename Cmp>
- int find_exact(Context *context, ham_key_t *key, Cmp &comparator) {
- int cmp = 0;
- int r = find_exact_impl(context, key, comparator, &cmp);
- return (cmp ? -1 : r);
- }
-
- // Splits a node and moves parts of the current node into |other|, starting
- // at the |pivot| slot
- void split(Context *context, BaseNodeImpl<KeyList, RecordList> *other,
- int pivot) {
- size_t node_count = m_node->get_count();
- size_t other_node_count = other->m_node->get_count();
-
- //
- // if a leaf page is split then the pivot element must be inserted in
- // the leaf page AND in the internal node. the internal node update
- // is handled by the caller.
- //
- // in internal nodes the pivot element is only propagated to the
- // parent node. the pivot element is skipped.
- //
- if (m_node->is_leaf()) {
- m_keys.copy_to(pivot, node_count, other->m_keys,
- other_node_count, 0);
- m_records.copy_to(pivot, node_count, other->m_records,
- other_node_count, 0);
- }
- else {
- m_keys.copy_to(pivot + 1, node_count, other->m_keys,
- other_node_count, 0);
- m_records.copy_to(pivot + 1, node_count, other->m_records,
- other_node_count, 0);
- }
- }
-
- // Returns true if the node requires a merge or a shift
- bool requires_merge() const {
- return (m_node->get_count() <= 3);
- }
-
- // Merges this node with the |other| node
- void merge_from(Context *context,
- BaseNodeImpl<KeyList, RecordList> *other) {
- size_t node_count = m_node->get_count();
- size_t other_node_count = other->m_node->get_count();
-
- // shift items from the sibling to this page
- if (other_node_count > 0) {
- other->m_keys.copy_to(0, other_node_count, m_keys,
- node_count, node_count);
- other->m_records.copy_to(0, other_node_count, m_records,
- node_count, node_count);
- }
- }
-
- // Reorganize this node; re-arranges capacities of KeyList and RecordList
- // in order to free space and avoid splits
- bool reorganize(Context *context, const ham_key_t *key) const {
- return (false);
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- metrics->number_of_pages++;
- metrics->number_of_keys += node_count;
-
- BtreeStatistics::update_min_max_avg(&metrics->keys_per_page, node_count);
-
- m_keys.fill_metrics(metrics, node_count);
- m_records.fill_metrics(metrics, node_count);
- }
-
- // Prints a slot to stdout (for debugging)
- void print(Context *context, int slot) {
- std::stringstream ss;
- ss << " ";
- m_keys.print(context, slot, ss);
- ss << " -> ";
- m_records.print(context, slot, ss);
- std::cout << ss.str() << std::endl;
- }
-
- // Returns the record id
- uint64_t get_record_id(Context *context, int slot) const {
- return (m_records.get_record_id(slot));
- }
-
- // Sets the record id
- void set_record_id(Context *context, int slot, uint64_t ptr) {
- m_records.set_record_id(slot, ptr);
- }
-
- // The page we're operating on
- Page *m_page;
-
- // The node we're operating on
- PBtreeNode *m_node;
-
- // Capacity of this node (maximum number of key/record pairs that
- // can be stored)
- size_t m_estimated_capacity;
-
- // for accessing the keys
- KeyList m_keys;
-
- // for accessing the records
- RecordList m_records;
-
- private:
- // Implementation of the find method for lower-bound matches. If there
- // is no exact match then the lower bound is returned, and the compare value
- // is returned in |*pcmp|.
- template<typename Cmp>
- int find_lowerbound_impl(Context *context, const ham_key_t *key,
- Cmp &comparator, int *pcmp) {
- switch ((int)KeyList::kSearchImplementation) {
- case BaseKeyList::kBinaryLinear:
- return (find_impl_binlin(context, key, comparator, pcmp));
- case BaseKeyList::kCustomSearch:
- return (m_keys.find(context, m_node->get_count(), key,
- comparator, pcmp));
- default: // BaseKeyList::kBinarySearch
- return (find_impl_binary(context, key, comparator, pcmp));
- }
- }
-
- // Implementation of the find method for exact matches. Supports a custom
- // search implementation in the KeyList (i.e. for SIMD).
- template<typename Cmp>
- int find_exact_impl(Context *context, const ham_key_t *key,
- Cmp &comparator, int *pcmp) {
- switch ((int)KeyList::kSearchImplementation) {
- case BaseKeyList::kBinaryLinear:
- return (find_impl_binlin(context, key, comparator, pcmp));
- case BaseKeyList::kCustomSearch:
- case BaseKeyList::kCustomExactImplementation:
- return (m_keys.find(context, m_node->get_count(), key,
- comparator, pcmp));
- default: // BaseKeyList::kBinarySearch
- return (find_impl_binary(context, key, comparator, pcmp));
- }
- }
-
- // Binary search
- template<typename Cmp>
- int find_impl_binary(Context *context, const ham_key_t *key,
- Cmp &comparator, int *pcmp) {
- size_t node_count = m_node->get_count();
- ham_assert(node_count > 0);
-
- int i, l = 0, r = (int)node_count;
- int last = node_count + 1;
- int cmp = -1;
-
- /* repeat till we found the key or the remaining range is so small that
- * we rather perform a linear search (which is faster for small ranges) */
- while (r - l > 0) {
- /* get the median item; if it's identical with the "last" item,
- * we've found the slot */
- i = (l + r) / 2;
-
- if (i == last) {
- ham_assert(i >= 0);
- ham_assert(i < (int)node_count);
- *pcmp = 1;
- return (i);
- }
-
- /* compare it against the key */
- cmp = compare(context, key, i, comparator);
-
- /* found it? */
- if (cmp == 0) {
- *pcmp = cmp;
- return (i);
- }
- /* if the key is bigger than the item: search "to the left" */
- else if (cmp < 0) {
- if (r == 0) {
- ham_assert(i == 0);
- *pcmp = cmp;
- return (-1);
- }
- r = i;
- }
- /* otherwise search "to the right" */
- else {
- last = i;
- l = i;
- }
- }
-
- *pcmp = cmp;
- return (-1);
- }
-
- // Binary search combined with linear search
- template<typename Cmp>
- int find_impl_binlin(Context *context, const ham_key_t *key,
- Cmp &comparator, int *pcmp) {
- size_t node_count = m_node->get_count();
- ham_assert(node_count > 0);
-
- int i, l = 0, r = (int)node_count;
- int last = node_count + 1;
- int cmp = -1;
-
- // Run a binary search, but fall back to linear search as soon as
- // the remaining range is too small. Sets threshold to 0 if linear
- // search is disabled for this KeyList.
- int threshold = m_keys.get_linear_search_threshold();
-
- /* repeat till we found the key or the remaining range is so small that
- * we rather perform a linear search (which is faster for small ranges) */
- while (r - l > threshold) {
- /* get the median item; if it's identical with the "last" item,
- * we've found the slot */
- i = (l + r) / 2;
-
- if (i == last) {
- ham_assert(i >= 0);
- ham_assert(i < (int)node_count);
- *pcmp = 1;
- return (i);
- }
-
- /* compare it against the key */
- cmp = compare(context, key, i, comparator);
-
- /* found it? */
- if (cmp == 0) {
- *pcmp = cmp;
- return (i);
- }
- /* if the key is bigger than the item: search "to the left" */
- else if (cmp < 0) {
- if (r == 0) {
- ham_assert(i == 0);
- *pcmp = cmp;
- return (-1);
- }
- r = i;
- }
- /* otherwise search "to the right" */
- else {
- last = i;
- l = i;
- }
- }
-
- // still here? then perform a linear search for the remaining range
- ham_assert(r - l <= threshold);
- return (m_keys.linear_search(l, r - l, key, comparator, pcmp));
- }
-
- // A memory arena for various tasks
- ByteArray m_arena;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_IMPL_BASE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_default.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_default.h
deleted file mode 100644
index 0e7e5618cc..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_default.h
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Btree node layout for variable length keys/records and/or duplicates
- * ====================================================================
- *
- * This is the default hamsterdb layout. It is chosen for
- * 1. variable length keys (with or without duplicates)
- * 2. fixed length keys with duplicates
- *
- * Like the PAX layout implemented in btree_impl_pax.h, the layout implemented
- * here stores key data and records separated from each other. This layout is
- * more complex, because it is capable of resizing the KeyList and RecordList
- * if the node becomes full.
- *
- * The flat memory layout looks like this:
- *
- * |Idx1|Idx2|...|Idxn|F1|F2|...|Fn|...(space)...|Key1|Key2|...|Keyn|
- *
- * ... where Idx<n> are the indices (of slot <n>)
- * where F<n> are freelist entries
- * where Key<n> is the key data of slot <n>.
- *
- * In addition, the first few bytes in the node store the following
- * information:
- * 0 (4 bytes): total capacity of index keys (used keys + freelist)
- * 4 (4 bytes): number of used freelist entries
- * 8 (4 bytes): offset for the next key at the end of the page
- *
- * In total, |capacity| contains the number of maximum keys (and index
- * entries) that can be stored in the node. The number of used index keys
- * is in |m_node->get_count()|. The number of used freelist entries is
- * returned by |get_freelist_count()|. The freelist indices start directly
- * after the key indices. The key space (with key data and records) starts at
- * N * capacity, where |N| is the size of an index entry (the size depends
- * on the actual btree configuration, i.e. whether key size is fixed,
- * duplicates are used etc).
- *
- * If records have fixed length then all records of a key (with duplicates)
- * are stored next to each other. If they have variable length then each of
- * these records is stored with 1 byte for flags:
- * Rec1|F1|Rec2|F2|...
- * where Recn is an 8 bytes record-ID (offset in the file) OR inline record,
- * and F1 is 1 byte for flags (kBlobSizeSmall etc).
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_IMPL_DEFAULT_H
-#define HAM_BTREE_IMPL_DEFAULT_H
-
-#include "0root/root.h"
-
-#include <algorithm>
-#include <iostream>
-#include <vector>
-#include <map>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_impl_base.h"
-#include "3btree/btree_node.h"
-#include "3btree/btree_visitor.h"
-#include "4env/env_local.h"
-#include "4db/db_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// A BtreeNodeProxy layout which can handle...
-//
-// 1. fixed length keys w/ duplicates
-// 2. variable length keys w/ duplicates
-// 3. variable length keys w/o duplicates
-//
-// Fixed length keys are stored sequentially and reuse the layout from pax.
-// Same for the distinct RecordList (if duplicates are disabled).
-//
-template<typename KeyList, typename RecordList>
-class DefaultNodeImpl : public BaseNodeImpl<KeyList, RecordList>
-{
- // C++ does not allow access to members of base classes unless they're
- // explicitly named; this typedef helps to make the code "less" ugly,
- // but it still sucks that i have to use it
- //
- // http://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data
- typedef BaseNodeImpl<KeyList, RecordList> P;
-
- // the type of |this| object
- typedef DefaultNodeImpl<KeyList, RecordList> NodeType;
-
- enum {
- // for capacity
- kPayloadOffset = 4
- };
-
- public:
- // Constructor
- DefaultNodeImpl(Page *page)
- : BaseNodeImpl<KeyList, RecordList>(page) {
- initialize();
- }
-
- // Checks the integrity of this node. Throws an exception if there is a
- // violation.
- virtual void check_integrity(Context *context) const {
- size_t node_count = P::m_node->get_count();
- if (node_count == 0)
- return;
-
- check_index_integrity(context, node_count);
- }
-
- // Iterates all keys, calls the |visitor| on each
- void scan(Context *context, ScanVisitor *visitor, uint32_t start,
- bool distinct) {
-#ifdef HAM_DEBUG
- check_index_integrity(context, P::m_node->get_count());
-#endif
-
- // a distinct scan over fixed-length keys can be moved to the KeyList
- if (KeyList::kSupportsBlockScans && distinct) {
- P::m_keys.scan(context, visitor, start, P::m_node->get_count() - start);
- return;
- }
-
- // otherwise iterate over the keys, call visitor for each key
- ham_key_t key = {0};
- ByteArray arena;
- size_t node_count = P::m_node->get_count() - start;
-
- for (size_t i = start; i < node_count; i++) {
- P::m_keys.get_key(context, i, &arena, &key, false);
- (*visitor)(key.data, key.size, distinct
- ? 1
- : P::get_record_count(context, i));
- }
- }
-
- // Returns the full record and stores it in |dest|
- void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags, int duplicate_index) {
-#ifdef HAM_DEBUG
- check_index_integrity(context, P::m_node->get_count());
-#endif
- P::get_record(context, slot, arena, record, flags, duplicate_index);
- }
-
- // Updates the record of a key
- void set_record(Context *context, int slot, ham_record_t *record,
- int duplicate_index, uint32_t flags,
- uint32_t *new_duplicate_index) {
- P::set_record(context, slot, record, duplicate_index,
- flags, new_duplicate_index);
-#ifdef HAM_DEBUG
- check_index_integrity(context, P::m_node->get_count());
-#endif
- }
-
- // Erases the record
- void erase_record(Context *context, int slot, int duplicate_index,
- bool all_duplicates) {
- P::erase_record(context, slot, duplicate_index, all_duplicates);
-#ifdef HAM_DEBUG
- check_index_integrity(context, P::m_node->get_count());
-#endif
- }
-
- // Erases a key
- void erase(Context *context, int slot) {
- P::erase(context, slot);
-#ifdef HAM_DEBUG
- check_index_integrity(context, P::m_node->get_count() - 1);
-#endif
- }
-
- // Returns true if |key| cannot be inserted because a split is required.
- // This function will try to re-arrange the node in order for the new
- // key to fit in.
- bool requires_split(Context *context, const ham_key_t *key) {
- size_t node_count = P::m_node->get_count();
-
- // the node is empty? that's either because nothing was inserted yet,
- // or because all keys were erased. For the latter case make sure
- // that no garbage remains behind, otherwise it's possible that
- // following inserts can fail
- if (node_count == 0) {
- P::m_records.vacuumize(node_count, true);
- P::m_keys.vacuumize(node_count, true);
- return (false);
- }
-
- bool keys_require_split = P::m_keys.requires_split(node_count, key);
- bool records_require_split = P::m_records.requires_split(node_count);
- if (!keys_require_split && !records_require_split)
- return (false);
-
- // first try to vaccumize the lists without rearranging them
- if (keys_require_split) {
- P::m_keys.vacuumize(node_count, false);
- keys_require_split = P::m_keys.requires_split(node_count, key);
- }
-
- if (records_require_split) {
- P::m_records.vacuumize(node_count, false);
- records_require_split = P::m_records.requires_split(node_count);
- }
-
- if (!keys_require_split && !records_require_split)
- return (false);
-
- // now adjust the ranges and the capacity
- if (reorganize(context, key)) {
-#ifdef HAM_DEBUG
- check_index_integrity(context, node_count);
-#endif
- return (false);
- }
-
-#ifdef HAM_DEBUG
- check_index_integrity(context, node_count);
-#endif
-
- // still here? then there's no way to avoid the split
- BtreeIndex *bi = P::m_page->get_db()->btree_index();
- bi->get_statistics()->set_keylist_range_size(P::m_node->is_leaf(),
- load_range_size());
- bi->get_statistics()->set_keylist_capacities(P::m_node->is_leaf(),
- node_count);
- return (true);
- }
-
- // Splits this node and moves some/half of the keys to |other|
- void split(Context *context, DefaultNodeImpl *other, int pivot) {
- size_t node_count = P::m_node->get_count();
-
-#ifdef HAM_DEBUG
- check_index_integrity(context, node_count);
- ham_assert(other->m_node->get_count() == 0);
-#endif
-
- // make sure that the other node has enough free space
- other->initialize(this);
-
- P::split(context, other, pivot);
-
- P::m_keys.vacuumize(pivot, true);
- P::m_records.vacuumize(pivot, true);
-
-#ifdef HAM_DEBUG
- check_index_integrity(context, pivot);
- if (P::m_node->is_leaf())
- other->check_index_integrity(context, node_count - pivot);
- else
- other->check_index_integrity(context, node_count - pivot - 1);
-#endif
- }
-
- // Merges keys from |other| to this node
- void merge_from(Context *context, DefaultNodeImpl *other) {
- size_t node_count = P::m_node->get_count();
-
- P::m_keys.vacuumize(node_count, true);
- P::m_records.vacuumize(node_count, true);
-
- P::merge_from(context, other);
-
-#ifdef HAM_DEBUG
- check_index_integrity(context, node_count + other->m_node->get_count());
-#endif
- }
-
- // Adjusts the size of both lists; either increases it or decreases
- // it (in order to free up space for variable length data).
- // Returns true if |key| and an additional record can be inserted, or
- // false if not; in this case the caller must perform a split.
- bool reorganize(Context *context, const ham_key_t *key) {
- size_t node_count = P::m_node->get_count();
-
- // One of the lists must be resizable (otherwise they would be managed
- // by the PaxLayout)
- ham_assert(!KeyList::kHasSequentialData
- || !RecordList::kHasSequentialData);
-
- // Retrieve the minimum sizes that both lists require to store their
- // data
- size_t capacity_hint;
- size_t old_key_range_size = load_range_size();
- size_t key_range_size, record_range_size;
- size_t required_key_range, required_record_range;
- size_t usable_size = usable_range_size();
- required_key_range = P::m_keys.get_required_range_size(node_count)
- + P::m_keys.get_full_key_size(key);
- required_record_range = P::m_records.get_required_range_size(node_count)
- + P::m_records.get_full_record_size();
-
- uint8_t *p = P::m_node->get_data();
- p += sizeof(uint32_t);
-
- // no records? then there's no way to change the ranges. but maybe we
- // can increase the capacity
- if (required_record_range == 0) {
- if (required_key_range > usable_size)
- return (false);
- P::m_keys.change_range_size(node_count, p, usable_size,
- node_count + 5);
- return (!P::m_keys.requires_split(node_count, key));
- }
-
- int remainder = usable_size
- - (required_key_range + required_record_range);
- if (remainder < 0)
- return (false);
-
- // Now split the remainder between both lists
- size_t additional_capacity = remainder
- / (P::m_keys.get_full_key_size(0) +
- P::m_records.get_full_record_size());
- if (additional_capacity == 0)
- return (false);
-
- key_range_size = required_key_range + additional_capacity
- * P::m_keys.get_full_key_size(0);
- record_range_size = usable_size - key_range_size;
-
- ham_assert(key_range_size + record_range_size <= usable_size);
-
- // Check if the required record space is large enough, and make sure
- // there is enough room for a new item
- if (key_range_size > usable_size
- || record_range_size > usable_size
- || key_range_size == old_key_range_size
- || key_range_size < required_key_range
- || record_range_size < required_record_range
- || key_range_size + record_range_size > usable_size)
- return (false);
-
- capacity_hint = get_capacity_hint(key_range_size, record_range_size);
-
- // sanity check: make sure that the new capacity would be big
- // enough for all the keys
- if (capacity_hint > 0 && capacity_hint < node_count)
- return (false);
-
- if (capacity_hint == 0) {
- BtreeStatistics *bstats = P::m_page->get_db()->btree_index()->get_statistics();
- capacity_hint = bstats->get_keylist_capacities(P::m_node->is_leaf());
- }
-
- if (capacity_hint < node_count)
- capacity_hint = node_count + 1;
-
- // Get a pointer to the data area and persist the new range size
- // of the KeyList
- store_range_size(key_range_size);
-
- // Now update the lists. If the KeyList grows then start with resizing
- // the RecordList, otherwise the moved KeyList will overwrite the
- // beginning of the RecordList.
- if (key_range_size > old_key_range_size) {
- P::m_records.change_range_size(node_count, p + key_range_size,
- usable_size - key_range_size,
- capacity_hint);
- P::m_keys.change_range_size(node_count, p, key_range_size,
- capacity_hint);
- }
- // And vice versa if the RecordList grows
- else {
- P::m_keys.change_range_size(node_count, p, key_range_size,
- capacity_hint);
- P::m_records.change_range_size(node_count, p + key_range_size,
- usable_size - key_range_size,
- capacity_hint);
- }
-
- // make sure that the page is flushed to disk
- P::m_page->set_dirty(true);
-
-#ifdef HAM_DEBUG
- check_index_integrity(context, node_count);
-#endif
-
- // finally check if the new space is sufficient for the new key
- // TODO this shouldn't be required if the check above is implemented
- // -> change to an assert, then return true
- return (!P::m_records.requires_split(node_count)
- && !P::m_keys.requires_split(node_count, key));
- }
-
- private:
- // Initializes the node
- void initialize(NodeType *other = 0) {
- LocalDatabase *db = P::m_page->get_db();
- size_t usable_size = usable_range_size();
-
- // initialize this page in the same way as |other| was initialized
- if (other) {
- size_t key_range_size = other->load_range_size();
-
- // persist the range size
- store_range_size(key_range_size);
- uint8_t *p = P::m_node->get_data();
- p += sizeof(uint32_t);
-
- // create the KeyList and RecordList
- P::m_keys.create(p, key_range_size);
- P::m_records.create(p + key_range_size,
- usable_size - key_range_size);
- }
- // initialize a new page from scratch
- else if ((P::m_node->get_count() == 0
- && !(db->get_flags() & HAM_READ_ONLY))) {
- size_t key_range_size;
- size_t record_range_size;
-
- // if yes then ask the btree for the default range size (it keeps
- // track of the average range size of older pages).
- BtreeStatistics *bstats = db->btree_index()->get_statistics();
- key_range_size = bstats->get_keylist_range_size(P::m_node->is_leaf());
-
- // no data so far? then come up with a good default
- if (key_range_size == 0) {
- // no records? then assign the full range to the KeyList
- if (P::m_records.get_full_record_size() == 0) {
- key_range_size = usable_size;
- }
- // Otherwise split the range between both lists
- else {
- size_t capacity = usable_size
- / (P::m_keys.get_full_key_size(0) +
- P::m_records.get_full_record_size());
- key_range_size = capacity * P::m_keys.get_full_key_size(0);
- }
- }
-
- record_range_size = usable_size - key_range_size;
-
- ham_assert(key_range_size + record_range_size <= usable_size);
-
- // persist the key range size
- store_range_size(key_range_size);
- uint8_t *p = P::m_node->get_data();
- p += sizeof(uint32_t);
-
- // and create the lists
- P::m_keys.create(p, key_range_size);
- P::m_records.create(p + key_range_size, record_range_size);
-
- P::m_estimated_capacity = key_range_size
- / (size_t)P::m_keys.get_full_key_size();
- }
- // open a page; read initialization parameters from persisted storage
- else {
- size_t key_range_size = load_range_size();
- size_t record_range_size = usable_size - key_range_size;
- uint8_t *p = P::m_node->get_data();
- p += sizeof(uint32_t);
-
- P::m_keys.open(p, key_range_size, P::m_node->get_count());
- P::m_records.open(p + key_range_size, record_range_size,
- P::m_node->get_count());
-
- P::m_estimated_capacity = key_range_size
- / (size_t)P::m_keys.get_full_key_size();
- }
- }
-
- // Try to get a clue about the capacity of the lists; this will help
- // those lists with an UpfrontIndex to better arrange their layout
- size_t get_capacity_hint(size_t key_range_size, size_t record_range_size) {
- if (KeyList::kHasSequentialData)
- return (key_range_size / P::m_keys.get_full_key_size());
- if (RecordList::kHasSequentialData && P::m_records.get_full_record_size())
- return (record_range_size / P::m_records.get_full_record_size());
- return (0);
- }
-
- // Checks the integrity of the key- and record-ranges. Throws an exception
- // if there's a problem.
- void check_index_integrity(Context *context, size_t node_count) const {
- P::m_keys.check_integrity(context, node_count);
- P::m_records.check_integrity(context, node_count);
- }
-
- // Returns the usable page size that can be used for actually
- // storing the data
- size_t usable_range_size() const {
- return (Page::usable_page_size(P::m_page->get_db()->lenv()->config().page_size_bytes)
- - kPayloadOffset
- - PBtreeNode::get_entry_offset()
- - sizeof(uint32_t));
- }
-
- // Persists the KeyList's range size
- void store_range_size(size_t key_range_size) {
- uint8_t *p = P::m_node->get_data();
- *(uint32_t *)p = (uint32_t)key_range_size;
- }
-
- // Load the stored KeyList's range size
- size_t load_range_size() const {
- uint8_t *p = P::m_node->get_data();
- return (*(uint32_t *)p);
- }
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_IMPL_DEFAULT_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_pax.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_pax.h
deleted file mode 100644
index 3a87f1c914..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_impl_pax.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Btree node layout for fixed length keys WITHOUT duplicates
- * ==========================================================
- *
- * This layout supports fixed length keys and fixed length records. It does
- * not support duplicates and extended keys. Keys and records are always
- * inlined, but records can refer to blobs (in this case the "fixed length"
- * record is the 8 byte record ID).
- *
- * Unlike the academic PAX paper, which stored multiple columns in one page,
- * hamsterdb stores only one column (= database) in a page, but keys and
- * records are separated from each other. The keys (flags + key data) are
- * stored in the beginning of the page, the records start somewhere in the
- * middle (the exact start position depends on key size, page size and other
- * parameters).
- *
- * This layout's implementation is relatively simple because the offset
- * of the key data and record data is easy to calculate since all keys
- * and records have the same size.
- *
- * This separation of keys and records allows a more compact layout and a
- * high density of the key data, which better exploits CPU caches and allows
- * very tight loops when searching through the keys.
- *
- * This layout has two incarnations:
- * 1. Fixed length keys, fixed length inline records
- * -> does not require additional flags
- * 2. Fixed length keys, variable length records (8 byte record id)
- * -> requires a 1 byte flag per key
- *
- * The flat memory layout looks like this:
- *
- * |Flag1|Flag2|...|Flagn|...|Key1|Key2|...|Keyn|...|Rec1|Rec2|...|Recn|
- *
- * Flags are optional, as described above.
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_IMPL_PAX_H
-#define HAM_BTREE_IMPL_PAX_H
-
-#include "0root/root.h"
-
-#include <sstream>
-#include <iostream>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_node.h"
-#include "3btree/btree_impl_base.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// A BtreeNodeProxy layout which stores key data, key flags and
-// and the record pointers in a PAX style layout.
-//
-template<typename KeyList, typename RecordList>
-class PaxNodeImpl : public BaseNodeImpl<KeyList, RecordList>
-{
- // C++ does not allow access to members of base classes unless they're
- // explicitly named; this typedef helps to make the code "less" ugly,
- // but it still sucks that i have to use it
- //
- // http://stackoverflow.com/questions/1120833/derived-template-class-access-to-base-class-member-data
- typedef BaseNodeImpl<KeyList, RecordList> P;
-
- public:
- // Constructor
- PaxNodeImpl(Page *page)
- : BaseNodeImpl<KeyList, RecordList>(page) {
- initialize();
- }
-
- // Iterates all keys, calls the |visitor| on each
- void scan(Context *context, ScanVisitor *visitor, uint32_t start,
- bool distinct) {
- P::m_keys.scan(context, visitor, start, P::m_node->get_count() - start);
- }
-
- // Returns true if |key| cannot be inserted because a split is required
- bool requires_split(Context *context, const ham_key_t *key) const {
- return (P::m_node->get_count() >= P::m_estimated_capacity);
- }
-
- private:
- void initialize() {
- uint32_t usable_nodesize
- = Page::usable_page_size(P::m_page->get_db()->lenv()->config().page_size_bytes)
- - PBtreeNode::get_entry_offset();
- size_t ks = P::m_keys.get_full_key_size();
- size_t rs = P::m_records.get_full_record_size();
- size_t capacity = usable_nodesize / (ks + rs);
-
- uint8_t *p = P::m_node->get_data();
- if (P::m_node->get_count() == 0) {
- P::m_keys.create(&p[0], capacity * ks);
- P::m_records.create(&p[capacity * ks], capacity * rs);
- }
- else {
- size_t key_range_size = capacity * ks;
- size_t record_range_size = capacity * rs;
-
- P::m_keys.open(p, key_range_size, P::m_node->get_count());
- P::m_records.open(p + key_range_size, record_range_size,
- P::m_node->get_count());
- }
-
- P::m_estimated_capacity = capacity;
- }
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_IMPL_PAX_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index.cc
deleted file mode 100644
index a934ba441b..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index.cc
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "2page/page.h"
-#include "3page_manager/page_manager.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_index_factory.h"
-#include "3btree/btree_node_proxy.h"
-#include "4db/db.h"
-#include "4env/env.h"
-#include "4cursor/cursor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-uint64_t BtreeIndex::ms_btree_smo_split = 0;
-uint64_t BtreeIndex::ms_btree_smo_merge = 0;
-uint64_t BtreeIndex::ms_btree_smo_shift = 0;
-
-BtreeIndex::BtreeIndex(LocalDatabase *db, PBtreeHeader *btree_header,
- uint32_t flags, uint32_t key_type, uint32_t key_size)
- : m_db(db), m_key_size(0), m_key_type(key_type), m_rec_size(0),
- m_btree_header(btree_header), m_flags(flags), m_root_address(0)
-{
- m_leaf_traits = BtreeIndexFactory::create(db, flags, key_type,
- key_size, true);
- m_internal_traits = BtreeIndexFactory::create(db, flags, key_type,
- key_size, false);
-}
-
-void
-BtreeIndex::create(Context *context, uint16_t key_type, uint32_t key_size,
- uint32_t rec_size)
-{
- ham_assert(key_size != 0);
-
- /* allocate a new root page */
- Page *root = m_db->lenv()->page_manager()->alloc(context,
- Page::kTypeBroot, PageManager::kClearWithZero);
-
- // initialize the new page
- PBtreeNode *node = PBtreeNode::from_page(root);
- node->set_flags(PBtreeNode::kLeafNode);
-
- m_key_size = key_size;
- m_key_type = key_type;
- m_rec_size = rec_size;
- m_root_address = root->get_address();
-
- flush_descriptor(context);
-}
-
-void
-BtreeIndex::open()
-{
- uint64_t rootadd;
- uint16_t key_size;
- uint16_t key_type;
- uint32_t flags;
- uint32_t rec_size;
-
- key_size = m_btree_header->get_key_size();
- key_type = m_btree_header->get_key_type();
- rec_size = m_btree_header->get_record_size();
- rootadd = m_btree_header->get_root_address();
- flags = m_btree_header->get_flags();
-
- ham_assert(key_size > 0);
- ham_assert(rootadd > 0);
-
- m_root_address = rootadd;
- m_key_size = key_size;
- m_key_type = key_type;
- m_flags = flags;
- m_rec_size = rec_size;
-}
-
-void
-BtreeIndex::set_record_compression(Context *context, int algo)
-{
- m_btree_header->set_record_compression(algo);
- flush_descriptor(context);
-}
-
-int
-BtreeIndex::get_record_compression()
-{
- return (m_btree_header->get_record_compression());
-}
-
-void
-BtreeIndex::set_key_compression(Context *context, int algo)
-{
- m_btree_header->set_key_compression(algo);
- flush_descriptor(context);
-}
-
-int
-BtreeIndex::get_key_compression()
-{
- return (m_btree_header->get_key_compression());
-}
-
-void
-BtreeIndex::flush_descriptor(Context *context)
-{
- if (m_db->get_flags() & HAM_READ_ONLY)
- return;
-
- m_btree_header->set_dbname(m_db->name());
- m_btree_header->set_key_size(get_key_size());
- m_btree_header->set_rec_size(get_record_size());
- m_btree_header->set_key_type(get_key_type());
- m_btree_header->set_root_address(get_root_address());
- m_btree_header->set_flags(get_flags());
-}
-
-Page *
-BtreeIndex::find_child(Context *context, Page *page, const ham_key_t *key,
- uint32_t page_manager_flags, int *idxptr)
-{
- BtreeNodeProxy *node = get_node_from_page(page);
-
- // make sure that we're not in a leaf page, and that the
- // page is not empty
- ham_assert(node->get_ptr_down() != 0);
-
- uint64_t record_id;
- int slot = node->find_child(context, (ham_key_t *)key, &record_id);
-
- if (idxptr)
- *idxptr = slot;
-
- return (m_db->lenv()->page_manager()->fetch(context,
- record_id, page_manager_flags));
-}
-
-int
-BtreeIndex::find_leaf(Context *context, Page *page, ham_key_t *key,
- uint32_t flags, uint32_t *approx_match)
-{
- *approx_match = 0;
-
- /* ensure the approx flag is NOT set by anyone yet */
- BtreeNodeProxy *node = get_node_from_page(page);
- if (node->get_count() == 0)
- return (-1);
-
- int cmp;
- int slot = node->find_child(context, key, 0, &cmp);
-
- /* successfull match */
- if (cmp == 0 && (flags == 0 || flags & HAM_FIND_EXACT_MATCH))
- return (slot);
-
- /* approx. matching: smaller key is required */
- if (flags & HAM_FIND_LT_MATCH) {
- if (cmp == 0 && (flags & HAM_FIND_GT_MATCH)) {
- *approx_match = BtreeKey::kLower;
- return (slot + 1);
- }
-
- if (slot < 0 && (flags & HAM_FIND_GT_MATCH)) {
- *approx_match = BtreeKey::kGreater;
- return (0);
- }
- *approx_match = BtreeKey::kLower;
- if (cmp <= 0)
- return (slot - 1);
- return (slot);
- }
-
- /* approx. matching: greater key is required */
- if (flags & HAM_FIND_GT_MATCH) {
- *approx_match = BtreeKey::kGreater;
- return (slot + 1);
- }
-
- return (cmp ? -1 : slot);
-}
-
-//
-// visitor object for estimating / counting the number of keys
-///
-class CalcKeysVisitor : public BtreeVisitor {
- public:
- CalcKeysVisitor(LocalDatabase *db, bool distinct)
- : m_db(db), m_distinct(distinct), m_count(0) {
- }
-
- virtual bool is_read_only() const {
- return (true);
- }
-
- virtual void operator()(Context *context, BtreeNodeProxy *node) {
- size_t node_count = node->get_count();
-
- if (m_distinct
- || (m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS) == 0) {
- m_count += node_count;
- return;
- }
-
- for (size_t i = 0; i < node_count; i++)
- m_count += node->get_record_count(context, i);
- }
-
- uint64_t get_result() const {
- return (m_count);
- }
-
- private:
- LocalDatabase *m_db;
- bool m_distinct;
- uint64_t m_count;
-};
-
-uint64_t
-BtreeIndex::count(Context *context, bool distinct)
-{
- CalcKeysVisitor visitor(m_db, distinct);
- visit_nodes(context, visitor, false);
- return (visitor.get_result());
-}
-
-//
-// visitor object to free all allocated blobs
-///
-class FreeBlobsVisitor : public BtreeVisitor {
- public:
- virtual void operator()(Context *context, BtreeNodeProxy *node) {
- node->remove_all_entries(context);
- }
-
- virtual bool is_read_only() const {
- return (false);
- }
-};
-
-void
-BtreeIndex::release(Context *context)
-{
- FreeBlobsVisitor visitor;
- visit_nodes(context, visitor, true);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index.h
deleted file mode 100644
index f325f7915f..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index.h
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_INDEX_H
-#define HAM_BTREE_INDEX_H
-
-#include "0root/root.h"
-
-#include <algorithm>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/abi.h"
-#include "1base/dynamic_array.h"
-#include "3btree/btree_cursor.h"
-#include "3btree/btree_stats.h"
-#include "3btree/btree_node.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-
-#include "1base/packstart.h"
-
-//
-// The persistent btree index descriptor. This structure manages the
-// persistent btree metadata.
-//
-HAM_PACK_0 class HAM_PACK_1 PBtreeHeader
-{
- public:
- PBtreeHeader() {
- memset(this, 0, sizeof(*this));
- }
-
- // Returns the database name
- uint16_t get_dbname() const {
- return (m_dbname);
- }
-
- // Sets the database name
- void set_dbname(uint16_t name) {
- m_dbname = name;
- }
-
- // Returns the btree's max. key_size
- size_t get_key_size() const {
- return (m_key_size);
- }
-
- // Sets the btree's max. key_size
- void set_key_size(uint16_t key_size) {
- m_key_size = key_size;
- }
-
- // Returns the record size (or 0 if none was specified)
- uint32_t get_record_size() const {
- return (m_rec_size);
- }
-
- // Sets the record size
- void set_rec_size(uint32_t rec_size) {
- m_rec_size = rec_size;
- }
-
- // Returns the btree's key type
- uint16_t get_key_type() const {
- return (m_key_type);
- }
-
- // Sets the btree's key type
- void set_key_type(uint16_t key_type) {
- m_key_type = key_type;
- }
-
- // Returns the address of the btree's root page.
- uint64_t get_root_address() const {
- return (m_root_address);
- }
-
- // Sets the address of the btree's root page.
- void set_root_address(uint64_t root_address) {
- m_root_address = root_address;
- }
-
- // Returns the btree's flags
- uint32_t get_flags() const {
- return (m_flags);
- }
-
- // Sets the btree's flags
- void set_flags(uint32_t flags) {
- m_flags = flags;
- }
-
- // PRO: Returns the record compression
- uint8_t get_record_compression() const {
- return (m_compression >> 4);
- }
-
- // PRO: Sets the record compression
- void set_record_compression(int algorithm) {
- m_compression |= algorithm << 4;
- }
-
- // PRO: Returns the key compression
- uint8_t get_key_compression() const {
- return (m_compression & 0xf);
- }
-
- // PRO: Sets the key compression
- void set_key_compression(int algorithm) {
- m_compression |= algorithm & 0xf;
- }
-
- private:
- // address of the root-page
- uint64_t m_root_address;
-
- // flags for this database
- uint32_t m_flags;
-
- // The name of the database
- uint16_t m_dbname;
-
- // key size used in the pages
- uint16_t m_key_size;
-
- // key type
- uint16_t m_key_type;
-
- // PRO: for storing key and record compression algorithm */
- uint8_t m_compression;
-
- // reserved
- uint8_t m_reserved1;
-
- // the record size
- uint32_t m_rec_size;
-
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-struct Context;
-class LocalDatabase;
-class BtreeNodeProxy;
-struct PDupeEntry;
-struct BtreeVisitor;
-
-//
-// Abstract base class, overwritten by a templated version
-//
-class BtreeIndexTraits
-{
- public:
- // virtual destructor
- virtual ~BtreeIndexTraits() { }
-
- // Compares two keys
- // Returns -1, 0, +1 or higher positive values are the result of a
- // successful key comparison (0 if both keys match, -1 when
- // LHS < RHS key, +1 when LHS > RHS key).
- virtual int compare_keys(LocalDatabase *db, ham_key_t *lhs,
- ham_key_t *rhs) const = 0;
-
- // Returns the class name (for testing)
- virtual std::string test_get_classname() const = 0;
-
- // Implementation of get_node_from_page()
- virtual BtreeNodeProxy *get_node_from_page_impl(Page *page) const = 0;
-};
-
-//
-// The Btree. Derived by BtreeIndexImpl, which uses template policies to
-// define the btree node layout.
-//
-class BtreeIndex
-{
- public:
- enum {
- // for get_node_from_page(): Page is a leaf
- kLeafPage = 1,
-
- // for get_node_from_page(): Page is an internal node
- kInternalPage = 2
- };
-
- // Constructor; creates and initializes a new btree
- BtreeIndex(LocalDatabase *db, PBtreeHeader *btree_header,
- uint32_t flags, uint32_t key_type, uint32_t key_size);
-
- ~BtreeIndex() {
- delete m_leaf_traits;
- m_leaf_traits = 0;
- delete m_internal_traits;
- m_internal_traits = 0;
- }
-
- // Returns the database pointer
- LocalDatabase *get_db() {
- return (m_db);
- }
-
- // Returns the database pointer
- LocalDatabase *get_db() const {
- return (m_db);
- }
-
- // Returns the internal key size
- size_t get_key_size() const {
- return (m_key_size);
- }
-
- // Returns the record size
- size_t get_record_size() const {
- return (m_rec_size);
- }
-
- // Returns the internal key type
- uint16_t get_key_type() const {
- return (m_key_type);
- }
-
- // Returns the address of the root page
- uint64_t get_root_address() const {
- return (m_root_address);
- }
-
- // Returns the btree flags
- uint32_t get_flags() const {
- return (m_flags);
- }
-
- // Creates and initializes the btree
- //
- // This function is called after the ham_db_t structure was allocated
- // and the file was opened
- void create(Context *context, uint16_t key_type, uint32_t key_size,
- uint32_t rec_size);
-
- // Opens and initializes the btree
- //
- // This function is called after the ham_db_t structure was allocated
- // and the file was opened
- void open();
-
- // Sets the record compression algorithm
- void set_record_compression(Context *context, int algo);
-
- // Returns the record compression algorithm
- int get_record_compression();
-
- // Sets the key compression algorithm
- void set_key_compression(Context *context, int algo);
-
- // Returns the key compression algorithm
- int get_key_compression();
-
- // Lookup a key in the index (ham_db_find)
- ham_status_t find(Context *context, Cursor *cursor, ham_key_t *key,
- ByteArray *key_arena, ham_record_t *record,
- ByteArray *record_arena, uint32_t flags);
-
- // Inserts (or updates) a key/record in the index (ham_db_insert)
- ham_status_t insert(Context *context, Cursor *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
- // Erases a key/record from the index (ham_db_erase).
- // If |duplicate_index| is 0 then all duplicates are erased, otherwise only
- // the specified duplicate is erased.
- ham_status_t erase(Context *context, Cursor *cursor, ham_key_t *key,
- int duplicate_index, uint32_t flags);
-
- // Iterates over the whole index and calls |visitor| on every node
- void visit_nodes(Context *context, BtreeVisitor &visitor,
- bool visit_internal_nodes);
-
- // Checks the integrity of the btree (ham_db_check_integrity)
- void check_integrity(Context *context, uint32_t flags);
-
- // Counts the keys in the btree
- uint64_t count(Context *context, bool distinct);
-
- // Erases all records, overflow areas, extended keys etc from the index;
- // used to avoid memory leaks when closing in-memory Databases and to
- // clean up when deleting on-disk Databases.
- void release(Context *context);
-
- // Compares two keys
- // Returns -1, 0, +1 or higher positive values are the result of a
- // successful key comparison (0 if both keys match, -1 when
- // LHS < RHS key, +1 when LHS > RHS key).
- int compare_keys(ham_key_t *lhs, ham_key_t *rhs) const {
- return (m_leaf_traits->compare_keys(m_db, lhs, rhs));
- }
-
- // Returns a BtreeNodeProxy for a Page
- BtreeNodeProxy *get_node_from_page(Page *page) {
- if (page->get_node_proxy())
- return (page->get_node_proxy());
-
- BtreeNodeProxy *proxy;
- PBtreeNode *node = PBtreeNode::from_page(page);
- if (node->is_leaf())
- proxy = get_leaf_node_from_page_impl(page);
- else
- proxy = get_internal_node_from_page_impl(page);
-
- page->set_node_proxy(proxy);
- return (proxy);
- }
-
- // Returns the usage metrics
- static void fill_metrics(ham_env_metrics_t *metrics) {
- metrics->btree_smo_split = ms_btree_smo_split;
- metrics->btree_smo_merge = ms_btree_smo_merge;
- metrics->extended_keys = Globals::ms_extended_keys;
- metrics->extended_duptables = Globals::ms_extended_duptables;
- metrics->key_bytes_before_compression
- = Globals::ms_bytes_before_compression;
- metrics->key_bytes_after_compression
- = Globals::ms_bytes_after_compression;
- }
-
- // Returns the btree usage statistics
- BtreeStatistics *get_statistics() {
- return (&m_statistics);
- }
-
- // Returns the class name (for testing)
- std::string test_get_classname() const {
- return (m_leaf_traits->test_get_classname());
- }
-
- private:
- friend class BtreeUpdateAction;
- friend class BtreeCheckAction;
- friend class BtreeEnumAction;
- friend class BtreeEraseAction;
- friend class BtreeFindAction;
- friend class BtreeInsertAction;
- friend class BtreeCursor;
- friend struct MiscFixture;
- friend struct BtreeKeyFixture;
- friend struct BtreeCursorFixture;
- friend struct DbFixture;
- friend struct DuplicateFixture;
-
- // Implementation of get_node_from_page() (for leaf nodes)
- BtreeNodeProxy *get_leaf_node_from_page_impl(Page *page) const {
- return (m_leaf_traits->get_node_from_page_impl(page));
- }
-
- // Implementation of get_node_from_page() (for internal nodes)
- BtreeNodeProxy *get_internal_node_from_page_impl(Page *page) const {
- return (m_internal_traits->get_node_from_page_impl(page));
- }
-
- // Sets the address of the root page
- void set_root_address(Context *context, uint64_t address) {
- m_root_address = address;
- flush_descriptor(context);
- }
-
- // Flushes the PBtreeHeader to the Environment's header page
- void flush_descriptor(Context *context);
-
- // Searches |parent| page for key |key| and returns the child
- // page in |child|.
- //
- // |page_manager_flags| are forwarded to PageManager::fetch.
- //
- // if |idxptr| is a valid pointer then it will return the anchor index
- // of the loaded page.
- Page *find_child(Context *context, Page *parent, const ham_key_t *key,
- uint32_t page_manager_flags, int *idxptr);
-
- // Searches a leaf node for a key.
- //
- // !!!
- // only works with leaf nodes!!
- //
- // Returns the index of the key, or -1 if the key was not found, or
- // another negative status code value when an unexpected error occurred.
- int find_leaf(Context *context, Page *page, ham_key_t *key, uint32_t flags,
- uint32_t *approx_match);
-
- // pointer to the database object
- LocalDatabase *m_db;
-
- // the Traits class wrapping the template parameters (factory for
- // leaf nodes)
- BtreeIndexTraits *m_leaf_traits;
-
- // the Traits class wrapping the template parameters (factory for
- // internal nodes)
- BtreeIndexTraits *m_internal_traits;
-
- // the key_size of this btree index
- uint16_t m_key_size;
-
- // the key_type of this btree index
- uint16_t m_key_type;
-
- // the record size (or 0 if none was specified)
- uint32_t m_rec_size;
-
- // the index of the PBtreeHeader in the Environment's header page
- PBtreeHeader *m_btree_header;
-
- // the persistent flags of this btree index
- uint32_t m_flags;
-
- // address of the root-page
- uint64_t m_root_address;
-
- // the btree statistics
- BtreeStatistics m_statistics;
-
- // usage metrics - number of page splits
- static uint64_t ms_btree_smo_split;
-
- // usage metrics - number of page merges
- static uint64_t ms_btree_smo_merge;
-
- // usage metrics - number of page shifts
- static uint64_t ms_btree_smo_shift;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_INDEX_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index_factory.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index_factory.h
deleted file mode 100644
index 49d1ea8189..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_index_factory.h
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_INDEX_FACTORY_H
-#define HAM_BTREE_INDEX_FACTORY_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "3btree/btree_index.h"
-#include "3btree/btree_impl_default.h"
-#include "3btree/btree_impl_pax.h"
-#include "3btree/btree_keys_pod.h"
-#include "3btree/btree_keys_binary.h"
-#include "3btree/btree_keys_varlen.h"
-#include "3btree/btree_records_default.h"
-#include "3btree/btree_records_inline.h"
-#include "3btree/btree_records_internal.h"
-#include "3btree/btree_records_duplicate.h"
-#include "3btree/btree_node_proxy.h"
-#include "4db/db_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// A specialied Traits class using template parameters
-//
-template<class NodeLayout, class Comparator>
-class BtreeIndexTraitsImpl : public BtreeIndexTraits
-{
- public:
- // Compares two keys
- // Returns -1, 0, +1 or higher positive values are the result of a
- // successful key comparison (0 if both keys match, -1 when
- // LHS < RHS key, +1 when LHS > RHS key).
- virtual int compare_keys(LocalDatabase *db, ham_key_t *lhs,
- ham_key_t *rhs) const {
- Comparator cmp(db);
- return (cmp(lhs->data, lhs->size, rhs->data, rhs->size));
- }
-
- // Returns the class name (for testing)
- virtual std::string test_get_classname() const {
- return (get_classname(*this));
- }
-
- // Implementation of get_node_from_page()
- virtual BtreeNodeProxy *get_node_from_page_impl(Page *page) const {
- return (new BtreeNodeProxyImpl<NodeLayout, Comparator>(page));
- }
-};
-
-//
-// A BtreeIndexFactory creates BtreeIndexProxy objects depending on the
-// Database configuration
-//
-struct BtreeIndexFactory
-{
- static BtreeIndexTraits *create(LocalDatabase *db, uint32_t flags,
- uint16_t key_type, uint16_t key_size, bool is_leaf) {
- bool inline_records = (is_leaf && (flags & HAM_FORCE_RECORDS_INLINE));
- bool fixed_keys = (key_size != HAM_KEY_SIZE_UNLIMITED);
- bool use_duplicates = (flags & HAM_ENABLE_DUPLICATES) != 0;
-
- switch (key_type) {
- // 8bit unsigned integer
- case HAM_TYPE_UINT8:
- if (use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::PodKeyList<uint8_t>,
- PaxLayout::InternalRecordList>,
- NumericCompare<uint8_t> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<uint8_t>,
- DefLayout::DuplicateInlineRecordList>,
- NumericCompare<uint8_t> >());
- else
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<uint8_t>,
- DefLayout::DuplicateDefaultRecordList>,
- NumericCompare<uint8_t> >());
- }
- else {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::PodKeyList<uint8_t>,
- PaxLayout::InternalRecordList>,
- NumericCompare<uint8_t> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint8_t>,
- PaxLayout::InlineRecordList>,
- NumericCompare<uint8_t> >());
- else
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint8_t>,
- PaxLayout::DefaultRecordList>,
- NumericCompare<uint8_t> >());
- }
- // 16bit unsigned integer
- case HAM_TYPE_UINT16:
- if (use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::PodKeyList<uint16_t>,
- PaxLayout::InternalRecordList>,
- NumericCompare<uint16_t> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<uint16_t>,
- DefLayout::DuplicateInlineRecordList>,
- NumericCompare<uint16_t> >());
- else
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<uint16_t>,
- DefLayout::DuplicateDefaultRecordList>,
- NumericCompare<uint16_t> >());
- }
- else {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint16_t>,
- PaxLayout::InternalRecordList>,
- NumericCompare<uint16_t> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint16_t>,
- PaxLayout::InlineRecordList>,
- NumericCompare<uint16_t> >());
- else
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint16_t>,
- PaxLayout::DefaultRecordList>,
- NumericCompare<uint16_t> >());
- }
- // 32bit unsigned integer
- case HAM_TYPE_UINT32:
- if (use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::PodKeyList<uint32_t>,
- PaxLayout::InternalRecordList>,
- NumericCompare<uint32_t> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<uint32_t>,
- DefLayout::DuplicateInlineRecordList>,
- NumericCompare<uint32_t> >());
- else
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<uint32_t>,
- DefLayout::DuplicateDefaultRecordList>,
- NumericCompare<uint32_t> >());
- }
- else {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint32_t>,
- PaxLayout::InternalRecordList>,
- NumericCompare<uint32_t> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint32_t>,
- PaxLayout::InlineRecordList>,
- NumericCompare<uint32_t> >());
- else
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint32_t>,
- PaxLayout::DefaultRecordList>,
- NumericCompare<uint32_t> >());
- }
- // 64bit unsigned integer
- case HAM_TYPE_UINT64:
- if (use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::PodKeyList<uint64_t>,
- PaxLayout::InternalRecordList>,
- NumericCompare<uint64_t> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<uint64_t>,
- DefLayout::DuplicateInlineRecordList>,
- NumericCompare<uint64_t> >());
- else
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<uint64_t>,
- DefLayout::DuplicateDefaultRecordList>,
- NumericCompare<uint64_t> >());
- }
- else {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::PodKeyList<uint64_t>,
- PaxLayout::InternalRecordList>,
- NumericCompare<uint64_t> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint64_t>,
- PaxLayout::InlineRecordList>,
- NumericCompare<uint64_t> >());
- else
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<uint64_t>,
- PaxLayout::DefaultRecordList>,
- NumericCompare<uint64_t> >());
- }
- // 32bit float
- case HAM_TYPE_REAL32:
- if (use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::PodKeyList<float>,
- PaxLayout::InternalRecordList>,
- NumericCompare<float> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<float>,
- DefLayout::DuplicateInlineRecordList>,
- NumericCompare<float> >());
- else
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<float>,
- DefLayout::DuplicateDefaultRecordList>,
- NumericCompare<float> >());
- }
- else {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<float>,
- PaxLayout::InternalRecordList>,
- NumericCompare<float> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<float>,
- PaxLayout::InlineRecordList>,
- NumericCompare<float> >());
- else
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<float>,
- PaxLayout::DefaultRecordList>,
- NumericCompare<float> >());
- }
- // 64bit double
- case HAM_TYPE_REAL64:
- if (use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::PodKeyList<double>,
- PaxLayout::InternalRecordList>,
- NumericCompare<double> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<double>,
- DefLayout::DuplicateInlineRecordList>,
- NumericCompare<double> >());
- else
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::PodKeyList<double>,
- DefLayout::DuplicateDefaultRecordList>,
- NumericCompare<double> >());
- }
- else {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<double>,
- PaxLayout::InternalRecordList>,
- NumericCompare<double> >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<double>,
- PaxLayout::InlineRecordList>,
- NumericCompare<double> >());
- else
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::PodKeyList<double>,
- PaxLayout::DefaultRecordList>,
- NumericCompare<double> >());
- }
- // Callback function provided by user?
- case HAM_TYPE_CUSTOM:
- // Fixed keys, no duplicates
- if (fixed_keys && !use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::BinaryKeyList,
- PaxLayout::InternalRecordList>,
- CallbackCompare>());
- if (inline_records)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::BinaryKeyList,
- PaxLayout::InlineRecordList>,
- CallbackCompare>());
- else
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::BinaryKeyList,
- PaxLayout::DefaultRecordList>,
- CallbackCompare>());
- }
- // Fixed keys WITH duplicates
- if (fixed_keys && use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::BinaryKeyList,
- PaxLayout::InternalRecordList>,
- CallbackCompare >());
- if (inline_records)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::BinaryKeyList,
- DefLayout::DuplicateInlineRecordList>,
- CallbackCompare >());
- else
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::BinaryKeyList,
- DefLayout::DuplicateDefaultRecordList>,
- CallbackCompare >());
- }
- // Variable keys with or without duplicates
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- PaxLayout::InternalRecordList>,
- CallbackCompare >());
- if (inline_records && !use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- PaxLayout::InlineRecordList>,
- CallbackCompare >());
- if (inline_records && use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- DefLayout::DuplicateInlineRecordList>,
- CallbackCompare >());
- if (!inline_records && !use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- PaxLayout::DefaultRecordList>,
- CallbackCompare >());
- if (!inline_records && use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- DefLayout::DuplicateDefaultRecordList>,
- CallbackCompare >());
- ham_assert(!"shouldn't be here");
- // BINARY is the default:
- case HAM_TYPE_BINARY:
- // Fixed keys, no duplicates
- if (fixed_keys && !use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::BinaryKeyList,
- PaxLayout::InternalRecordList>,
- FixedSizeCompare>());
- if (inline_records)
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::BinaryKeyList,
- PaxLayout::InlineRecordList>,
- FixedSizeCompare>());
- else
- return (new BtreeIndexTraitsImpl
- <PaxNodeImpl<PaxLayout::BinaryKeyList,
- PaxLayout::DefaultRecordList>,
- FixedSizeCompare>());
- }
- // fixed keys with duplicates
- if (fixed_keys && use_duplicates) {
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- PaxNodeImpl<PaxLayout::BinaryKeyList,
- PaxLayout::InternalRecordList>,
- FixedSizeCompare >());
- if (inline_records && use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::BinaryKeyList,
- DefLayout::DuplicateInlineRecordList>,
- FixedSizeCompare >());
- if (!inline_records && use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<PaxLayout::BinaryKeyList,
- DefLayout::DuplicateDefaultRecordList>,
- FixedSizeCompare >());
- }
- // variable length keys, with and without duplicates
- if (!is_leaf)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- PaxLayout::InternalRecordList>,
- VariableSizeCompare >());
- if (inline_records && !use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- PaxLayout::InlineRecordList>,
- VariableSizeCompare >());
- if (inline_records && use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- DefLayout::DuplicateInlineRecordList>,
- VariableSizeCompare >());
- if (!inline_records && !use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- PaxLayout::DefaultRecordList>,
- VariableSizeCompare >());
- if (!inline_records && use_duplicates)
- return (new BtreeIndexTraitsImpl<
- DefaultNodeImpl<DefLayout::VariableLengthKeyList,
- DefLayout::DuplicateDefaultRecordList>,
- VariableSizeCompare >());
- ham_assert(!"shouldn't be here");
- default:
- break;
- }
-
- ham_assert(!"shouldn't be here");
- return (0);
- }
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_INDEX_FACTORY_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_insert.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_insert.cc
deleted file mode 100644
index 7dac8365d7..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_insert.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * btree inserting
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-#include <algorithm>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3blob_manager/blob_manager.h"
-#include "3page_manager/page_manager.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_stats.h"
-#include "3btree/btree_node_proxy.h"
-#include "3btree/btree_cursor.h"
-#include "3btree/btree_update.h"
-#include "4cursor/cursor.h"
-#include "4db/db.h"
-#include "4env/env.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace std;
-
-namespace hamsterdb {
-
-class BtreeInsertAction : public BtreeUpdateAction
-{
- public:
- BtreeInsertAction(BtreeIndex *btree, Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags)
- : BtreeUpdateAction(btree, context, cursor
- ? cursor->get_btree_cursor()
- : 0, 0),
- m_key(key), m_record(record), m_flags(flags) {
- if (m_cursor)
- m_duplicate_index = m_cursor->get_duplicate_index();
- }
-
- // This is the entry point for the actual insert operation
- ham_status_t run() {
- BtreeStatistics *stats = m_btree->get_statistics();
-
- m_hints = stats->get_insert_hints(m_flags);
-
- ham_assert((m_hints.flags & (HAM_DUPLICATE_INSERT_BEFORE
- | HAM_DUPLICATE_INSERT_AFTER
- | HAM_DUPLICATE_INSERT_FIRST
- | HAM_DUPLICATE_INSERT_LAST))
- ? (m_hints.flags & HAM_DUPLICATE)
- : 1);
-
- /*
- * append the key? append_or_prepend_key() will try to append or
- * prepend the key; if this fails because the key is NOT the largest
- * (or smallest) key in the database or because the current page is
- * already full, it will remove the HINT_APPEND (or HINT_PREPEND)
- * flag and call insert()
- */
- ham_status_t st;
- if (m_hints.leaf_page_addr
- && (m_hints.flags & HAM_HINT_APPEND
- || m_hints.flags & HAM_HINT_PREPEND))
- st = append_or_prepend_key();
- else
- st = insert();
-
- if (st == HAM_LIMITS_REACHED)
- st = insert();
-
- if (st)
- stats->insert_failed();
- else {
- if (m_hints.processed_leaf_page)
- stats->insert_succeeded(m_hints.processed_leaf_page,
- m_hints.processed_slot);
- }
-
- return (st);
- }
-
- private:
- // Appends a key at the "end" of the btree, or prepends it at the
- // "beginning"
- ham_status_t append_or_prepend_key() {
- Page *page;
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
- bool force_append = false;
- bool force_prepend = false;
-
- /*
- * see if we get this btree leaf; if not, revert to regular scan
- *
- * As this is a speed-improvement hint re-using recent material, the page
- * should still sit in the cache, or we're using old info, which should
- * be discarded.
- */
- page = env->page_manager()->fetch(m_context, m_hints.leaf_page_addr,
- PageManager::kOnlyFromCache);
- /* if the page is not in cache: do a regular insert */
- if (!page)
- return (insert());
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
- ham_assert(node->is_leaf());
-
- /*
- * if the page is already full OR this page is not the right-most page
- * when we APPEND or the left-most node when we PREPEND
- * OR the new key is not the highest key: perform a normal insert
- */
- if ((m_hints.flags & HAM_HINT_APPEND && node->get_right() != 0)
- || (m_hints.flags & HAM_HINT_PREPEND && node->get_left() != 0)
- || node->requires_split(m_context, m_key))
- return (insert());
-
- /*
- * if the page is not empty: check if we append the key at the end/start
- * (depending on the flags), or if it's actually inserted in the middle.
- */
- if (node->get_count() != 0) {
- if (m_hints.flags & HAM_HINT_APPEND) {
- int cmp_hi = node->compare(m_context, m_key, node->get_count() - 1);
- /* key is at the end */
- if (cmp_hi > 0) {
- ham_assert(node->get_right() == 0);
- force_append = true;
- }
- }
-
- if (m_hints.flags & HAM_HINT_PREPEND) {
- int cmp_lo = node->compare(m_context, m_key, 0);
- /* key is at the start of page */
- if (cmp_lo < 0) {
- ham_assert(node->get_left() == 0);
- force_prepend = true;
- }
- }
- }
-
- /* OK - we're really appending/prepending the new key. */
- if (force_append || force_prepend)
- return (insert_in_page(page, m_key, m_record, m_hints,
- force_prepend, force_append));
-
- /* otherwise reset the hints because they are no longer valid */
- m_hints.flags &= ~HAM_HINT_APPEND;
- m_hints.flags &= ~HAM_HINT_PREPEND;
- return (insert());
- }
-
- ham_status_t insert() {
- // traverse the tree till a leaf is reached
- Page *parent;
- Page *page = traverse_tree(m_key, m_hints, &parent);
-
- // We've reached the leaf; it's still possible that we have to
- // split the page, therefore this case has to be handled
- ham_status_t st = insert_in_page(page, m_key, m_record, m_hints);
- if (st == HAM_LIMITS_REACHED) {
- page = split_page(page, parent, m_key, m_hints);
- return (insert_in_page(page, m_key, m_record, m_hints));
- }
- return (st);
- }
-
- // the key that is inserted
- ham_key_t *m_key;
-
- // the record that is inserted
- ham_record_t *m_record;
-
- // flags of ham_db_insert()
- uint32_t m_flags;
-
- // statistical hints for this operation
- BtreeStatistics::InsertHints m_hints;
-};
-
-ham_status_t
-BtreeIndex::insert(Context *context, Cursor *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- context->db = get_db();
-
- BtreeInsertAction bia(this, context, cursor, key, record, flags);
- return (bia.run());
-}
-
-} // namespace hamsterdb
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_base.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_base.h
deleted file mode 100644
index da5804ad04..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_base.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Base class for KeyLists
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_KEYS_BASE_H
-#define HAM_BTREE_KEYS_BASE_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct BaseKeyList
-{
- enum {
- // This KeyList cannot reduce its capacity in order to release storage
- kCanReduceCapacity = 0,
-
- // This KeyList uses binary search combined with linear search
- kBinaryLinear,
-
- // This KeyList has a custom search implementation
- kCustomSearch,
-
- // This KeyList has a custom search implementation for exact matches
- // *only*
- kCustomExactImplementation,
-
- // This KeyList uses binary search (this is the default)
- kBinarySearch,
-
- // Specifies the search implementation:
- kSearchImplementation = kBinarySearch,
-
- // This KeyList does NOT have a custom insert implementation
- kCustomInsert = 0,
- };
-
- BaseKeyList()
- : m_range_size(0) {
- }
-
- // Erases the extended part of a key; nothing to do here
- void erase_extended_key(Context *context, int slot) const {
- }
-
- // Checks the integrity of this node. Throws an exception if there is a
- // violation.
- void check_integrity(Context *context, size_t node_count) const {
- }
-
- // Rearranges the list
- void vacuumize(size_t node_count, bool force) const {
- }
-
- // Finds a key
- template<typename Cmp>
- int find(Context *, size_t node_count, const ham_key_t *key, Cmp &comparator,
- int *pcmp) {
- ham_assert(!"shouldn't be here");
- return (0);
- }
-
- // Returns the threshold when switching from binary search to
- // linear search. Disabled by default
- size_t get_linear_search_threshold() const {
- return ((size_t)-1);
- }
-
- // Performs a linear search in a given range between |start| and
- // |start + length|. Disabled by default.
- template<typename Cmp>
- int linear_search(size_t start, size_t length, const ham_key_t *hkey,
- Cmp &comparator, int *pcmp) {
- ham_assert(!"shouldn't be here");
- throw Exception(HAM_INTERNAL_ERROR);
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BtreeStatistics::update_min_max_avg(&metrics->keylist_ranges, m_range_size);
- }
-
- // The size of the range (in bytes)
- size_t m_range_size;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_KEYS_BASE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_binary.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_binary.h
deleted file mode 100644
index faea959ec5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_binary.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Fixed length KeyList for binary data
- *
- * This KeyList stores binary keys of fixed length size. It is implemented
- * as a plain C array of type uint8_t[]. It has fast random access, i.e.
- * key #N starts at data[N * keysize].
- *
- * This KeyList cannot be resized.
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_KEYS_BINARY_H
-#define HAM_BTREE_KEYS_BINARY_H
-
-#include "0root/root.h"
-
-#include <sstream>
-#include <iostream>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3btree/btree_node.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_keys_base.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// The template classes in this file are wrapped in a separate namespace
-// to avoid naming clashes with btree_impl_default.h
-//
-namespace PaxLayout {
-
-//
-// Same as the PodKeyList, but for binary arrays of fixed length
-//
-class BinaryKeyList : public BaseKeyList
-{
- public:
- enum {
- // A flag whether this KeyList has sequential data
- kHasSequentialData = 1,
-
- // A flag whether this KeyList supports the scan() call
- kSupportsBlockScans = 1,
-
- // This KeyList uses binary search in combination with linear search
- kSearchImplementation = kBinaryLinear,
- };
-
- // Constructor
- BinaryKeyList(LocalDatabase *db)
- : m_data(0) {
- m_key_size = db->config().key_size;
- ham_assert(m_key_size != 0);
- }
-
- // Creates a new KeyList starting at |data|, total size is
- // |range_size| (in bytes)
- void create(uint8_t *data, size_t range_size) {
- m_data = data;
- m_range_size = range_size;
- }
-
- // Opens an existing KeyList starting at |data|
- void open(uint8_t *data, size_t range_size, size_t node_count) {
- m_data = data;
- m_range_size = range_size;
- }
-
- // Calculates the required size for this range
- size_t get_required_range_size(size_t node_count) const {
- return (node_count * m_key_size);
- }
-
- // Returns the actual key size including overhead
- size_t get_full_key_size(const ham_key_t *key = 0) const {
- return (m_key_size);
- }
-
- // Copies a key into |dest|
- void get_key(Context *context, int slot, ByteArray *arena, ham_key_t *dest,
- bool deep_copy = true) const {
- dest->size = (uint16_t)m_key_size;
- if (likely(deep_copy == false)) {
- dest->data = &m_data[slot * m_key_size];
- return;
- }
-
- // allocate memory (if required)
- if (!(dest->flags & HAM_KEY_USER_ALLOC)) {
- arena->resize(dest->size);
- dest->data = arena->get_ptr();
- }
-
- memcpy(dest->data, &m_data[slot * m_key_size], m_key_size);
- }
-
- // Returns the threshold when switching from binary search to
- // linear search
- size_t get_linear_search_threshold() const {
- if (m_key_size > 32)
- return (-1); // disable linear search for large keys
- return (128 / m_key_size);
- }
-
- // Performs a linear search in a given range between |start| and
- // |start + length|
- template<typename Cmp>
- int linear_search(size_t start, size_t length, const ham_key_t *key,
- Cmp &comparator, int *pcmp) {
- uint8_t *begin = &m_data[start * m_key_size];
- uint8_t *end = &m_data[(start + length) * m_key_size];
- uint8_t *current = begin;
-
- int c = start;
-
- while (current < end) {
- /* compare it against the key */
- int cmp = comparator(key->data, key->size, current, m_key_size);
-
- /* found it, or moved past the key? */
- if (cmp <= 0) {
- if (cmp < 0) {
- if (c == 0)
- *pcmp = -1; // key is < #m_data[0]
- else
- *pcmp = +1; // key is > #m_data[c - 1]!
- return (c - 1);
- }
- *pcmp = 0;
- return (c);
- }
-
- current += m_key_size;
- c++;
- }
-
- /* the new key is > the last key in the page */
- *pcmp = 1;
- return (start + length - 1);
- }
-
- // Iterates all keys, calls the |visitor| on each
- void scan(Context *context, ScanVisitor *visitor, uint32_t start,
- size_t length) {
- (*visitor)(&m_data[start * m_key_size], length);
- }
-
- // Erases a whole slot by shifting all larger keys to the "left"
- void erase(Context *context, size_t node_count, int slot) {
- if (slot < (int)node_count - 1)
- memmove(&m_data[slot * m_key_size], &m_data[(slot + 1) * m_key_size],
- m_key_size * (node_count - slot - 1));
- }
-
- // Inserts a key
- template<typename Cmp>
- PBtreeNode::InsertResult insert(Context *context, size_t node_count,
- const ham_key_t *key, uint32_t flags, Cmp &comparator,
- int slot) {
- if (node_count > (size_t)slot)
- memmove(&m_data[(slot + 1) * m_key_size], &m_data[slot * m_key_size],
- m_key_size * (node_count - slot));
- set_key_data(slot, key->data, key->size);
- return (PBtreeNode::InsertResult(0, slot));
- }
-
- // Returns true if the |key| no longer fits into the node
- bool requires_split(size_t node_count, const ham_key_t *key) const {
- return ((node_count + 1) * m_key_size >= m_range_size);
- }
-
- // Copies |count| key from this[sstart] to dest[dstart]
- void copy_to(int sstart, size_t node_count, BinaryKeyList &dest,
- size_t other_count, int dstart) {
- memcpy(&dest.m_data[dstart * m_key_size], &m_data[sstart * m_key_size],
- m_key_size * (node_count - sstart));
- }
-
- // Change the capacity; for PAX layouts this just means copying the
- // data from one place to the other
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t capacity_hint) {
- memmove(new_data_ptr, m_data, node_count * m_key_size);
- m_data = new_data_ptr;
- m_range_size = new_range_size;
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BaseKeyList::fill_metrics(metrics, node_count);
- BtreeStatistics::update_min_max_avg(&metrics->keylist_unused,
- m_range_size - (node_count * m_key_size));
- }
-
- // Prints a slot to |out| (for debugging)
- void print(Context *context, int slot, std::stringstream &out) const {
- for (size_t i = 0; i < m_key_size; i++)
- out << (char)m_data[slot * m_key_size + i];
- }
-
- // Returns the key size
- size_t get_key_size(int slot) const {
- return (m_key_size);
- }
-
- // Returns the pointer to a key's data
- uint8_t *get_key_data(int slot) {
- return (&m_data[slot * m_key_size]);
- }
-
- // Has support for SIMD style search?
- bool has_simd_support() const {
- return (false);
- }
-
- // Returns the pointer to the key's inline data - for SIMD calculations
- // Not implemented by this KeyList
- uint8_t *get_simd_data() {
- return (0);
- }
-
- private:
- // Returns the pointer to a key's data (const flavour)
- uint8_t *get_key_data(int slot) const {
- return (&m_data[slot * m_key_size]);
- }
-
- // Overwrites a key's data. The |size| of the new data HAS
- // to be identical to the "official" key size
- void set_key_data(int slot, const void *ptr, size_t size) {
- ham_assert(size == get_key_size(slot));
- memcpy(&m_data[slot * m_key_size], ptr, size);
- }
-
- // The size of a single key
- size_t m_key_size;
-
- // Pointer to the actual key data
- uint8_t *m_data;
-};
-
-} // namespace PaxLayout
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_KEYS_BINARY_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_pod.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_pod.h
deleted file mode 100644
index 1a0582da69..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_pod.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Fixed length KeyList for built-in data types ("POD types")
- *
- * This is the fastest KeyList available. It stores POD data sequentially
- * in an array, i.e. PodKeyList<uint32_t> is simply a plain
- * C array of type uint32_t[]. Each key has zero overhead.
- *
- * This KeyList cannot be resized.
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_KEYS_POD_H
-#define HAM_BTREE_KEYS_POD_H
-
-#include "0root/root.h"
-
-#include <sstream>
-#include <iostream>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3btree/btree_node.h"
-#include "3btree/btree_keys_base.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// The template classes in this file are wrapped in a separate namespace
-// to avoid naming clashes with btree_impl_default.h
-//
-namespace PaxLayout {
-
-//
-// The PodKeyList provides simplified access to a list of keys where each
-// key is of type T (i.e. uint32_t).
-//
-template<typename T>
-class PodKeyList : public BaseKeyList
-{
- public:
- enum {
- // A flag whether this KeyList has sequential data
- kHasSequentialData = 1,
-
- // A flag whether this KeyList supports the scan() call
- kSupportsBlockScans = 1,
-
- // This KeyList uses a custom SIMD implementation if possible,
- // otherwise binary search in combination with linear search
- kSearchImplementation = kBinaryLinear,
- };
-
- // Constructor
- PodKeyList(LocalDatabase *db)
- : m_data(0) {
- }
-
- // Creates a new PodKeyList starting at |ptr|, total size is
- // |range_size| (in bytes)
- void create(uint8_t *data, size_t range_size) {
- m_data = (T *)data;
- m_range_size = range_size;
- }
-
- // Opens an existing PodKeyList starting at |ptr|
- void open(uint8_t *data, size_t range_size, size_t node_count) {
- m_data = (T *)data;
- m_range_size = range_size;
- }
-
- // Returns the required size for the current set of keys
- size_t get_required_range_size(size_t node_count) const {
- return (node_count * sizeof(T));
- }
-
- // Returns the actual key size including overhead
- size_t get_full_key_size(const ham_key_t *key = 0) const {
- return (sizeof(T));
- }
-
- // Copies a key into |dest|
- void get_key(Context *context, int slot, ByteArray *arena, ham_key_t *dest,
- bool deep_copy = true) const {
- dest->size = sizeof(T);
- if (deep_copy == false) {
- dest->data = &m_data[slot];
- return;
- }
-
- // allocate memory (if required)
- if (!(dest->flags & HAM_KEY_USER_ALLOC)) {
- arena->resize(dest->size);
- dest->data = arena->get_ptr();
- }
-
- memcpy(dest->data, &m_data[slot], sizeof(T));
- }
-
- // Returns the threshold when switching from binary search to
- // linear search
- size_t get_linear_search_threshold() const {
- return (128 / sizeof(T));
- }
-
- // Performs a linear search in a given range between |start| and
- // |start + length|
- template<typename Cmp>
- int linear_search(size_t start, size_t length, const ham_key_t *hkey,
- Cmp &comparator, int *pcmp) {
- T key = *(T *)hkey->data;
- size_t c = start;
- size_t end = start + length;
-
- #undef COMPARE
- #define COMPARE(c) if (key <= m_data[c]) { \
- if (key < m_data[c]) { \
- if (c == 0) \
- *pcmp = -1; /* key < m_data[0] */ \
- else \
- *pcmp = +1; /* key > m_data[c - 1] */ \
- return ((c) - 1); \
- } \
- *pcmp = 0; \
- return (c); \
- }
-
- while (c + 8 < end) {
- COMPARE(c)
- COMPARE(c + 1)
- COMPARE(c + 2)
- COMPARE(c + 3)
- COMPARE(c + 4)
- COMPARE(c + 5)
- COMPARE(c + 6)
- COMPARE(c + 7)
- c += 8;
- }
-
- while (c < end) {
- COMPARE(c)
- c++;
- }
-
- /* the new key is > the last key in the page */
- *pcmp = 1;
- return (start + length - 1);
- }
-
- // Iterates all keys, calls the |visitor| on each
- void scan(Context *context, ScanVisitor *visitor, uint32_t start,
- size_t length) {
- (*visitor)(&m_data[start], length);
- }
-
- // Erases a whole slot by shifting all larger keys to the "left"
- void erase(Context *context, size_t node_count, int slot) {
- if (slot < (int)node_count - 1)
- memmove(&m_data[slot], &m_data[slot + 1],
- sizeof(T) * (node_count - slot - 1));
- }
-
- // Inserts a key
- template<typename Cmp>
- PBtreeNode::InsertResult insert(Context *context, size_t node_count,
- const ham_key_t *key, uint32_t flags, Cmp &comparator,
- int slot) {
- if (node_count > (size_t)slot)
- memmove(&m_data[slot + 1], &m_data[slot],
- sizeof(T) * (node_count - slot));
- set_key_data(slot, key->data, key->size);
- return (PBtreeNode::InsertResult(0, slot));
- }
-
- // Copies |count| key from this[sstart] to dest[dstart]
- void copy_to(int sstart, size_t node_count, PodKeyList<T> &dest,
- size_t other_count, int dstart) {
- memcpy(&dest.m_data[dstart], &m_data[sstart],
- sizeof(T) * (node_count - sstart));
- }
-
- // Returns true if the |key| no longer fits into the node
- bool requires_split(size_t node_count, const ham_key_t *key) const {
- return ((node_count + 1) * sizeof(T) >= m_range_size);
- }
-
- // Change the range size; just copy the data from one place to the other
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t capacity_hint) {
- memmove(new_data_ptr, m_data, node_count * sizeof(T));
- m_data = (T *)new_data_ptr;
- m_range_size = new_range_size;
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BaseKeyList::fill_metrics(metrics, node_count);
- BtreeStatistics::update_min_max_avg(&metrics->keylist_unused,
- m_range_size - (node_count * sizeof(T)));
- }
-
- // Prints a slot to |out| (for debugging)
- void print(Context *context, int slot, std::stringstream &out) const {
- out << m_data[slot];
- }
-
- // Returns the size of a key
- size_t get_key_size(int slot) const {
- return (sizeof(T));
- }
-
- // Returns a pointer to the key's data
- uint8_t *get_key_data(int slot) {
- return ((uint8_t *)&m_data[slot]);
- }
-
- private:
- // Returns a pointer to the key's data (const flavour)
- uint8_t *get_key_data(int slot) const {
- return ((uint8_t *)&m_data[slot]);
- }
-
- // Overwrites an existing key; the |size| of the new data HAS to be
- // identical with the key size specified when the database was created!
- void set_key_data(int slot, const void *ptr, size_t size) {
- ham_assert(size == sizeof(T));
- m_data[slot] = *(T *)ptr;
- }
-
- // The actual array of T's
- T *m_data;
-};
-
-} // namespace PaxLayout
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_KEYS_POD_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_varlen.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_varlen.h
deleted file mode 100644
index 5f85676c56..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_keys_varlen.h
+++ /dev/null
@@ -1,533 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Variable length KeyList
- *
- * Each key is stored in a "chunk", and the chunks are managed by an upfront
- * index which contains offset and size of each chunk. The index also keeps
- * track of deleted chunks.
- *
- * The actual chunk data contains the key's data (which can be a 64bit blob
- * ID if the key is too big).
- *
- * If the key is too big (exceeds |m_extkey_threshold|) then it's offloaded
- * to an external blob, and only the 64bit record id of this blob is stored
- * in the node. These "extended keys" are cached; the cache's lifetime is
- * coupled to the lifetime of the node.
- *
- * To avoid expensive memcpy-operations, erasing a key only affects this
- * upfront index: the relevant slot is moved to a "freelist". This freelist
- * contains the same meta information as the index table.
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_KEYS_VARLEN_H
-#define HAM_BTREE_KEYS_VARLEN_H
-
-#include "0root/root.h"
-
-#include <algorithm>
-#include <iostream>
-#include <vector>
-#include <map>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "1base/scoped_ptr.h"
-#include "2page/page.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_node.h"
-#include "3btree/btree_index.h"
-#include "3btree/upfront_index.h"
-#include "3btree/btree_keys_base.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-namespace DefLayout {
-
-//
-// Variable length keys
-//
-// This KeyList uses an UpfrontIndex to manage the variable length data
-// chunks. The UpfrontIndex knows the sizes of the chunks, and therefore
-// the VariableLengthKeyList does *not* store additional size information.
-//
-// The format of a single key is:
-// |Flags|Data...|
-// where Flags are 8 bit.
-//
-// The key size (as specified by the user when inserting the key) therefore
-// is UpfrontIndex::get_chunk_size() - 1.
-//
-class VariableLengthKeyList : public BaseKeyList
-{
- // for caching external keys
- typedef std::map<uint64_t, ByteArray> ExtKeyCache;
-
- public:
- enum {
- // A flag whether this KeyList has sequential data
- kHasSequentialData = 0,
-
- // A flag whether this KeyList supports the scan() call
- kSupportsBlockScans = 0,
-
- // This KeyList can reduce its capacity in order to release storage
- kCanReduceCapacity = 1,
-
- // This KeyList uses binary search
- kSearchImplementation = kBinarySearch,
- };
-
- // Constructor
- VariableLengthKeyList(LocalDatabase *db)
- : m_db(db), m_index(db), m_data(0) {
- size_t page_size = db->lenv()->config().page_size_bytes;
- if (Globals::ms_extended_threshold)
- m_extkey_threshold = Globals::ms_extended_threshold;
- else {
- if (page_size == 1024)
- m_extkey_threshold = 64;
- else if (page_size <= 1024 * 8)
- m_extkey_threshold = 128;
- else {
- // UpfrontIndex's chunk size has 8 bit (max 255), and reserve
- // a few bytes for metadata (flags)
- m_extkey_threshold = 250;
- }
- }
- }
-
- // Creates a new KeyList starting at |ptr|, total size is
- // |range_size| (in bytes)
- void create(uint8_t *data, size_t range_size) {
- m_data = data;
- m_range_size = range_size;
- m_index.create(m_data, range_size, range_size / get_full_key_size());
- }
-
- // Opens an existing KeyList
- void open(uint8_t *data, size_t range_size, size_t node_count) {
- m_data = data;
- m_range_size = range_size;
- m_index.open(m_data, range_size);
- }
-
- // Calculates the required size for a range
- size_t get_required_range_size(size_t node_count) const {
- return (m_index.get_required_range_size(node_count));
- }
-
- // Returns the actual key size including overhead. This is an estimate
- // since we don't know how large the keys will be
- size_t get_full_key_size(const ham_key_t *key = 0) const {
- if (!key)
- return (24 + m_index.get_full_index_size() + 1);
- // always make sure to have enough space for an extkey id
- if (key->size < 8 || key->size > m_extkey_threshold)
- return (sizeof(uint64_t) + m_index.get_full_index_size() + 1);
- return (key->size + m_index.get_full_index_size() + 1);
- }
-
- // Copies a key into |dest|
- void get_key(Context *context, int slot, ByteArray *arena, ham_key_t *dest,
- bool deep_copy = true) {
- ham_key_t tmp;
- uint32_t offset = m_index.get_chunk_offset(slot);
- uint8_t *p = m_index.get_chunk_data_by_offset(offset);
-
- if (unlikely(*p & BtreeKey::kExtendedKey)) {
- memset(&tmp, 0, sizeof(tmp));
- get_extended_key(context, get_extended_blob_id(slot), &tmp);
- }
- else {
- tmp.size = get_key_size(slot);
- tmp.data = p + 1;
- }
-
- dest->size = tmp.size;
-
- if (likely(deep_copy == false)) {
- dest->data = tmp.data;
- return;
- }
-
- // allocate memory (if required)
- if (!(dest->flags & HAM_KEY_USER_ALLOC)) {
- arena->resize(tmp.size);
- dest->data = arena->get_ptr();
- }
- memcpy(dest->data, tmp.data, tmp.size);
- }
-
- // Iterates all keys, calls the |visitor| on each. Not supported by
- // this KeyList implementation. For variable length keys, the caller
- // must iterate over all keys. The |scan()| interface is only implemented
- // for PAX style layouts.
- void scan(Context *context, ScanVisitor *visitor, size_t node_count,
- uint32_t start) {
- ham_assert(!"shouldn't be here");
- throw Exception(HAM_INTERNAL_ERROR);
- }
-
- // Erases a key's payload. Does NOT remove the chunk from the UpfrontIndex
- // (see |erase()|).
- void erase_extended_key(Context *context, int slot) {
- uint8_t flags = get_key_flags(slot);
- if (flags & BtreeKey::kExtendedKey) {
- // delete the extended key from the cache
- erase_extended_key(context, get_extended_blob_id(slot));
- // and transform into a key which is non-extended and occupies
- // the same space as before, when it was extended
- set_key_flags(slot, flags & (~BtreeKey::kExtendedKey));
- set_key_size(slot, sizeof(uint64_t));
- }
- }
-
- // Erases a key, including extended blobs
- void erase(Context *context, size_t node_count, int slot) {
- erase_extended_key(context, slot);
- m_index.erase(node_count, slot);
- }
-
- // Inserts the |key| at the position identified by |slot|.
- // This method cannot fail; there MUST be sufficient free space in the
- // node (otherwise the caller would have split the node).
- template<typename Cmp>
- PBtreeNode::InsertResult insert(Context *context, size_t node_count,
- const ham_key_t *key, uint32_t flags,
- Cmp &comparator, int slot) {
- m_index.insert(node_count, slot);
-
- // now there's one additional slot
- node_count++;
-
- uint32_t key_flags = 0;
-
- // When inserting the data: always add 1 byte for key flags
- if (key->size <= m_extkey_threshold
- && m_index.can_allocate_space(node_count, key->size + 1)) {
- uint32_t offset = m_index.allocate_space(node_count, slot,
- key->size + 1);
- uint8_t *p = m_index.get_chunk_data_by_offset(offset);
- *p = key_flags;
- memcpy(p + 1, key->data, key->size); // and data
- }
- else {
- uint64_t blob_id = add_extended_key(context, key);
- m_index.allocate_space(node_count, slot, 8 + 1);
- set_extended_blob_id(slot, blob_id);
- set_key_flags(slot, key_flags | BtreeKey::kExtendedKey);
- }
-
- return (PBtreeNode::InsertResult(0, slot));
- }
-
- // Returns true if the |key| no longer fits into the node and a split
- // is required. Makes sure that there is ALWAYS enough headroom
- // for an extended key!
- //
- // If there's no key specified then always assume the worst case and
- // pretend that the key has the maximum length
- bool requires_split(size_t node_count, const ham_key_t *key) {
- size_t required;
- if (key) {
- required = key->size + 1;
- // add 1 byte for flags
- if (key->size > m_extkey_threshold || key->size < 8 + 1)
- required = 8 + 1;
- }
- else
- required = m_extkey_threshold + 1;
- return (m_index.requires_split(node_count, required));
- }
-
- // Copies |count| key from this[sstart] to dest[dstart]
- void copy_to(int sstart, size_t node_count,
- VariableLengthKeyList &dest, size_t other_node_count,
- int dstart) {
- size_t to_copy = node_count - sstart;
- ham_assert(to_copy > 0);
-
- // make sure that the other node has sufficient capacity in its
- // UpfrontIndex
- dest.m_index.change_range_size(other_node_count, 0, 0,
- m_index.get_capacity());
-
- for (size_t i = 0; i < to_copy; i++) {
- size_t size = get_key_size(sstart + i);
-
- uint8_t *p = m_index.get_chunk_data_by_offset(
- m_index.get_chunk_offset(sstart + i));
- uint8_t flags = *p;
- uint8_t *data = p + 1;
-
- dest.m_index.insert(other_node_count + i, dstart + i);
- // Add 1 byte for key flags
- uint32_t offset = dest.m_index.allocate_space(other_node_count + i + 1,
- dstart + i, size + 1);
- p = dest.m_index.get_chunk_data_by_offset(offset);
- *p = flags; // sets flags
- memcpy(p + 1, data, size); // and data
- }
-
- // A lot of keys will be invalidated after copying, therefore make
- // sure that the next_offset is recalculated when it's required
- m_index.invalidate_next_offset();
- }
-
- // Checks the integrity of this node. Throws an exception if there is a
- // violation.
- void check_integrity(Context *context, size_t node_count) const {
- ByteArray arena;
-
- // verify that the offsets and sizes are not overlapping
- m_index.check_integrity(node_count);
-
- // make sure that extkeys are handled correctly
- for (size_t i = 0; i < node_count; i++) {
- if (get_key_size(i) > m_extkey_threshold
- && !(get_key_flags(i) & BtreeKey::kExtendedKey)) {
- ham_log(("key size %d, but key is not extended", get_key_size(i)));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
-
- if (get_key_flags(i) & BtreeKey::kExtendedKey) {
- uint64_t blobid = get_extended_blob_id(i);
- if (!blobid) {
- ham_log(("integrity check failed: item %u "
- "is extended, but has no blob", i));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
-
- // make sure that the extended blob can be loaded
- ham_record_t record = {0};
- m_db->lenv()->blob_manager()->read(context, blobid,
- &record, 0, &arena);
-
- // compare it to the cached key (if there is one)
- if (m_extkey_cache) {
- ExtKeyCache::iterator it = m_extkey_cache->find(blobid);
- if (it != m_extkey_cache->end()) {
- if (record.size != it->second.get_size()) {
- ham_log(("Cached extended key differs from real key"));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- if (memcmp(record.data, it->second.get_ptr(), record.size)) {
- ham_log(("Cached extended key differs from real key"));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- }
- }
- }
- }
- }
-
- // Rearranges the list
- void vacuumize(size_t node_count, bool force) {
- if (force)
- m_index.increase_vacuumize_counter(100);
- m_index.maybe_vacuumize(node_count);
- }
-
- // Change the range size; the capacity will be adjusted, the data is
- // copied as necessary
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t capacity_hint) {
- // no capacity given? then try to find a good default one
- if (capacity_hint == 0) {
- capacity_hint = (new_range_size - m_index.get_next_offset(node_count)
- - get_full_key_size()) / m_index.get_full_index_size();
- if (capacity_hint <= node_count)
- capacity_hint = node_count + 1;
- }
-
- // if there's not enough space for the new capacity then try to reduce
- // the capacity
- if (m_index.get_next_offset(node_count) + get_full_key_size(0)
- + capacity_hint * m_index.get_full_index_size()
- + UpfrontIndex::kPayloadOffset
- > new_range_size)
- capacity_hint = node_count + 1;
-
- m_index.change_range_size(node_count, new_data_ptr, new_range_size,
- capacity_hint);
- m_data = new_data_ptr;
- m_range_size = new_range_size;
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BaseKeyList::fill_metrics(metrics, node_count);
- BtreeStatistics::update_min_max_avg(&metrics->keylist_index,
- (uint32_t)(m_index.get_capacity()
- * m_index.get_full_index_size()));
- BtreeStatistics::update_min_max_avg(&metrics->keylist_unused,
- m_range_size
- - (uint32_t)m_index.get_required_range_size(node_count));
- }
-
- // Prints a slot to |out| (for debugging)
- void print(Context *context, int slot, std::stringstream &out) {
- ham_key_t tmp = {0};
- if (get_key_flags(slot) & BtreeKey::kExtendedKey) {
- get_extended_key(context, get_extended_blob_id(slot), &tmp);
- }
- else {
- tmp.size = get_key_size(slot);
- tmp.data = get_key_data(slot);
- }
- out << (const char *)tmp.data;
- }
-
- // Returns the pointer to a key's inline data (const flavour)
- uint8_t *get_key_data(int slot) const {
- uint32_t offset = m_index.get_chunk_offset(slot);
- return (m_index.get_chunk_data_by_offset(offset) + 1);
- }
-
- // Returns the size of a key
- size_t get_key_size(int slot) const {
- return (m_index.get_chunk_size(slot) - 1);
- }
-
- private:
- // Returns the flags of a key. Flags are defined in btree_flags.h
- uint8_t get_key_flags(int slot) const {
- uint32_t offset = m_index.get_chunk_offset(slot);
- return (*m_index.get_chunk_data_by_offset(offset));
- }
-
- // Sets the flags of a key. Flags are defined in btree_flags.h
- void set_key_flags(int slot, uint8_t flags) {
- uint32_t offset = m_index.get_chunk_offset(slot);
- *m_index.get_chunk_data_by_offset(offset) = flags;
- }
-
- // Overwrites the (inline) data of the key
- void set_key_data(int slot, const void *ptr, size_t size) {
- ham_assert(m_index.get_chunk_size(slot) >= size);
- set_key_size(slot, (uint16_t)size);
- memcpy(get_key_data(slot), ptr, size);
- }
-
- // Sets the size of a key
- void set_key_size(int slot, size_t size) {
- ham_assert(size + 1 <= m_index.get_chunk_size(slot));
- m_index.set_chunk_size(slot, size + 1);
- }
-
- // Returns the record address of an extended key overflow area
- uint64_t get_extended_blob_id(int slot) const {
- return (*(uint64_t *)get_key_data(slot));
- }
-
- // Sets the record address of an extended key overflow area
- void set_extended_blob_id(int slot, uint64_t blobid) {
- *(uint64_t *)get_key_data(slot) = blobid;
- }
-
- // Erases an extended key from disk and from the cache
- void erase_extended_key(Context *context, uint64_t blobid) {
- m_db->lenv()->blob_manager()->erase(context, blobid);
- if (m_extkey_cache) {
- ExtKeyCache::iterator it = m_extkey_cache->find(blobid);
- if (it != m_extkey_cache->end())
- m_extkey_cache->erase(it);
- }
- }
-
- // Retrieves the extended key at |blobid| and stores it in |key|; will
- // use the cache.
- void get_extended_key(Context *context, uint64_t blob_id, ham_key_t *key) {
- if (!m_extkey_cache)
- m_extkey_cache.reset(new ExtKeyCache());
- else {
- ExtKeyCache::iterator it = m_extkey_cache->find(blob_id);
- if (it != m_extkey_cache->end()) {
- key->size = it->second.get_size();
- key->data = it->second.get_ptr();
- return;
- }
- }
-
- ByteArray arena;
- ham_record_t record = {0};
- m_db->lenv()->blob_manager()->read(context, blob_id, &record,
- HAM_FORCE_DEEP_COPY, &arena);
- (*m_extkey_cache)[blob_id] = arena;
- arena.disown();
- key->data = record.data;
- key->size = record.size;
- }
-
- // Allocates an extended key and stores it in the cache
- uint64_t add_extended_key(Context *context, const ham_key_t *key) {
- if (!m_extkey_cache)
- m_extkey_cache.reset(new ExtKeyCache());
-
- ham_record_t rec = {0};
- rec.data = key->data;
- rec.size = key->size;
-
- uint64_t blob_id = m_db->lenv()->blob_manager()->allocate(
- context, &rec, 0);
- ham_assert(blob_id != 0);
- ham_assert(m_extkey_cache->find(blob_id) == m_extkey_cache->end());
-
- ByteArray arena;
- arena.resize(key->size);
- memcpy(arena.get_ptr(), key->data, key->size);
- (*m_extkey_cache)[blob_id] = arena;
- arena.disown();
-
- // increment counter (for statistics)
- Globals::ms_extended_keys++;
-
- return (blob_id);
- }
-
- // The database
- LocalDatabase *m_db;
-
- // The index for managing the variable-length chunks
- UpfrontIndex m_index;
-
- // Pointer to the data of the node
- uint8_t *m_data;
-
- // Cache for extended keys
- ScopedPtr<ExtKeyCache> m_extkey_cache;
-
- // Threshold for extended keys; if key size is > threshold then the
- // key is moved to a blob
- size_t m_extkey_threshold;
-};
-
-} // namespace DefLayout
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_KEYS_VARLEN_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_node.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_node.h
deleted file mode 100644
index 854e68e1a5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_node.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_NODE_H
-#define HAM_BTREE_NODE_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "2page/page.h"
-#include "3btree/btree_flags.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class PBtreeKeyDefault;
-
-#include "1base/packstart.h"
-
-/*
- * A BtreeNode structure spans the persistent part of a Page
- *
- * This structure is directly written to/read from the file.
- */
-HAM_PACK_0 struct HAM_PACK_1 PBtreeNode
-{
- public:
- // Result of the insert() operation
- struct InsertResult {
- InsertResult(ham_status_t _status = 0, int _slot = 0)
- : status(_status), slot(_slot) {
- }
-
- // hamsterdb status code
- ham_status_t status;
-
- // the slot of the new (or existing) key
- int slot;
- };
-
- enum {
- // insert key at the beginning of the page
- kInsertPrepend = 1,
-
- // append key to the end of the page
- kInsertAppend = 2,
- };
-
- enum {
- // node is a leaf
- kLeafNode = 1
- };
-
- // Returns a PBtreeNode from a Page
- static PBtreeNode *from_page(Page *page) {
- return ((PBtreeNode *)page->get_payload());
- }
-
- // Returns the offset (in bytes) of the member |m_data|
- static uint32_t get_entry_offset() {
- return (sizeof(PBtreeNode) - 1);
- }
-
- // Returns the flags of the btree node (|kLeafNode|)
- uint32_t get_flags() const {
- return (m_flags);
- }
-
- // Sets the flags of the btree node (|kLeafNode|)
- void set_flags(uint32_t flags) {
- m_flags = flags;
- }
-
- // Returns the number of entries in a BtreeNode
- uint32_t get_count() const {
- return (m_count);
- }
-
- // Sets the number of entries in a BtreeNode
- void set_count(uint32_t count) {
- m_count = count;
- }
-
- // Returns the address of the left sibling of this node
- uint64_t get_left() const {
- return (m_left);
- }
-
- // Sets the address of the left sibling of this node
- void set_left(uint64_t left) {
- m_left = left;
- }
-
- // Returns the address of the right sibling of this node
- uint64_t get_right() const {
- return (m_right);
- }
-
- // Sets the address of the right sibling of this node
- void set_right(uint64_t right) {
- m_right = right;
- }
-
- // Returns the ptr_down of this node
- uint64_t get_ptr_down() const {
- return (m_ptr_down);
- }
-
- // Returns true if this btree node is a leaf node
- bool is_leaf() const {
- return (m_flags & kLeafNode);
- }
-
- // Sets the ptr_down of this node
- void set_ptr_down(uint64_t ptr_down) {
- m_ptr_down = ptr_down;
- }
-
- // Returns a pointer to the key data
- uint8_t *get_data() {
- return (&m_data[0]);
- }
-
- const uint8_t *get_data() const {
- return (&m_data[0]);
- }
-
- private:
- // flags of this node
- uint32_t m_flags;
-
- // number of used entries in the node
- uint32_t m_count;
-
- // address of left sibling
- uint64_t m_left;
-
- // address of right sibling
- uint64_t m_right;
-
- // address of child node whose items are smaller than all items
- // in this node
- uint64_t m_ptr_down;
-
- // the entries of this node
- uint8_t m_data[1];
-
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_NODE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_node_proxy.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_node_proxy.h
deleted file mode 100644
index 110bd05f08..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_node_proxy.h
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_NODE_PROXY_H
-#define HAM_BTREE_NODE_PROXY_H
-
-#include "0root/root.h"
-
-#include <set>
-#include <string.h>
-#include <iostream>
-#include <sstream>
-#include <fstream>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/abi.h"
-#include "1base/dynamic_array.h"
-#include "1base/error.h"
-#include "2page/page.h"
-#include "3btree/btree_node.h"
-#include "3blob_manager/blob_manager.h"
-#include "4env/env_local.h"
-#include "4db/db_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-struct ScanVisitor;
-
-//
-// A BtreeNodeProxy wraps a PBtreeNode structure and defines the actual
-// format of the btree payload.
-//
-// The BtreeNodeProxy class provides access to the actual Btree nodes. The
-// layout of those nodes depends heavily on the database configuration,
-// and is implemented by template classes (btree_impl_default.h,
-// btree_impl_pax.h.).
-//
-class BtreeNodeProxy
-{
- public:
- // Constructor
- BtreeNodeProxy(Page *page)
- : m_page(page) {
- }
-
- // Destructor
- virtual ~BtreeNodeProxy() {
- }
-
- // Returns the flags of the btree node (|kLeafNode|)
- uint32_t get_flags() const {
- return (PBtreeNode::from_page(m_page)->get_flags());
- }
-
- // Sets the flags of the btree node (|kLeafNode|)
- void set_flags(uint32_t flags) {
- PBtreeNode::from_page(m_page)->set_flags(flags);
- }
-
- // Returns the number of entries in the BtreeNode
- size_t get_count() const {
- return (PBtreeNode::from_page(m_page)->get_count());
- }
-
- // Sets the number of entries in the BtreeNode
- void set_count(size_t count) {
- PBtreeNode::from_page(m_page)->set_count((uint32_t)count);
- }
-
- // Returns true if this btree node is a leaf node
- bool is_leaf() const {
- return (PBtreeNode::from_page(m_page)->is_leaf());
- }
-
- // Returns the address of the left sibling of this node
- uint64_t get_left() const {
- return (PBtreeNode::from_page(m_page)->get_left());
- }
-
- // Sets the address of the left sibling of this node
- void set_left(uint64_t address) {
- PBtreeNode::from_page(m_page)->set_left(address);
- }
-
- // Returns the address of the right sibling of this node
- uint64_t get_right() const {
- return (PBtreeNode::from_page(m_page)->get_right());
- }
-
- // Sets the address of the right sibling of this node
- void set_right(uint64_t address) {
- PBtreeNode::from_page(m_page)->set_right(address);
- }
-
- // Returns the ptr_down of this node
- uint64_t get_ptr_down() const {
- return (PBtreeNode::from_page(m_page)->get_ptr_down());
- }
-
- // Sets the ptr_down of this node
- void set_ptr_down(uint64_t address) {
- PBtreeNode::from_page(m_page)->set_ptr_down(address);
- }
-
- // Returns the page pointer - const version
- const Page *get_page() const {
- return (m_page);
- }
-
- // Returns the page pointer
- Page *get_page() {
- return (m_page);
- }
-
- // Returns the estimated capacity of this node
- virtual size_t estimate_capacity() const = 0;
-
- // Checks the integrity of the node. Throws an exception if it is
- // not. Called by ham_db_check_integrity().
- virtual void check_integrity(Context *context) const = 0;
-
- // Iterates all keys, calls the |visitor| on each
- virtual void scan(Context *context, ScanVisitor *visitor,
- size_t start, bool distinct) = 0;
-
- // Compares the two keys. Returns 0 if both are equal, otherwise -1 (if
- // |lhs| is greater) or +1 (if |rhs| is greater).
- virtual int compare(const ham_key_t *lhs, const ham_key_t *rhs) const = 0;
-
- // Compares a public key and an internal key
- virtual int compare(Context *context, const ham_key_t *lhs, int rhs) = 0;
-
- // Returns true if the public key (|lhs|) and an internal key (slot
- // |rhs|) are equal
- virtual bool equals(Context *context, const ham_key_t *lhs, int rhs) = 0;
-
- // Searches the node for the |key|, and returns the slot of this key.
- // If |record_id| is not null then it will store the result of the last
- // compare operation.
- // If |pcmp| is not null then it will store the result of the last
- // compare operation.
- virtual int find_child(Context *context, ham_key_t *key,
- uint64_t *record_id = 0, int *pcmp = 0) = 0;
-
- // Searches the node for the |key|, but will always return -1 if
- // an exact match was not found
- virtual int find_exact(Context *context, ham_key_t *key) = 0;
-
- // Returns the full key at the |slot|. Also resolves extended keys
- // and respects HAM_KEY_USER_ALLOC in dest->flags.
- virtual void get_key(Context *context, int slot, ByteArray *arena,
- ham_key_t *dest) = 0;
-
- // Returns the number of records of a key at the given |slot|. This is
- // either 1 or higher, but only if duplicate keys exist.
- virtual int get_record_count(Context *context, int slot) = 0;
-
- // Returns the record size of a key or one of its duplicates.
- virtual uint64_t get_record_size(Context *context, int slot,
- int duplicate_index) = 0;
-
- // Returns the record id of the key at the given |slot|
- // Only for internal nodes!
- virtual uint64_t get_record_id(Context *context, int slot) const = 0;
-
- // Sets the record id of the key at the given |slot|
- // Only for internal nodes!
- virtual void set_record_id(Context *context, int slot, uint64_t id) = 0;
-
- // Returns the full record and stores it in |dest|. The record is identified
- // by |slot| and |duplicate_index|. TINY and SMALL records are handled
- // correctly, as well as HAM_DIRECT_ACCESS.
- virtual void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags,
- int duplicate_index = 0) = 0;
-
- // High-level function to set a new record
- //
- // flags can be
- // - HAM_OVERWRITE
- // - HAM_DUPLICATE*
- //
- // a previously existing blob will be deleted if necessary
- virtual void set_record(Context *context, int slot, ham_record_t *record,
- int duplicate_index, uint32_t flags,
- uint32_t *new_duplicate_index) = 0;
-
- // Removes the record (or the duplicate of it, if |duplicate_index| is > 0).
- // If |all_duplicates| is set then all duplicates of this key are deleted.
- // |has_duplicates_left| will return true if there are more duplicates left
- // after the current one was deleted.
- virtual void erase_record(Context *context, int slot, int duplicate_index,
- bool all_duplicates, bool *has_duplicates_left) = 0;
-
- // High level function to remove an existing entry
- virtual void erase(Context *context, int slot) = 0;
-
- // Erases all extended keys, overflow areas and records that are
- // linked from this page; usually called when the Database is deleted
- // or an In-Memory Database is freed
- virtual void remove_all_entries(Context *context) = 0;
-
- // High level function to insert a new key. Only inserts the key. The
- // actual record is then updated with |set_record|.
- virtual PBtreeNode::InsertResult insert(Context *context, ham_key_t *key,
- uint32_t flags) = 0;
-
- // Returns true if a node requires a split to insert a new |key|
- virtual bool requires_split(Context *context, const ham_key_t *key = 0) = 0;
-
- // Returns true if a node requires a merge or a shift
- virtual bool requires_merge() const = 0;
-
- // Splits a page and moves all elements at a position >= |pivot|
- // to the |other| page. If the node is a leaf node then the pivot element
- // is also copied, otherwise it is not because it will be propagated
- // to the parent node instead (by the caller).
- virtual void split(Context *context, BtreeNodeProxy *other, int pivot) = 0;
-
- // Merges all keys from the |other| node to this node
- virtual void merge_from(Context *context, BtreeNodeProxy *other) = 0;
-
- // Fills the btree_metrics structure
- virtual void fill_metrics(btree_metrics_t *metrics) = 0;
-
- // Prints the node to stdout. Only for testing and debugging!
- virtual void print(Context *context, size_t node_count = 0) = 0;
-
- // Returns the class name. Only for testing! Uses the functions exported
- // by abi.h, which are only available on assorted platforms. Other
- // platforms will return empty strings.
- virtual std::string test_get_classname() const = 0;
-
- protected:
- Page *m_page;
-};
-
-//
-// A comparator which uses a user-supplied callback function (installed
-// with |ham_db_set_compare_func|) to compare two keys
-//
-struct CallbackCompare
-{
- CallbackCompare(LocalDatabase *db)
- : m_db(db) {
- }
-
- int operator()(const void *lhs_data, uint32_t lhs_size,
- const void *rhs_data, uint32_t rhs_size) const {
- return (m_db->compare_func()((::ham_db_t *)m_db, (uint8_t *)lhs_data,
- lhs_size, (uint8_t *)rhs_data, rhs_size));
- }
-
- LocalDatabase *m_db;
-};
-
-//
-// A comparator for numeric keys.
-// The actual type for the key is supplied with a template parameter.
-// This has to be a POD type with support for operators < and >.
-//
-template<typename T>
-struct NumericCompare
-{
- NumericCompare(LocalDatabase *) {
- }
-
- int operator()(const void *lhs_data, uint32_t lhs_size,
- const void *rhs_data, uint32_t rhs_size) const {
- ham_assert(lhs_size == rhs_size);
- ham_assert(lhs_size == sizeof(T));
- T l = *(T *)lhs_data;
- T r = *(T *)rhs_data;
- return (l < r ? -1 : (l > r ? +1 : 0));
- }
-};
-
-//
-// The default comparator for two keys, implemented with memcmp(3).
-// Both keys have the same size!
-//
-struct FixedSizeCompare
-{
- FixedSizeCompare(LocalDatabase *) {
- }
-
- int operator()(const void *lhs_data, uint32_t lhs_size,
- const void *rhs_data, uint32_t rhs_size) const {
- ham_assert(lhs_size == rhs_size);
- return (::memcmp(lhs_data, rhs_data, lhs_size));
- }
-};
-
-//
-// The default comparator for two keys, implemented with memcmp(3).
-// Both keys can have different sizes! shorter strings are treated as
-// "greater"
-//
-struct VariableSizeCompare
-{
- VariableSizeCompare(LocalDatabase *) {
- }
-
- int operator()(const void *lhs_data, uint32_t lhs_size,
- const void *rhs_data, uint32_t rhs_size) const {
- if (lhs_size < rhs_size) {
- int m = ::memcmp(lhs_data, rhs_data, lhs_size);
- return (m == 0 ? -1 : m);
- }
- if (rhs_size < lhs_size) {
- int m = ::memcmp(lhs_data, rhs_data, rhs_size);
- return (m == 0 ? +1 : m);
- }
- return (::memcmp(lhs_data, rhs_data, lhs_size));
- }
-};
-
-//
-// An implementation of the BtreeNodeProxy interface declared above.
-// Its actual memory implementation of the btree keys/records is delegated
-// to a template parameter |NodeImpl|, and the key comparisons are
-// delegated to |Comparator|.
-//
-template<class NodeImpl, class Comparator>
-class BtreeNodeProxyImpl : public BtreeNodeProxy
-{
- typedef BtreeNodeProxyImpl<NodeImpl, Comparator> ClassType;
-
- public:
- // Constructor
- BtreeNodeProxyImpl(Page *page)
- : BtreeNodeProxy(page), m_impl(page) {
- }
-
- // Returns the estimated capacity of this node
- virtual size_t estimate_capacity() const {
- return (m_impl.estimate_capacity());
- }
-
- // Checks the integrity of the node
- virtual void check_integrity(Context *context) const {
- m_impl.check_integrity(context);
- }
-
- // Iterates all keys, calls the |visitor| on each
- virtual void scan(Context *context, ScanVisitor *visitor,
- size_t start, bool distinct) {
- m_impl.scan(context, visitor, start, distinct);
- }
-
- // Compares two internal keys using the supplied comparator
- virtual int compare(const ham_key_t *lhs, const ham_key_t *rhs) const {
- Comparator cmp(m_page->get_db());
- return (cmp(lhs->data, lhs->size, rhs->data, rhs->size));
- }
-
- // Compares a public key and an internal key
- virtual int compare(Context *context, const ham_key_t *lhs, int rhs) {
- Comparator cmp(m_page->get_db());
- return (m_impl.compare(context, lhs, rhs, cmp));
- }
-
- // Returns true if the public key and an internal key are equal
- virtual bool equals(Context *context, const ham_key_t *lhs, int rhs) {
- return (0 == compare(context, lhs, rhs));
- }
-
- // Searches the node for the key and returns the slot of this key.
- // If |pcmp| is not null then it will store the result of the last
- // compare operation.
- virtual int find_child(Context *context, ham_key_t *key,
- uint64_t *precord_id = 0, int *pcmp = 0) {
- int dummy;
- if (get_count() == 0) {
- if (pcmp)
- *pcmp = 1;
- if (precord_id)
- *precord_id = get_ptr_down();
- return (-1);
- }
- Comparator cmp(m_page->get_db());
- return (m_impl.find_child(context, key, cmp,
- precord_id ? precord_id : 0,
- pcmp ? pcmp : &dummy));
- }
-
- // Searches the node for the |key|, but will always return -1 if
- // an exact match was not found
- virtual int find_exact(Context *context, ham_key_t *key) {
- if (get_count() == 0)
- return (-1);
- Comparator cmp(m_page->get_db());
- return (m_impl.find_exact(context, key, cmp));
- }
-
- // Returns the full key at the |slot|. Also resolves extended keys
- // and respects HAM_KEY_USER_ALLOC in dest->flags.
- virtual void get_key(Context *context, int slot, ByteArray *arena,
- ham_key_t *dest) {
- m_impl.get_key(context, slot, arena, dest);
- }
-
- // Returns the number of records of a key at the given |slot|
- virtual int get_record_count(Context *context, int slot) {
- ham_assert(slot < (int)get_count());
- return (m_impl.get_record_count(context, slot));
- }
-
- // Returns the full record and stores it in |dest|. The record is identified
- // by |slot| and |duplicate_index|. TINY and SMALL records are handled
- // correctly, as well as HAM_DIRECT_ACCESS.
- virtual void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags,
- int duplicate_index = 0) {
- ham_assert(slot < (int)get_count());
- m_impl.get_record(context, slot, arena, record, flags, duplicate_index);
- }
-
- virtual void set_record(Context *context, int slot, ham_record_t *record,
- int duplicate_index, uint32_t flags,
- uint32_t *new_duplicate_index) {
- m_impl.set_record(context, slot, record, duplicate_index, flags,
- new_duplicate_index);
- }
-
- // Returns the record size of a key or one of its duplicates
- virtual uint64_t get_record_size(Context *context, int slot,
- int duplicate_index) {
- ham_assert(slot < (int)get_count());
- return (m_impl.get_record_size(context, slot, duplicate_index));
- }
-
- // Returns the record id of the key at the given |slot|
- // Only for internal nodes!
- virtual uint64_t get_record_id(Context *context, int slot) const {
- ham_assert(slot < (int)get_count());
- return (m_impl.get_record_id(context, slot));
- }
-
- // Sets the record id of the key at the given |slot|
- // Only for internal nodes!
- virtual void set_record_id(Context *context, int slot, uint64_t id) {
- return (m_impl.set_record_id(context, slot, id));
- }
-
- // High level function to remove an existing entry. Will call
- // |erase_extended_key| to clean up (a potential) extended key,
- // and |erase_record| on each record that is associated with the key.
- virtual void erase(Context *context, int slot) {
- ham_assert(slot < (int)get_count());
- m_impl.erase(context, slot);
- set_count(get_count() - 1);
- }
-
- // Removes the record (or the duplicate of it, if |duplicate_index| is > 0).
- // If |all_duplicates| is set then all duplicates of this key are deleted.
- // |has_duplicates_left| will return true if there are more duplicates left
- // after the current one was deleted.
- virtual void erase_record(Context *context, int slot, int duplicate_index,
- bool all_duplicates, bool *has_duplicates_left) {
- ham_assert(slot < (int)get_count());
- m_impl.erase_record(context, slot, duplicate_index, all_duplicates);
- if (has_duplicates_left)
- *has_duplicates_left = get_record_count(context, slot) > 0;
- }
-
- // Erases all extended keys, overflow areas and records that are
- // linked from this page; usually called when the Database is deleted
- // or an In-Memory Database is closed
- virtual void remove_all_entries(Context *context) {
- size_t node_count = get_count();
- for (size_t i = 0; i < node_count; i++) {
- m_impl.erase_extended_key(context, i);
-
- // If we're in the leaf page, delete the associated record. (Only
- // leaf nodes have records; internal nodes have record IDs that
- // reference other pages, and these pages must not be deleted.)
- if (is_leaf())
- erase_record(context, i, 0, true, 0);
- }
- }
-
- // High level function to insert a new key. Only inserts the key. The
- // actual record is then updated with |set_record|.
- virtual PBtreeNode::InsertResult insert(Context *context,
- ham_key_t *key, uint32_t flags) {
- PBtreeNode::InsertResult result(0, 0);
- if (m_impl.requires_split(context, key)) {
- result.status = HAM_LIMITS_REACHED;
- return (result);
- }
-
- Comparator cmp(m_page->get_db());
- try {
- result = m_impl.insert(context, key, flags, cmp);
- }
- catch (Exception &ex) {
- result.status = ex.code;
- }
-
- // split required? then reorganize the node, try again
- if (result.status == HAM_LIMITS_REACHED) {
- try {
- if (m_impl.reorganize(context, key))
- result = m_impl.insert(context, key, flags, cmp);
- }
- catch (Exception &ex) {
- result.status = ex.code;
- }
- }
-
- if (result.status == HAM_SUCCESS)
- set_count(get_count() + 1);
-
- return (result);
- }
-
- // Returns true if a node requires a split to insert |key|
- virtual bool requires_split(Context *context, const ham_key_t *key = 0) {
- return (m_impl.requires_split(context, key));
- }
-
- // Returns true if a node requires a merge or a shift
- virtual bool requires_merge() const {
- return (m_impl.requires_merge());
- }
-
- // Splits the node
- virtual void split(Context *context, BtreeNodeProxy *other_node,
- int pivot) {
- ClassType *other = dynamic_cast<ClassType *>(other_node);
- ham_assert(other != 0);
-
- m_impl.split(context, &other->m_impl, pivot);
-
- size_t node_count = get_count();
- set_count(pivot);
-
- if (is_leaf())
- other->set_count(node_count - pivot);
- else
- other->set_count(node_count - pivot - 1);
- }
-
- // Merges all keys from the |other| node into this node
- virtual void merge_from(Context *context, BtreeNodeProxy *other_node) {
- ClassType *other = dynamic_cast<ClassType *>(other_node);
- ham_assert(other != 0);
-
- m_impl.merge_from(context, &other->m_impl);
-
- set_count(get_count() + other->get_count());
- other->set_count(0);
- }
-
- // Fills the btree_metrics structure
- virtual void fill_metrics(btree_metrics_t *metrics) {
- m_impl.fill_metrics(metrics, get_count());
- }
-
- // Prints the node to stdout (for debugging)
- virtual void print(Context *context, size_t node_count = 0) {
- std::cout << "page " << m_page->get_address() << ": " << get_count()
- << " elements (leaf: " << (is_leaf() ? 1 : 0) << ", left: "
- << get_left() << ", right: " << get_right() << ", ptr_down: "
- << get_ptr_down() << ")" << std::endl;
- if (!node_count)
- node_count = get_count();
- for (size_t i = 0; i < node_count; i++)
- m_impl.print(context, i);
- }
-
- // Returns the class name. Only for testing! Uses the functions exported
- // by abi.h, which are only available on assorted platforms. Other
- // platforms will return empty strings.
- virtual std::string test_get_classname() const {
- return (get_classname(*this));
- }
-
- private:
- NodeImpl m_impl;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_NODE_PROXY_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_base.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_base.h
deleted file mode 100644
index 6128c8834d..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_base.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Base class for RecordLists
- *
- * @exception_safe: nothrow
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_RECORDS_BASE_H
-#define HAM_BTREE_RECORDS_BASE_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct BaseRecordList
-{
- BaseRecordList()
- : m_range_size(0) {
- }
-
- // Checks the integrity of this node. Throws an exception if there is a
- // violation.
- void check_integrity(Context *context, size_t node_count) const {
- }
-
- // Rearranges the list
- void vacuumize(size_t node_count, bool force) const {
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BtreeStatistics::update_min_max_avg(&metrics->recordlist_ranges,
- m_range_size);
- }
-
- // The size of the range (in bytes)
- size_t m_range_size;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_RECORDS_BASE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_default.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_default.h
deleted file mode 100644
index 6fcb6f1cb7..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_default.h
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The DefaultRecordList provides simplified access to a list of records,
- * where each record is either a 8-byte record identifier (specifying the
- * address of a blob) or is stored inline, if the record's size is <= 8 bytes.
- *
- * Stores 1 byte of flags per record (see btree_flags.h).
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_RECORDS_DEFAULT_H
-#define HAM_BTREE_RECORDS_DEFAULT_H
-
-#include "0root/root.h"
-
-#include <sstream>
-#include <iostream>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_node.h"
-#include "3btree/btree_records_base.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// The template classes in this file are wrapped in a separate namespace
-// to avoid naming clashes with btree_impl_default.h
-//
-namespace PaxLayout {
-
-class DefaultRecordList : public BaseRecordList
-{
- public:
- enum {
- // A flag whether this RecordList has sequential data
- kHasSequentialData = 1
- };
-
- // Constructor
- DefaultRecordList(LocalDatabase *db, PBtreeNode *node)
- : m_db(db), m_flags(0), m_data(0) {
- }
-
- // Sets the data pointer; required for initialization
- void create(uint8_t *data, size_t range_size) {
- size_t capacity = range_size / get_full_record_size();
- m_range_size = range_size;
-
- if (m_db->config().record_size == HAM_RECORD_SIZE_UNLIMITED) {
- m_flags = data;
- m_data = (uint64_t *)&data[capacity];
- }
- else {
- m_flags = 0;
- m_data = (uint64_t *)data;
- }
- }
-
- // Opens an existing RecordList
- void open(uint8_t *data, size_t range_size, size_t node_count) {
- size_t capacity = range_size / get_full_record_size();
- m_range_size = range_size;
-
- if (m_db->config().record_size == HAM_RECORD_SIZE_UNLIMITED) {
- m_flags = data;
- m_data = (uint64_t *)&data[capacity];
- }
- else {
- m_flags = 0;
- m_data = (uint64_t *)data;
- }
- }
-
- // Calculates the required size for a range
- size_t get_required_range_size(size_t node_count) {
- return (node_count * get_full_record_size());
- }
-
- // Returns the actual record size including overhead
- size_t get_full_record_size() const {
- return (sizeof(uint64_t) +
- (m_db->config().record_size == HAM_RECORD_SIZE_UNLIMITED
- ? 1
- : 0));
- }
-
- // Returns the record counter of a key
- int get_record_count(Context *context, int slot) const {
- if (unlikely(!is_record_inline(slot) && get_record_id(slot) == 0))
- return (0);
- return (1);
- }
-
- // Returns the record size
- uint64_t get_record_size(Context *context, int slot,
- int duplicate_index = 0) const {
- if (is_record_inline(slot))
- return (get_inline_record_size(slot));
-
- LocalEnvironment *env = m_db->lenv();
- return (env->blob_manager()->get_blob_size(context, get_record_id(slot)));
- }
-
- // Returns the full record and stores it in |dest|; memory must be
- // allocated by the caller
- void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags,
- int duplicate_index) const {
- bool direct_access = (flags & HAM_DIRECT_ACCESS) != 0;
-
- // the record is stored inline
- if (is_record_inline(slot)) {
- record->size = get_inline_record_size(slot);
- if (record->size == 0) {
- record->data = 0;
- return;
- }
- if (flags & HAM_PARTIAL) {
- ham_trace(("flag HAM_PARTIAL is not allowed if record is "
- "stored inline"));
- throw Exception(HAM_INV_PARAMETER);
- }
- if (direct_access)
- record->data = (void *)&m_data[slot];
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, &m_data[slot], record->size);
- }
- return;
- }
-
- // the record is stored as a blob
- LocalEnvironment *env = m_db->lenv();
- env->blob_manager()->read(context, get_record_id(slot), record,
- flags, arena);
- }
-
- // Updates the record of a key
- void set_record(Context *context, int slot, int duplicate_index,
- ham_record_t *record, uint32_t flags,
- uint32_t *new_duplicate_index = 0) {
- uint64_t ptr = get_record_id(slot);
- LocalEnvironment *env = m_db->lenv();
-
- // key does not yet exist
- if (!ptr && !is_record_inline(slot)) {
- // a new inline key is inserted
- if (record->size <= sizeof(uint64_t)) {
- set_record_data(slot, record->data, record->size);
- }
- // a new (non-inline) key is inserted
- else {
- ptr = env->blob_manager()->allocate(context, record, flags);
- set_record_id(slot, ptr);
- }
- return;
- }
-
- // an inline key exists
- if (is_record_inline(slot)) {
- // disable small/tiny/empty flags
- set_record_flags(slot, get_record_flags(slot)
- & ~(BtreeRecord::kBlobSizeSmall
- | BtreeRecord::kBlobSizeTiny
- | BtreeRecord::kBlobSizeEmpty));
- // ... and is overwritten with another inline key
- if (record->size <= sizeof(uint64_t)) {
- set_record_data(slot, record->data, record->size);
- }
- // ... or with a (non-inline) key
- else {
- ptr = env->blob_manager()->allocate(context, record, flags);
- set_record_id(slot, ptr);
- }
- return;
- }
-
- // a (non-inline) key exists
- if (ptr) {
- // ... and is overwritten by a inline key
- if (record->size <= sizeof(uint64_t)) {
- env->blob_manager()->erase(context, ptr);
- set_record_data(slot, record->data, record->size);
- }
- // ... and is overwritten by a (non-inline) key
- else {
- ptr = env->blob_manager()->overwrite(context, ptr, record, flags);
- set_record_id(slot, ptr);
- }
- return;
- }
-
- ham_assert(!"shouldn't be here");
- throw Exception(HAM_INTERNAL_ERROR);
- }
-
- // Erases the record
- void erase_record(Context *context, int slot, int duplicate_index = 0,
- bool all_duplicates = true) {
- if (is_record_inline(slot)) {
- remove_inline_record(slot);
- return;
- }
-
- // now erase the blob
- m_db->lenv()->blob_manager()->erase(context, get_record_id(slot), 0);
- set_record_id(slot, 0);
- }
-
- // Erases a whole slot by shifting all larger records to the "left"
- void erase(Context *context, size_t node_count, int slot) {
- if (slot < (int)node_count - 1) {
- if (m_flags)
- memmove(&m_flags[slot], &m_flags[slot + 1], node_count - slot - 1);
- memmove(&m_data[slot], &m_data[slot + 1],
- sizeof(uint64_t) * (node_count - slot - 1));
- }
- }
-
- // Creates space for one additional record
- void insert(Context *context, size_t node_count, int slot) {
- if (slot < (int)node_count) {
- if (m_flags)
- memmove(&m_flags[slot + 1], &m_flags[slot], node_count - slot);
- memmove(&m_data[slot + 1], &m_data[slot],
- sizeof(uint64_t) * (node_count - slot));
- }
- if (m_flags)
- m_flags[slot] = 0;
- m_data[slot] = 0;
- }
-
- // Copies |count| records from this[sstart] to dest[dstart]
- void copy_to(int sstart, size_t node_count, DefaultRecordList &dest,
- size_t other_count, int dstart) {
- if (m_flags)
- memcpy(&dest.m_flags[dstart], &m_flags[sstart], (node_count - sstart));
- memcpy(&dest.m_data[dstart], &m_data[sstart],
- sizeof(uint64_t) * (node_count - sstart));
- }
-
- // Sets the record id
- void set_record_id(int slot, uint64_t ptr) {
- m_data[slot] = ptr;
- }
-
- // Returns the record id
- uint64_t get_record_id(int slot, int duplicate_index = 0) const {
- return (m_data[slot]);
- }
-
- // Returns true if there's not enough space for another record
- bool requires_split(size_t node_count) const {
- return ((node_count + 1) * get_full_record_size() >= m_range_size);
- }
-
- // Change the capacity; for PAX layouts this just means copying the
- // data from one place to the other
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t capacity_hint) {
- size_t new_capacity = capacity_hint
- ? capacity_hint
- : new_range_size / get_full_record_size();
- // shift "to the right"? then first shift key data, otherwise
- // the flags might overwrite the data
- if (m_flags == 0) {
- memmove(new_data_ptr, m_data, node_count * sizeof(uint64_t));
- }
- else {
- if (new_data_ptr > m_flags) {
- memmove(&new_data_ptr[new_capacity], m_data,
- node_count * sizeof(uint64_t));
- memmove(new_data_ptr, m_flags, node_count);
- }
- else {
- memmove(new_data_ptr, m_flags, node_count);
- memmove(&new_data_ptr[new_capacity], m_data,
- node_count * sizeof(uint64_t));
- }
- }
-
- if (m_db->config().record_size == HAM_RECORD_SIZE_UNLIMITED) {
- m_flags = new_data_ptr;
- m_data = (uint64_t *)&new_data_ptr[new_capacity];
- }
- else {
- m_flags = 0;
- m_data = (uint64_t *)new_data_ptr;
- }
- m_range_size = new_range_size;
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BaseRecordList::fill_metrics(metrics, node_count);
- BtreeStatistics::update_min_max_avg(&metrics->recordlist_unused,
- m_range_size - get_required_range_size(node_count));
- }
-
- // Prints a slot to |out| (for debugging)
- void print(Context *context, int slot, std::stringstream &out) const {
- out << "(" << get_record_size(context, slot) << " bytes)";
- }
-
- private:
- // Sets record data
- void set_record_data(int slot, const void *ptr, size_t size) {
- uint8_t flags = get_record_flags(slot);
- flags &= ~(BtreeRecord::kBlobSizeSmall
- | BtreeRecord::kBlobSizeTiny
- | BtreeRecord::kBlobSizeEmpty);
-
- if (size == 0) {
- m_data[slot] = 0;
- set_record_flags(slot, flags | BtreeRecord::kBlobSizeEmpty);
- }
- else if (size < 8) {
- /* the highest byte of the record id is the size of the blob */
- char *p = (char *)&m_data[slot];
- p[sizeof(uint64_t) - 1] = size;
- memcpy(&m_data[slot], ptr, size);
- set_record_flags(slot, flags | BtreeRecord::kBlobSizeTiny);
- }
- else if (size == 8) {
- memcpy(&m_data[slot], ptr, size);
- set_record_flags(slot, flags | BtreeRecord::kBlobSizeSmall);
- }
- else {
- ham_assert(!"shouldn't be here");
- set_record_flags(slot, flags);
- }
- }
-
- // Returns the record flags of a given |slot|
- uint8_t get_record_flags(int slot, int duplicate_index = 0)
- const {
- return (m_flags ? m_flags[slot] : 0);
- }
-
- // Sets the record flags of a given |slot|
- void set_record_flags(int slot, uint8_t flags) {
- ham_assert(m_flags != 0);
- m_flags[slot] = flags;
- }
-
- // Returns the size of an inline record
- uint32_t get_inline_record_size(int slot) const {
- uint8_t flags = get_record_flags(slot);
- ham_assert(is_record_inline(slot));
- if (flags & BtreeRecord::kBlobSizeTiny) {
- /* the highest byte of the record id is the size of the blob */
- char *p = (char *)&m_data[slot];
- return (p[sizeof(uint64_t) - 1]);
- }
- if (flags & BtreeRecord::kBlobSizeSmall)
- return (sizeof(uint64_t));
- if (flags & BtreeRecord::kBlobSizeEmpty)
- return (0);
- ham_assert(!"shouldn't be here");
- return (0);
- }
-
- // Returns true if the record is inline, false if the record is a blob
- bool is_record_inline(int slot) const {
- uint8_t flags = get_record_flags(slot);
- return ((flags & BtreeRecord::kBlobSizeTiny)
- || (flags & BtreeRecord::kBlobSizeSmall)
- || (flags & BtreeRecord::kBlobSizeEmpty) != 0);
- }
-
- // Removes an inline record; returns the updated record flags
- void remove_inline_record(int slot) {
- uint8_t flags = get_record_flags(slot);
- m_data[slot] = 0;
- set_record_flags(slot,
- flags & ~(BtreeRecord::kBlobSizeSmall
- | BtreeRecord::kBlobSizeTiny
- | BtreeRecord::kBlobSizeEmpty));
- }
-
- // The parent database of this btree
- LocalDatabase *m_db;
-
- // The record flags
- uint8_t *m_flags;
-
- // The actual record data - an array of 64bit record IDs
- uint64_t *m_data;
-};
-
-} // namespace PaxLayout
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_RECORDS_DEFAULT_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_duplicate.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_duplicate.h
deleted file mode 100644
index 861f7a7640..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_duplicate.h
+++ /dev/null
@@ -1,1557 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * RecordList implementations for duplicate records
- *
- * Duplicate records are stored inline till a certain threshold limit
- * (m_duptable_threshold) is reached. In this case the duplicates are stored
- * in a separate blob (the DuplicateTable), and the previously occupied storage
- * in the node is reused for other records.
- *
- * Since records therefore have variable length, an UpfrontIndex is used
- * (see btree_keys_varlen.h).
- *
- * This file has two RecordList implementations:
- *
- * - DuplicateRecordList: stores regular records as duplicates; records
- * are stored as blobs if their size exceeds 8 bytes. Otherwise
- * they are stored inline.
- *
- * - DuplicateInlineRecordList: stores small fixed length records as
- * duplicates
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_RECORDS_DUPLICATE_H
-#define HAM_BTREE_RECORDS_DUPLICATE_H
-
-#include "0root/root.h"
-
-#include <algorithm>
-#include <iostream>
-#include <vector>
-#include <map>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/scoped_ptr.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_node.h"
-#include "3btree/btree_index.h"
-#include "3btree/upfront_index.h"
-#include "3btree/btree_records_base.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-namespace DefLayout {
-
-// helper function which returns true if a record is inline
-static bool is_record_inline(uint8_t flags) {
- return (flags != 0);
-}
-
-//
-// A helper class for dealing with extended duplicate tables
-//
-// Byte [0..3] - count
-// [4..7] - capacity
-// [8.. [ - the record list
-// if m_inline_records:
-// each record has n bytes record-data
-// else
-// each record has 1 byte flags, n bytes record-data
-//
-class DuplicateTable
-{
- public:
- // Constructor; the flag |inline_records| indicates whether record
- // flags should be stored for each record. |record_size| is the
- // fixed length size of each record, or HAM_RECORD_SIZE_UNLIMITED
- DuplicateTable(LocalDatabase *db, bool inline_records, size_t record_size)
- : m_db(db), m_store_flags(!inline_records), m_record_size(record_size),
- m_inline_records(inline_records), m_table_id(0) {
- }
-
- // Allocates and fills the table; returns the new table id.
- // Can allocate empty tables (required for testing purposes).
- // The initial capacity of the table is twice the current
- // |record_count|.
- uint64_t create(Context *context, const uint8_t *data,
- size_t record_count) {
- ham_assert(m_table_id == 0);
-
- // This sets the initial capacity as described above
- size_t capacity = record_count * 2;
- m_table.resize(8 + capacity * get_record_width());
- if (likely(record_count > 0))
- m_table.overwrite(8, data, (m_inline_records
- ? m_record_size * record_count
- : 9 * record_count));
-
- set_record_count(record_count);
- set_record_capacity(record_count * 2);
-
- // Flush the table to disk, returns the blob-id of the table
- return (flush_duplicate_table(context));
- }
-
- // Reads the table from disk
- void open(Context *context, uint64_t table_id) {
- ham_record_t record = {0};
- m_db->lenv()->blob_manager()->read(context, table_id,
- &record, HAM_FORCE_DEEP_COPY, &m_table);
- m_table_id = table_id;
- }
-
- // Returns the number of duplicates in that table
- int get_record_count() const {
- ham_assert(m_table.get_size() > 4);
- return ((int) *(uint32_t *)m_table.get_ptr());
- }
-
- // Returns the record size of a duplicate
- uint64_t get_record_size(Context *context, int duplicate_index) {
- ham_assert(duplicate_index < get_record_count());
- if (m_inline_records)
- return (m_record_size);
- ham_assert(m_store_flags == true);
-
- uint8_t *precord_flags;
- uint8_t *p = get_record_data(duplicate_index, &precord_flags);
- uint8_t flags = *precord_flags;
-
- if (flags & BtreeRecord::kBlobSizeTiny)
- return (p[sizeof(uint64_t) - 1]);
- if (flags & BtreeRecord::kBlobSizeSmall)
- return (sizeof(uint64_t));
- if (flags & BtreeRecord::kBlobSizeEmpty)
- return (0);
-
- uint64_t blob_id = *(uint64_t *)p;
- return (m_db->lenv()->blob_manager()->get_blob_size(context, blob_id));
- }
-
- // Returns the full record and stores it in |record|. |flags| can
- // be 0 or |HAM_DIRECT_ACCESS|, |HAM_PARTIAL|. These are the default
- // flags of ham_db_find et al.
- void get_record(Context *context, ByteArray *arena, ham_record_t *record,
- uint32_t flags, int duplicate_index) {
- ham_assert(duplicate_index < get_record_count());
- bool direct_access = (flags & HAM_DIRECT_ACCESS) != 0;
-
- uint8_t *precord_flags;
- uint8_t *p = get_record_data(duplicate_index, &precord_flags);
- uint8_t record_flags = precord_flags ? *precord_flags : 0;
-
- if (m_inline_records) {
- if (flags & HAM_PARTIAL) {
- ham_trace(("flag HAM_PARTIAL is not allowed if record is "
- "stored inline"));
- throw Exception(HAM_INV_PARAMETER);
- }
-
- record->size = m_record_size;
- if (direct_access)
- record->data = p;
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, p, m_record_size);
- }
- return;
- }
-
- ham_assert(m_store_flags == true);
-
- if (record_flags & BtreeRecord::kBlobSizeEmpty) {
- record->data = 0;
- record->size = 0;
- return;
- }
-
- if (record_flags & BtreeRecord::kBlobSizeTiny) {
- record->size = p[sizeof(uint64_t) - 1];
- if (direct_access)
- record->data = &p[0];
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, &p[0], record->size);
- }
- return;
- }
-
- if (record_flags & BtreeRecord::kBlobSizeSmall) {
- record->size = sizeof(uint64_t);
- if (direct_access)
- record->data = &p[0];
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, &p[0], record->size);
- }
- return;
- }
-
- uint64_t blob_id = *(uint64_t *)p;
-
- // the record is stored as a blob
- LocalEnvironment *env = m_db->lenv();
- env->blob_manager()->read(context, blob_id, record, flags, arena);
- }
-
- // Updates the record of a key. Analog to the set_record() method
- // of the NodeLayout class. Returns the new table id and the
- // new duplicate index, if |new_duplicate_index| is not null.
- uint64_t set_record(Context *context, int duplicate_index,
- ham_record_t *record, uint32_t flags,
- uint32_t *new_duplicate_index) {
- BlobManager *blob_manager = m_db->lenv()->blob_manager();
-
- // the duplicate is overwritten
- if (flags & HAM_OVERWRITE) {
- uint8_t *record_flags = 0;
- uint8_t *p = get_record_data(duplicate_index, &record_flags);
-
- // the record is stored inline w/ fixed length?
- if (m_inline_records) {
- ham_assert(record->size == m_record_size);
- memcpy(p, record->data, record->size);
- return (flush_duplicate_table(context));
- }
- // the existing record is a blob
- if (!is_record_inline(*record_flags)) {
- uint64_t ptr = *(uint64_t *)p;
- // overwrite the blob record
- if (record->size > sizeof(uint64_t)) {
- *(uint64_t *)p = blob_manager->overwrite(context, ptr,
- record, flags);
- return (flush_duplicate_table(context));
- }
- // otherwise delete it and continue
- blob_manager->erase(context, ptr, 0);
- }
- }
-
- // If the key is not overwritten but inserted or appended: create a
- // "gap" in the table
- else {
- int record_count = get_record_count();
-
- // check for overflow
- if (unlikely(record_count == std::numeric_limits<int>::max())) {
- ham_log(("Duplicate table overflow"));
- throw Exception(HAM_LIMITS_REACHED);
- }
-
- // adjust flags
- if (flags & HAM_DUPLICATE_INSERT_BEFORE && duplicate_index == 0)
- flags |= HAM_DUPLICATE_INSERT_FIRST;
- else if (flags & HAM_DUPLICATE_INSERT_AFTER) {
- if (duplicate_index == record_count)
- flags |= HAM_DUPLICATE_INSERT_LAST;
- else {
- flags |= HAM_DUPLICATE_INSERT_BEFORE;
- duplicate_index++;
- }
- }
-
- // resize the table, if necessary
- if (unlikely(record_count == get_record_capacity()))
- grow_duplicate_table();
-
- // handle overwrites or inserts/appends
- if (flags & HAM_DUPLICATE_INSERT_FIRST) {
- if (record_count) {
- uint8_t *ptr = get_raw_record_data(0);
- memmove(ptr + get_record_width(), ptr,
- record_count * get_record_width());
- }
- duplicate_index = 0;
- }
- else if (flags & HAM_DUPLICATE_INSERT_BEFORE) {
- uint8_t *ptr = get_raw_record_data(duplicate_index);
- memmove(ptr + get_record_width(), ptr,
- (record_count - duplicate_index) * get_record_width());
- }
- else // HAM_DUPLICATE_INSERT_LAST
- duplicate_index = record_count;
-
- set_record_count(record_count + 1);
- }
-
- uint8_t *record_flags = 0;
- uint8_t *p = get_record_data(duplicate_index, &record_flags);
-
- // store record inline?
- if (m_inline_records) {
- ham_assert(m_record_size == record->size);
- if (m_record_size > 0)
- memcpy(p, record->data, record->size);
- }
- else if (record->size == 0) {
- memcpy(p, "\0\0\0\0\0\0\0\0", 8);
- *record_flags = BtreeRecord::kBlobSizeEmpty;
- }
- else if (record->size < sizeof(uint64_t)) {
- p[sizeof(uint64_t) - 1] = (uint8_t)record->size;
- memcpy(&p[0], record->data, record->size);
- *record_flags = BtreeRecord::kBlobSizeTiny;
- }
- else if (record->size == sizeof(uint64_t)) {
- memcpy(&p[0], record->data, record->size);
- *record_flags = BtreeRecord::kBlobSizeSmall;
- }
- else {
- *record_flags = 0;
- uint64_t blob_id = blob_manager->allocate(context, record, flags);
- memcpy(p, &blob_id, sizeof(blob_id));
- }
-
- if (new_duplicate_index)
- *new_duplicate_index = duplicate_index;
-
- // write the duplicate table to disk and return the table-id
- return (flush_duplicate_table(context));
- }
-
- // Deletes a record from the table; also adjusts the count. If
- // |all_duplicates| is true or if the last element of the table is
- // deleted then the table itself will also be deleted. Returns 0
- // if this is the case, otherwise returns the table id.
- uint64_t erase_record(Context *context, int duplicate_index,
- bool all_duplicates) {
- int record_count = get_record_count();
-
- if (record_count == 1 && duplicate_index == 0)
- all_duplicates = true;
-
- if (all_duplicates) {
- if (m_store_flags && !m_inline_records) {
- for (int i = 0; i < record_count; i++) {
- uint8_t *record_flags;
- uint8_t *p = get_record_data(i, &record_flags);
- if (is_record_inline(*record_flags))
- continue;
- if (*(uint64_t *)p != 0) {
- m_db->lenv()->blob_manager()->erase(context, *(uint64_t *)p);
- *(uint64_t *)p = 0;
- }
- }
- }
- if (m_table_id != 0)
- m_db->lenv()->blob_manager()->erase(context, m_table_id);
- set_record_count(0);
- m_table_id = 0;
- return (0);
- }
-
- ham_assert(record_count > 0 && duplicate_index < record_count);
-
- uint8_t *record_flags;
- uint8_t *lhs = get_record_data(duplicate_index, &record_flags);
- if (record_flags != 0 && *record_flags == 0 && !m_inline_records) {
- m_db->lenv()->blob_manager()->erase(context, *(uint64_t *)lhs);
- *(uint64_t *)lhs = 0;
- }
-
- if (duplicate_index < record_count - 1) {
- lhs = get_raw_record_data(duplicate_index);
- uint8_t *rhs = lhs + get_record_width();
- memmove(lhs, rhs, get_record_width()
- * (record_count - duplicate_index - 1));
- }
-
- // adjust the counter
- set_record_count(record_count - 1);
-
- // write the duplicate table to disk and return the table-id
- return (flush_duplicate_table(context));
- }
-
- // Returns the maximum capacity of elements in a duplicate table
- // This method could be private, but it's required by the unittests
- int get_record_capacity() const {
- ham_assert(m_table.get_size() >= 8);
- return ((int) *(uint32_t *)((uint8_t *)m_table.get_ptr() + 4));
- }
-
- private:
- // Doubles the capacity of the ByteArray which backs the table
- void grow_duplicate_table() {
- int capacity = get_record_capacity();
- if (capacity == 0)
- capacity = 8;
- m_table.resize(8 + (capacity * 2) * get_record_width());
- set_record_capacity(capacity * 2);
- }
-
- // Writes the modified duplicate table to disk; returns the new
- // table-id
- uint64_t flush_duplicate_table(Context *context) {
- ham_record_t record = {0};
- record.data = m_table.get_ptr();
- record.size = m_table.get_size();
- if (!m_table_id)
- m_table_id = m_db->lenv()->blob_manager()->allocate(
- context, &record, 0);
- else
- m_table_id = m_db->lenv()->blob_manager()->overwrite(
- context, m_table_id, &record, 0);
- return (m_table_id);
- }
-
- // Returns the size of a record structure in the ByteArray
- size_t get_record_width() const {
- if (m_inline_records)
- return (m_record_size);
- ham_assert(m_store_flags == true);
- return (sizeof(uint64_t) + 1);
- }
-
- // Returns a pointer to the record data (including flags)
- uint8_t *get_raw_record_data(int duplicate_index) {
- if (m_inline_records)
- return ((uint8_t *)m_table.get_ptr()
- + 8
- + m_record_size * duplicate_index);
- else
- return ((uint8_t *)m_table.get_ptr()
- + 8
- + 9 * duplicate_index);
- }
-
- // Returns a pointer to the record data, and the flags
- uint8_t *get_record_data(int duplicate_index,
- uint8_t **pflags = 0) {
- uint8_t *p = get_raw_record_data(duplicate_index);
- if (m_store_flags) {
- if (pflags)
- *pflags = p++;
- else
- p++;
- }
- else if (pflags)
- *pflags = 0;
- return (p);
- }
-
- // Sets the number of used elements in a duplicate table
- void set_record_count(int record_count) {
- *(uint32_t *)m_table.get_ptr() = (uint32_t)record_count;
- }
-
- // Sets the maximum capacity of elements in a duplicate table
- void set_record_capacity(int capacity) {
- ham_assert(m_table.get_size() >= 8);
- *(uint32_t *)((uint8_t *)m_table.get_ptr() + 4) = (uint32_t)capacity;
- }
-
- // The database
- LocalDatabase *m_db;
-
- // Whether to store flags per record or not (true unless records
- // have constant length)
- bool m_store_flags;
-
- // The constant length record size, or HAM_RECORD_SIZE_UNLIMITED
- size_t m_record_size;
-
- // Stores the actual data of the table
- ByteArray m_table;
-
- // True if records are inline
- bool m_inline_records;
-
- // The blob id for persisting the table
- uint64_t m_table_id;
-};
-
-//
-// Common functions for duplicate record lists
-//
-class DuplicateRecordList : public BaseRecordList
-{
- protected:
- // for caching external duplicate tables
- typedef std::map<uint64_t, DuplicateTable *> DuplicateTableCache;
-
- public:
- enum {
- // A flag whether this RecordList has sequential data
- kHasSequentialData = 0
- };
-
- // Constructor
- DuplicateRecordList(LocalDatabase *db, PBtreeNode *node,
- bool store_flags, size_t record_size)
- : m_db(db), m_node(node), m_index(db), m_data(0),
- m_store_flags(store_flags), m_record_size(record_size) {
- size_t page_size = db->lenv()->config().page_size_bytes;
- if (Globals::ms_duplicate_threshold)
- m_duptable_threshold = Globals::ms_duplicate_threshold;
- else {
- if (page_size == 1024)
- m_duptable_threshold = 8;
- else if (page_size <= 1024 * 8)
- m_duptable_threshold = 12;
- else if (page_size <= 1024 * 16)
- m_duptable_threshold = 20;
- else if (page_size <= 1024 * 32)
- m_duptable_threshold = 32;
- else {
- // 0x7f/127 is the maximum that we can store in the record
- // counter (7 bits), but we won't exploit this fully
- m_duptable_threshold = 64;
- }
- }
-
- // UpfrontIndex's chunk_size is just 1 byte (max 255); make sure that
- // the duplicate list fits into a single chunk!
- size_t rec_size = m_record_size;
- if (rec_size == HAM_RECORD_SIZE_UNLIMITED)
- rec_size = 9;
- if (m_duptable_threshold * rec_size > 250)
- m_duptable_threshold = 250 / rec_size;
- }
-
- // Destructor - clears the cache
- ~DuplicateRecordList() {
- if (m_duptable_cache) {
- for (DuplicateTableCache::iterator it = m_duptable_cache->begin();
- it != m_duptable_cache->end(); it++)
- delete it->second;
- }
- }
-
- // Opens an existing RecordList
- void open(uint8_t *ptr, size_t range_size, size_t node_count) {
- m_data = ptr;
- m_index.open(m_data, range_size);
- m_range_size = range_size;
- }
-
- // Returns a duplicate table; uses a cache to speed up access
- DuplicateTable *get_duplicate_table(Context *context, uint64_t table_id) {
- if (!m_duptable_cache)
- m_duptable_cache.reset(new DuplicateTableCache());
- else {
- DuplicateTableCache::iterator it = m_duptable_cache->find(table_id);
- if (it != m_duptable_cache->end())
- return (it->second);
- }
-
- DuplicateTable *dt = new DuplicateTable(m_db, !m_store_flags,
- m_record_size);
- dt->open(context, table_id);
- (*m_duptable_cache)[table_id] = dt;
- return (dt);
- }
-
- // Updates the DupTableCache and changes the table id of a DuplicateTable.
- // Called whenever a DuplicateTable's size increases, and the new blob-id
- // differs from the old one.
- void update_duplicate_table_id(DuplicateTable *dt,
- uint64_t old_table_id, uint64_t new_table_id) {
- m_duptable_cache->erase(old_table_id);
- (*m_duptable_cache)[new_table_id] = dt;
- }
-
- // Erases a slot. Only updates the UpfrontIndex; does NOT delete the
- // record blobs!
- void erase(Context *context, size_t node_count, int slot) {
- m_index.erase(node_count, slot);
- }
-
- // Inserts a slot for one additional record
- void insert(Context *context, size_t node_count, int slot) {
- m_index.insert(node_count, slot);
- }
-
- // Copies |count| items from this[sstart] to dest[dstart]
- void copy_to(int sstart, size_t node_count,
- DuplicateRecordList &dest, size_t other_node_count,
- int dstart) {
- // make sure that the other node has sufficient capacity in its
- // UpfrontIndex
- dest.m_index.change_range_size(other_node_count, 0, 0,
- m_index.get_capacity());
-
- uint32_t doffset;
- for (size_t i = 0; i < node_count - sstart; i++) {
- size_t size = m_index.get_chunk_size(sstart + i);
-
- dest.m_index.insert(other_node_count + i, dstart + i);
- // destination offset
- doffset = dest.m_index.allocate_space(other_node_count + i + 1,
- dstart + i, size);
- doffset = dest.m_index.get_absolute_offset(doffset);
- // source offset
- uint32_t soffset = m_index.get_chunk_offset(sstart + i);
- soffset = m_index.get_absolute_offset(soffset);
- // copy the data
- memcpy(&dest.m_data[doffset], &m_data[soffset], size);
- }
-
- // After copying, the caller will reduce the node count drastically.
- // Therefore invalidate the cached next_offset.
- m_index.invalidate_next_offset();
- }
-
- // Rearranges the list
- void vacuumize(size_t node_count, bool force) {
- if (force)
- m_index.increase_vacuumize_counter(100);
- m_index.maybe_vacuumize(node_count);
- }
-
- protected:
- // The database
- LocalDatabase *m_db;
-
- // The current node
- PBtreeNode *m_node;
-
- // The index which manages variable length chunks
- UpfrontIndex m_index;
-
- // The actual data of the node
- uint8_t *m_data;
-
- // Whether record flags are required
- bool m_store_flags;
-
- // The constant record size, or HAM_RECORD_SIZE_UNLIMITED
- size_t m_record_size;
-
- // The duplicate threshold
- size_t m_duptable_threshold;
-
- // A cache for duplicate tables
- ScopedPtr<DuplicateTableCache> m_duptable_cache;
-};
-
-//
-// RecordList for records with fixed length, with duplicates. It uses
-// an UpfrontIndex to manage the variable length chunks.
-//
-// If a key has duplicates, then all duplicates are stored sequentially.
-// If that duplicate list exceeds a certain threshold then they are moved
-// to a DuplicateTable, which is stored as a blob.
-//
-// Format for each slot:
-//
-// 1 byte meta data
-// bit 1 - 7: duplicate counter, if kExtendedDuplicates == 0
-// bit 8: kExtendedDuplicates
-// if kExtendedDuplicates == 0:
-// <counter> * <length> bytes
-// <length> byte data (always inline)
-// if kExtendedDuplicates == 1:
-// 8 byte: record id of the extended duplicate table
-//
-class DuplicateInlineRecordList : public DuplicateRecordList
-{
- public:
- // Constructor
- DuplicateInlineRecordList(LocalDatabase *db, PBtreeNode *node)
- : DuplicateRecordList(db, node, false, db->config().record_size),
- m_record_size(db->config().record_size) {
- }
-
- // Creates a new RecordList starting at |data|
- void create(uint8_t *data, size_t range_size) {
- m_data = data;
- m_index.create(m_data, range_size, range_size / get_full_record_size());
- m_range_size = range_size;
- }
-
- // Calculates the required size for a range with the specified |capacity|
- size_t get_required_range_size(size_t node_count) const {
- return (m_index.get_required_range_size(node_count));
- }
-
- // Returns the actual record size including overhead
- size_t get_full_record_size() const {
- return (1 + m_record_size + m_index.get_full_index_size());
- }
-
- // Returns the number of duplicates for a slot
- int get_record_count(Context *context, int slot) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- if (m_data[offset] & BtreeRecord::kExtendedDuplicates) {
- DuplicateTable *dt = get_duplicate_table(context, get_record_id(slot));
- return ((int)dt->get_record_count());
- }
-
- return (m_data[offset] & 0x7f);
- }
-
- // Returns the size of a record; the size is always constant
- uint64_t get_record_size(Context *context, int slot,
- int duplicate_index = 0) const {
- return (m_record_size);
- }
-
- // Returns the full record and stores it in |dest|
- void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags,
- int duplicate_index) {
- // forward to duplicate table?
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- if (unlikely(m_data[offset] & BtreeRecord::kExtendedDuplicates)) {
- DuplicateTable *dt = get_duplicate_table(context, get_record_id(slot));
- dt->get_record(context, arena, record, flags, duplicate_index);
- return;
- }
-
- if (flags & HAM_PARTIAL) {
- ham_trace(("flag HAM_PARTIAL is not allowed if record is "
- "stored inline"));
- throw Exception(HAM_INV_PARAMETER);
- }
-
- ham_assert(duplicate_index < (int)get_inline_record_count(slot));
- bool direct_access = (flags & HAM_DIRECT_ACCESS) != 0;
-
- // the record is always stored inline
- const uint8_t *ptr = get_record_data(slot, duplicate_index);
- record->size = m_record_size;
- if (direct_access)
- record->data = (void *)ptr;
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, ptr, m_record_size);
- }
- }
-
- // Adds or overwrites a record
- void set_record(Context *context, int slot, int duplicate_index,
- ham_record_t *record, uint32_t flags,
- uint32_t *new_duplicate_index = 0) {
- uint32_t chunk_offset = m_index.get_absolute_chunk_offset(slot);
- uint32_t current_size = m_index.get_chunk_size(slot);
-
- ham_assert(m_record_size == record->size);
-
- // if the slot was not yet allocated: allocate new space, initialize
- // it and then overwrite the record
- if (current_size == 0) {
- duplicate_index = 0;
- flags |= HAM_OVERWRITE;
- chunk_offset = m_index.allocate_space(m_node->get_count(), slot,
- 1 + m_record_size);
- chunk_offset = m_index.get_absolute_offset(chunk_offset);
- // clear the flags
- m_data[chunk_offset] = 0;
-
- set_inline_record_count(slot, 1);
- }
-
- // if there's no duplicate table, but we're not able to add another
- // duplicate because of size constraints, then offload all
- // existing duplicates to an external DuplicateTable
- uint32_t record_count = get_inline_record_count(slot);
- size_t required_size = 1 + (record_count + 1) * m_record_size;
-
- if (!(m_data[chunk_offset] & BtreeRecord::kExtendedDuplicates)
- && !(flags & HAM_OVERWRITE)) {
- bool force_duptable = record_count >= m_duptable_threshold;
- if (!force_duptable
- && !m_index.can_allocate_space(m_node->get_count(),
- required_size))
- force_duptable = true;
-
- // update chunk_offset - it might have been modified if
- // m_index.can_allocate_space triggered a vacuumize() operation
- chunk_offset = m_index.get_absolute_chunk_offset(slot);
-
- // already too many duplicates, or the record does not fit? then
- // allocate an overflow duplicate list and move all duplicates to
- // this list
- if (force_duptable) {
- DuplicateTable *dt = new DuplicateTable(m_db, !m_store_flags,
- m_record_size);
- uint64_t table_id = dt->create(context, get_record_data(slot, 0),
- record_count);
- if (!m_duptable_cache)
- m_duptable_cache.reset(new DuplicateTableCache());
- (*m_duptable_cache)[table_id] = dt;
-
- // write the id of the duplicate table
- if (m_index.get_chunk_size(slot) < 8 + 1) {
- // do not erase the slot because it occupies so little space
- size_t node_count = m_node->get_count();
- // force a split in the caller if the duplicate table cannot
- // be inserted
- if (!m_index.can_allocate_space(node_count, 8 + 1))
- throw Exception(HAM_LIMITS_REACHED);
- m_index.allocate_space(node_count, slot, 8 + 1);
- chunk_offset = m_index.get_absolute_chunk_offset(slot);
- }
-
- m_data[chunk_offset] |= BtreeRecord::kExtendedDuplicates;
- set_record_id(slot, table_id);
- set_inline_record_count(slot, 0);
-
- m_index.set_chunk_size(slot, 8 + 1);
- m_index.increase_vacuumize_counter(m_index.get_chunk_size(slot) - 9);
- m_index.invalidate_next_offset();
-
- // fall through
- }
- }
-
- // forward to duplicate table?
- if (unlikely(m_data[chunk_offset] & BtreeRecord::kExtendedDuplicates)) {
- uint64_t table_id = get_record_id(slot);
- DuplicateTable *dt = get_duplicate_table(context, table_id);
- uint64_t new_table_id = dt->set_record(context, duplicate_index, record,
- flags, new_duplicate_index);
- if (new_table_id != table_id) {
- update_duplicate_table_id(dt, table_id, new_table_id);
- set_record_id(slot, new_table_id);
- }
- return;
- }
-
- // the duplicate is overwritten
- if (flags & HAM_OVERWRITE) {
- // the record is always stored inline w/ fixed length
- uint8_t *p = (uint8_t *)get_record_data(slot, duplicate_index);
- memcpy(p, record->data, record->size);
- return;
- }
-
- // Allocate new space for the duplicate table, if required
- if (current_size < required_size) {
- uint8_t *oldp = &m_data[chunk_offset];
- uint32_t old_chunk_size = m_index.get_chunk_size(slot);
- uint32_t old_chunk_offset = m_index.get_chunk_offset(slot);
- uint32_t new_chunk_offset = m_index.allocate_space(m_node->get_count(),
- slot, required_size);
- chunk_offset = m_index.get_absolute_offset(new_chunk_offset);
- if (current_size > 0 && old_chunk_offset != new_chunk_offset) {
- memmove(&m_data[chunk_offset], oldp, current_size);
- m_index.add_to_freelist(m_node->get_count(), old_chunk_offset,
- old_chunk_size);
- }
- }
-
- // adjust flags
- if (flags & HAM_DUPLICATE_INSERT_BEFORE && duplicate_index == 0)
- flags |= HAM_DUPLICATE_INSERT_FIRST;
- else if (flags & HAM_DUPLICATE_INSERT_AFTER) {
- if (duplicate_index == (int)record_count)
- flags |= HAM_DUPLICATE_INSERT_LAST;
- else {
- flags |= HAM_DUPLICATE_INSERT_BEFORE;
- duplicate_index++;
- }
- }
-
- // handle overwrites or inserts/appends
- if (flags & HAM_DUPLICATE_INSERT_FIRST) {
- if (record_count > 0) {
- uint8_t *ptr = get_record_data(slot, 0);
- memmove(get_record_data(slot, 1), ptr, record_count * m_record_size);
- }
- duplicate_index = 0;
- }
- else if (flags & HAM_DUPLICATE_INSERT_BEFORE) {
- memmove(get_record_data(slot, duplicate_index),
- get_record_data(slot, duplicate_index + 1),
- (record_count - duplicate_index) * m_record_size);
- }
- else // HAM_DUPLICATE_INSERT_LAST
- duplicate_index = record_count;
-
- set_inline_record_count(slot, record_count + 1);
-
- // store the new record inline
- if (m_record_size > 0)
- memcpy(get_record_data(slot, duplicate_index),
- record->data, record->size);
-
- if (new_duplicate_index)
- *new_duplicate_index = duplicate_index;
- }
-
- // Erases a record's blob (does not remove the slot!)
- void erase_record(Context *context, int slot, int duplicate_index = 0,
- bool all_duplicates = false) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
-
- // forward to external duplicate table?
- if (unlikely(m_data[offset] & BtreeRecord::kExtendedDuplicates)) {
- uint64_t table_id = get_record_id(slot);
- DuplicateTable *dt = get_duplicate_table(context, table_id);
- uint64_t new_table_id = dt->erase_record(context, duplicate_index,
- all_duplicates);
- if (new_table_id == 0) {
- m_duptable_cache->erase(table_id);
- set_record_id(slot, 0);
- m_data[offset] &= ~BtreeRecord::kExtendedDuplicates;
- delete dt;
- }
- else if (new_table_id != table_id) {
- update_duplicate_table_id(dt, table_id, new_table_id);
- set_record_id(slot, new_table_id);
- }
- return;
- }
-
- // there's only one record left which is erased?
- size_t node_count = get_inline_record_count(slot);
- if (node_count == 1 && duplicate_index == 0)
- all_duplicates = true;
-
- // erase all duplicates?
- if (all_duplicates) {
- set_inline_record_count(slot, 0);
- }
- else {
- if (duplicate_index < (int)node_count - 1)
- memmove(get_record_data(duplicate_index),
- get_record_data(duplicate_index + 1),
- m_record_size * (node_count - duplicate_index - 1));
- set_inline_record_count(slot, node_count - 1);
- }
- }
-
- // Returns a 64bit record id from a record
- uint64_t get_record_id(int slot,
- int duplicate_index = 0) const {
- return (*(uint64_t *)get_record_data(slot, duplicate_index));
- }
-
- // Sets a 64bit record id; used for internal nodes to store Page IDs
- // or for leaf nodes to store DuplicateTable IDs
- void set_record_id(int slot, uint64_t id) {
- ham_assert(m_index.get_chunk_size(slot) >= sizeof(id));
- *(uint64_t *)get_record_data(slot, 0) = id;
- }
-
- // Checks the integrity of this node. Throws an exception if there is a
- // violation.
- void check_integrity(Context *context, size_t node_count,
- bool quick = false) const {
- for (size_t i = 0; i < node_count; i++) {
- uint32_t offset = m_index.get_absolute_chunk_offset(i);
- if (m_data[offset] & BtreeRecord::kExtendedDuplicates) {
- ham_assert((m_data[offset] & 0x7f) == 0);
- }
- }
-
- m_index.check_integrity(node_count);
- }
-
- // Change the capacity; the capacity will be reduced, growing is not
- // implemented. Which means that the data area must be copied; the offsets
- // do not have to be changed.
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t capacity_hint) {
- // no capacity given? then try to find a good default one
- if (capacity_hint == 0) {
- capacity_hint = (new_range_size - m_index.get_next_offset(node_count)
- - get_full_record_size()) / m_index.get_full_index_size();
- if (capacity_hint <= node_count)
- capacity_hint = node_count + 1;
- }
-
- // if there's not enough space for the new capacity then try to reduce
- // the capacity
- if (m_index.get_next_offset(node_count) + get_full_record_size()
- + capacity_hint * m_index.get_full_index_size()
- + UpfrontIndex::kPayloadOffset
- > new_range_size)
- capacity_hint = node_count + 1;
-
- m_index.change_range_size(node_count, new_data_ptr, new_range_size,
- capacity_hint);
- m_data = new_data_ptr;
- m_range_size = new_range_size;
- }
-
- // Returns true if there's not enough space for another record
- bool requires_split(size_t node_count) {
- // if the record is extremely small then make sure there's some headroom;
- // this is required for DuplicateTable ids which are 64bit numbers
- size_t required = get_full_record_size();
- if (required < 10)
- required = 10;
- return (m_index.requires_split(node_count, required));
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BaseRecordList::fill_metrics(metrics, node_count);
- BtreeStatistics::update_min_max_avg(&metrics->recordlist_index,
- m_index.get_capacity() * m_index.get_full_index_size());
- BtreeStatistics::update_min_max_avg(&metrics->recordlist_unused,
- m_range_size - get_required_range_size(node_count));
- }
-
- // Prints a slot to |out| (for debugging)
- void print(Context *context, int slot, std::stringstream &out) {
- out << "(" << get_record_count(context, slot) << " records)";
- }
-
- private:
- // Returns the number of records that are stored inline
- uint32_t get_inline_record_count(int slot) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- return (m_data[offset] & 0x7f);
- }
-
- // Sets the number of records that are stored inline
- void set_inline_record_count(int slot, size_t count) {
- ham_assert(count <= 0x7f);
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- m_data[offset] &= BtreeRecord::kExtendedDuplicates;
- m_data[offset] |= count;
- }
-
- // Returns a pointer to the record data
- uint8_t *get_record_data(int slot, int duplicate_index = 0) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- return (&m_data[offset + 1 + m_record_size * duplicate_index]);
- }
-
- // Returns a pointer to the record data (const flavour)
- const uint8_t *get_record_data(int slot,
- int duplicate_index = 0) const {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- return (&m_data[offset + 1 + m_record_size * duplicate_index]);
- }
-
- // The constant length record size
- size_t m_record_size;
-};
-
-//
-// RecordList for default records (8 bytes; either inline or a record id),
-// with duplicates
-//
-// Format for each slot:
-//
-// 1 byte meta data
-// bit 1 - 7: duplicate counter, if kExtendedDuplicates == 0
-// bit 8: kExtendedDuplicates
-// if kExtendedDuplicates == 0:
-// <counter> * 9 bytes
-// 1 byte flags (RecordFlag::*)
-// 8 byte data (either inline or record-id)
-// if kExtendedDuplicates == 1:
-// 8 byte: record id of the extended duplicate table
-//
-class DuplicateDefaultRecordList : public DuplicateRecordList
-{
- public:
- // Constructor
- DuplicateDefaultRecordList(LocalDatabase *db, PBtreeNode *node)
- : DuplicateRecordList(db, node, true, HAM_RECORD_SIZE_UNLIMITED) {
- }
-
- // Creates a new RecordList starting at |data|
- void create(uint8_t *data, size_t range_size) {
- m_data = data;
- m_index.create(m_data, range_size, range_size / get_full_record_size());
- }
-
- // Calculates the required size for a range with the specified |capacity|
- size_t get_required_range_size(size_t node_count) const {
- return (m_index.get_required_range_size(node_count));
- }
-
- // Returns the actual key record including overhead
- size_t get_full_record_size() const {
- return (1 + 1 + 8 + m_index.get_full_index_size());
- }
-
- // Returns the number of duplicates
- int get_record_count(Context *context, int slot) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- if (unlikely(m_data[offset] & BtreeRecord::kExtendedDuplicates)) {
- DuplicateTable *dt = get_duplicate_table(context, get_record_id(slot));
- return ((int) dt->get_record_count());
- }
-
- return (m_data[offset] & 0x7f);
- }
-
- // Returns the size of a record
- uint64_t get_record_size(Context *context, int slot,
- int duplicate_index = 0) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- if (unlikely(m_data[offset] & BtreeRecord::kExtendedDuplicates)) {
- DuplicateTable *dt = get_duplicate_table(context, get_record_id(slot));
- return (dt->get_record_size(context, duplicate_index));
- }
-
- uint8_t *p = &m_data[offset + 1 + 9 * duplicate_index];
- uint8_t flags = *(p++);
- if (flags & BtreeRecord::kBlobSizeTiny)
- return (p[sizeof(uint64_t) - 1]);
- if (flags & BtreeRecord::kBlobSizeSmall)
- return (sizeof(uint64_t));
- if (flags & BtreeRecord::kBlobSizeEmpty)
- return (0);
-
- LocalEnvironment *env = m_db->lenv();
- return (env->blob_manager()->get_blob_size(context, *(uint64_t *)p));
- }
-
- // Returns the full record and stores it in |dest|; memory must be
- // allocated by the caller
- void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags, int duplicate_index) {
- // forward to duplicate table?
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- if (unlikely(m_data[offset] & BtreeRecord::kExtendedDuplicates)) {
- DuplicateTable *dt = get_duplicate_table(context, get_record_id(slot));
- dt->get_record(context, arena, record, flags, duplicate_index);
- return;
- }
-
- ham_assert(duplicate_index < (int)get_inline_record_count(slot));
- bool direct_access = (flags & HAM_DIRECT_ACCESS) != 0;
-
- uint8_t *p = &m_data[offset + 1 + 9 * duplicate_index];
- uint8_t record_flags = *(p++);
-
- if (record_flags && (flags & HAM_PARTIAL)) {
- ham_trace(("flag HAM_PARTIAL is not allowed if record is "
- "stored inline"));
- throw Exception(HAM_INV_PARAMETER);
- }
-
- if (record_flags & BtreeRecord::kBlobSizeEmpty) {
- record->data = 0;
- record->size = 0;
- return;
- }
-
- if (record_flags & BtreeRecord::kBlobSizeTiny) {
- record->size = p[sizeof(uint64_t) - 1];
- if (direct_access)
- record->data = &p[0];
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, &p[0], record->size);
- }
- return;
- }
-
- if (record_flags & BtreeRecord::kBlobSizeSmall) {
- record->size = sizeof(uint64_t);
- if (direct_access)
- record->data = &p[0];
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, &p[0], record->size);
- }
- return;
- }
-
- uint64_t blob_id = *(uint64_t *)p;
-
- // the record is stored as a blob
- LocalEnvironment *env = m_db->lenv();
- env->blob_manager()->read(context, blob_id, record, flags, arena);
- }
-
- // Updates the record of a key
- void set_record(Context *context, int slot, int duplicate_index,
- ham_record_t *record, uint32_t flags,
- uint32_t *new_duplicate_index = 0) {
- uint32_t chunk_offset = m_index.get_absolute_chunk_offset(slot);
- uint32_t current_size = m_index.get_chunk_size(slot);
-
- // if the slot was not yet allocated: allocate new space, initialize
- // it and then overwrite the record
- if (current_size == 0) {
- duplicate_index = 0;
- flags |= HAM_OVERWRITE;
- chunk_offset = m_index.allocate_space(m_node->get_count(), slot, 1 + 9);
- chunk_offset = m_index.get_absolute_offset(chunk_offset);
- // clear the record flags
- m_data[chunk_offset] = 0;
- m_data[chunk_offset + 1] = BtreeRecord::kBlobSizeEmpty;
-
- set_inline_record_count(slot, 1);
- }
-
- // if there's no duplicate table, but we're not able to add another
- // duplicate then offload all existing duplicates to a table
- uint32_t record_count = get_inline_record_count(slot);
- size_t required_size = 1 + (record_count + 1) * 9;
-
- if (!(m_data[chunk_offset] & BtreeRecord::kExtendedDuplicates)
- && !(flags & HAM_OVERWRITE)) {
- bool force_duptable = record_count >= m_duptable_threshold;
- if (!force_duptable
- && !m_index.can_allocate_space(m_node->get_count(),
- required_size))
- force_duptable = true;
-
- // update chunk_offset - it might have been modified if
- // m_index.can_allocate_space triggered a vacuumize() operation
- chunk_offset = m_index.get_absolute_chunk_offset(slot);
-
- // already too many duplicates, or the record does not fit? then
- // allocate an overflow duplicate list and move all duplicates to
- // this list
- if (force_duptable) {
- DuplicateTable *dt = new DuplicateTable(m_db, !m_store_flags,
- HAM_RECORD_SIZE_UNLIMITED);
- uint64_t table_id = dt->create(context, get_record_data(slot, 0),
- record_count);
- if (!m_duptable_cache)
- m_duptable_cache.reset(new DuplicateTableCache());
- (*m_duptable_cache)[table_id] = dt;
-
- // write the id of the duplicate table
- if (m_index.get_chunk_size(slot) < 8 + 1) {
- // do not erase the slot because it obviously occupies so
- // little space
- m_index.allocate_space(m_node->get_count(), slot, 8 + 1);
- chunk_offset = m_index.get_absolute_chunk_offset(slot);
- }
-
- m_data[chunk_offset] |= BtreeRecord::kExtendedDuplicates;
- set_record_id(slot, table_id);
- set_inline_record_count(slot, 0);
-
- m_index.set_chunk_size(slot, 10);
- m_index.increase_vacuumize_counter(m_index.get_chunk_size(slot) - 10);
- m_index.invalidate_next_offset();
-
- // fall through
- }
- }
-
- // forward to duplicate table?
- if (unlikely(m_data[chunk_offset] & BtreeRecord::kExtendedDuplicates)) {
- uint64_t table_id = get_record_id(slot);
- DuplicateTable *dt = get_duplicate_table(context, table_id);
- uint64_t new_table_id = dt->set_record(context, duplicate_index, record,
- flags, new_duplicate_index);
- if (new_table_id != table_id) {
- update_duplicate_table_id(dt, table_id, new_table_id);
- set_record_id(slot, new_table_id);
- }
- return;
- }
-
- uint64_t overwrite_blob_id = 0;
- uint8_t *record_flags = 0;
- uint8_t *p = 0;
-
- // the (inline) duplicate is overwritten
- if (flags & HAM_OVERWRITE) {
- record_flags = &m_data[chunk_offset + 1 + 9 * duplicate_index];
- p = record_flags + 1;
-
- // If a blob is overwritten with an inline record then the old blob
- // has to be deleted
- if (*record_flags == 0) {
- if (record->size <= 8) {
- uint64_t blob_id = *(uint64_t *)p;
- if (blob_id)
- m_db->lenv()->blob_manager()->erase(context, blob_id);
- }
- else
- overwrite_blob_id = *(uint64_t *)p;
- // fall through
- }
- // then jump to the code which performs the actual insertion
- goto write_record;
- }
-
- // Allocate new space for the duplicate table, if required
- if (current_size < required_size) {
- uint8_t *oldp = &m_data[chunk_offset];
- uint32_t old_chunk_size = m_index.get_chunk_size(slot);
- uint32_t old_chunk_offset = m_index.get_chunk_offset(slot);
- uint32_t new_chunk_offset = m_index.allocate_space(m_node->get_count(),
- slot, required_size);
- chunk_offset = m_index.get_absolute_offset(new_chunk_offset);
- if (current_size > 0)
- memmove(&m_data[chunk_offset], oldp, current_size);
- if (old_chunk_offset != new_chunk_offset)
- m_index.add_to_freelist(m_node->get_count(), old_chunk_offset,
- old_chunk_size);
- }
-
- // adjust flags
- if (flags & HAM_DUPLICATE_INSERT_BEFORE && duplicate_index == 0)
- flags |= HAM_DUPLICATE_INSERT_FIRST;
- else if (flags & HAM_DUPLICATE_INSERT_AFTER) {
- if (duplicate_index == (int)record_count)
- flags |= HAM_DUPLICATE_INSERT_LAST;
- else {
- flags |= HAM_DUPLICATE_INSERT_BEFORE;
- duplicate_index++;
- }
- }
-
- // handle overwrites or inserts/appends
- if (flags & HAM_DUPLICATE_INSERT_FIRST) {
- if (record_count > 0) {
- uint8_t *ptr = &m_data[chunk_offset + 1];
- memmove(&m_data[chunk_offset + 1 + 9], ptr, record_count * 9);
- }
- duplicate_index = 0;
- }
- else if (flags & HAM_DUPLICATE_INSERT_BEFORE) {
- memmove(&m_data[chunk_offset + 1 + 9 * (duplicate_index + 1)],
- &m_data[chunk_offset + 1 + 9 * duplicate_index],
- (record_count - duplicate_index) * 9);
- }
- else // HAM_DUPLICATE_INSERT_LAST
- duplicate_index = record_count;
-
- set_inline_record_count(slot, record_count + 1);
-
- record_flags = &m_data[chunk_offset + 1 + 9 * duplicate_index];
- p = record_flags + 1;
-
-write_record:
- if (record->size == 0) {
- memcpy(p, "\0\0\0\0\0\0\0\0", 8);
- *record_flags = BtreeRecord::kBlobSizeEmpty;
- }
- else if (record->size < sizeof(uint64_t)) {
- p[sizeof(uint64_t) - 1] = (uint8_t)record->size;
- memcpy(&p[0], record->data, record->size);
- *record_flags = BtreeRecord::kBlobSizeTiny;
- }
- else if (record->size == sizeof(uint64_t)) {
- memcpy(&p[0], record->data, record->size);
- *record_flags = BtreeRecord::kBlobSizeSmall;
- }
- else {
- LocalEnvironment *env = m_db->lenv();
- *record_flags = 0;
- uint64_t blob_id;
- if (overwrite_blob_id)
- blob_id = env->blob_manager()->overwrite(context,
- overwrite_blob_id, record, flags);
- else
- blob_id = env->blob_manager()->allocate(context, record, flags);
- memcpy(p, &blob_id, sizeof(blob_id));
- }
-
- if (new_duplicate_index)
- *new_duplicate_index = duplicate_index;
- }
-
- // Erases a record
- void erase_record(Context *context, int slot, int duplicate_index = 0,
- bool all_duplicates = false) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
-
- // forward to external duplicate table?
- if (unlikely(m_data[offset] & BtreeRecord::kExtendedDuplicates)) {
- uint64_t table_id = get_record_id(slot);
- DuplicateTable *dt = get_duplicate_table(context, table_id);
- uint64_t new_table_id = dt->erase_record(context, duplicate_index,
- all_duplicates);
- if (new_table_id == 0) {
- m_duptable_cache->erase(table_id);
- set_record_id(slot, 0);
- m_data[offset] &= ~BtreeRecord::kExtendedDuplicates;
- delete dt;
- }
- else if (new_table_id != table_id) {
- update_duplicate_table_id(dt, table_id, new_table_id);
- set_record_id(slot, new_table_id);
- }
- return;
- }
-
- // erase the last duplicate?
- uint32_t count = get_inline_record_count(slot);
- if (count == 1 && duplicate_index == 0)
- all_duplicates = true;
-
- // adjust next_offset, if necessary. Note that get_next_offset() is
- // called with a node_count of zero, which is valid (it avoids a
- // recalculation in case there is no next_offset)
- m_index.maybe_invalidate_next_offset(m_index.get_chunk_offset(slot)
- + m_index.get_chunk_size(slot));
-
- // erase all duplicates?
- if (all_duplicates) {
- for (uint32_t i = 0; i < count; i++) {
- uint8_t *p = &m_data[offset + 1 + 9 * i];
- if (!is_record_inline(*p)) {
- m_db->lenv()->blob_manager()->erase(context, *(uint64_t *)(p + 1));
- *(uint64_t *)(p + 1) = 0;
- }
- }
- set_inline_record_count(slot, 0);
- m_index.set_chunk_size(slot, 0);
- }
- else {
- uint8_t *p = &m_data[offset + 1 + 9 * duplicate_index];
- if (!is_record_inline(*p)) {
- m_db->lenv()->blob_manager()->erase(context, *(uint64_t *)(p + 1));
- *(uint64_t *)(p + 1) = 0;
- }
- if (duplicate_index < (int)count - 1)
- memmove(&m_data[offset + 1 + 9 * duplicate_index],
- &m_data[offset + 1 + 9 * (duplicate_index + 1)],
- 9 * (count - duplicate_index - 1));
- set_inline_record_count(slot, count - 1);
- }
- }
-
- // Returns a record id
- uint64_t get_record_id(int slot,
- int duplicate_index = 0) const {
- return (*(uint64_t *)get_record_data(slot, duplicate_index));
- }
-
- // Sets a record id
- void set_record_id(int slot, uint64_t id) {
- *(uint64_t *)get_record_data(slot, 0) = id;
- }
-
- // Checks the integrity of this node. Throws an exception if there is a
- // violation.
- void check_integrity(Context *context, size_t node_count) const {
- for (size_t i = 0; i < node_count; i++) {
- uint32_t offset = m_index.get_absolute_chunk_offset(i);
- if (m_data[offset] & BtreeRecord::kExtendedDuplicates) {
- ham_assert((m_data[offset] & 0x7f) == 0);
- }
- }
-
- m_index.check_integrity(node_count);
- }
-
- // Change the capacity; the capacity will be reduced, growing is not
- // implemented. Which means that the data area must be copied; the offsets
- // do not have to be changed.
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t capacity_hint) {
- // no capacity given? then try to find a good default one
- if (capacity_hint == 0) {
- capacity_hint = (new_range_size - m_index.get_next_offset(node_count)
- - get_full_record_size()) / m_index.get_full_index_size();
- if (capacity_hint <= node_count)
- capacity_hint = node_count + 1;
- }
-
- // if there's not enough space for the new capacity then try to reduce
- // the capacity
- if (m_index.get_next_offset(node_count) + get_full_record_size()
- + capacity_hint * m_index.get_full_index_size()
- + UpfrontIndex::kPayloadOffset
- > new_range_size)
- capacity_hint = node_count + 1;
-
- m_index.change_range_size(node_count, new_data_ptr, new_range_size,
- capacity_hint);
- m_data = new_data_ptr;
- m_range_size = new_range_size;
- }
-
- // Returns true if there's not enough space for another record
- bool requires_split(size_t node_count) {
- // if the record is extremely small then make sure there's some headroom;
- // this is required for DuplicateTable ids which are 64bit numbers
- size_t required = get_full_record_size();
- if (required < 10)
- required = 10;
- return (m_index.requires_split(node_count, required));
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BaseRecordList::fill_metrics(metrics, node_count);
- BtreeStatistics::update_min_max_avg(&metrics->recordlist_index,
- m_index.get_capacity() * m_index.get_full_index_size());
- BtreeStatistics::update_min_max_avg(&metrics->recordlist_unused,
- m_range_size - get_required_range_size(node_count));
- }
-
- // Prints a slot to |out| (for debugging)
- void print(Context *context, int slot, std::stringstream &out) {
- out << "(" << get_record_count(context, slot) << " records)";
- }
-
- private:
- // Returns the number of records that are stored inline
- uint32_t get_inline_record_count(int slot) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- return (m_data[offset] & 0x7f);
- }
-
- // Sets the number of records that are stored inline
- void set_inline_record_count(int slot, size_t count) {
- ham_assert(count <= 0x7f);
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- m_data[offset] &= BtreeRecord::kExtendedDuplicates;
- m_data[offset] |= count;
- }
-
- // Returns a pointer to the record data (const flavour)
- uint8_t *get_record_data(int slot, int duplicate_index = 0) {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- return (&m_data[offset + 1 + 9 * duplicate_index]);
- }
-
- // Returns a pointer to the record data (const flavour)
- const uint8_t *get_record_data(int slot,
- int duplicate_index = 0) const {
- uint32_t offset = m_index.get_absolute_chunk_offset(slot);
- return (&m_data[offset + 1 + 9 * duplicate_index]);
- }
-};
-
-} // namespace DefLayout
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_RECORDS_DUPLICATE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_inline.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_inline.h
deleted file mode 100644
index 6a7ac4ff35..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_inline.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * RecordList for Inline Records
- *
- * Inline Records are records that are stored directly in the leaf node, and
- * not in an external blob. Only for fixed length records.
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_RECORDS_INLINE_H
-#define HAM_BTREE_RECORDS_INLINE_H
-
-#include "0root/root.h"
-
-#include <sstream>
-#include <iostream>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_node.h"
-#include "3btree/btree_records_base.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// The template classes in this file are wrapped in a separate namespace
-// to avoid naming clashes with btree_impl_default.h
-//
-namespace PaxLayout {
-
-class InlineRecordList : public BaseRecordList
-{
- public:
- enum {
- // A flag whether this RecordList has sequential data
- kHasSequentialData = 1
- };
-
- // Constructor
- InlineRecordList(LocalDatabase *db, PBtreeNode *node)
- : m_db(db), m_record_size(db->config().record_size), m_data(0) {
- ham_assert(m_record_size != HAM_RECORD_SIZE_UNLIMITED);
- }
-
- // Sets the data pointer
- void create(uint8_t *data, size_t range_size) {
- m_data = (uint8_t *)data;
- m_range_size = range_size;
- }
-
- // Opens an existing RecordList
- void open(uint8_t *ptr, size_t range_size, size_t node_count) {
- m_data = ptr;
- m_range_size = range_size;
- }
-
- // Returns the actual record size including overhead
- size_t get_full_record_size() const {
- return (m_record_size);
- }
-
- // Calculates the required size for a range with the specified |capacity|
- size_t get_required_range_size(size_t node_count) const {
- return (node_count * m_record_size);
- }
-
- // Returns the record counter of a key
- int get_record_count(Context *context, int slot) const {
- return (1);
- }
-
- // Returns the record size
- uint64_t get_record_size(Context *context, int slot,
- int duplicate_index = 0) const {
- return (m_record_size);
- }
-
- // Returns the full record and stores it in |dest|; memory must be
- // allocated by the caller
- void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags,
- int duplicate_index) const {
- bool direct_access = (flags & HAM_DIRECT_ACCESS) != 0;
-
- if (flags & HAM_PARTIAL) {
- ham_trace(("flag HAM_PARTIAL is not allowed if record is "
- "stored inline"));
- throw Exception(HAM_INV_PARAMETER);
- }
-
- // the record is stored inline
- record->size = m_record_size;
-
- if (m_record_size == 0)
- record->data = 0;
- else if (direct_access)
- record->data = &m_data[slot * m_record_size];
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, &m_data[slot * m_record_size], record->size);
- }
- }
-
- // Updates the record of a key
- void set_record(Context *context, int slot, int duplicate_index,
- ham_record_t *record, uint32_t flags,
- uint32_t *new_duplicate_index = 0) {
- ham_assert(record->size == m_record_size);
- // it's possible that the records have size 0 - then don't copy anything
- if (m_record_size)
- memcpy(&m_data[m_record_size * slot], record->data, m_record_size);
- }
-
- // Erases the record
- void erase_record(Context *context, int slot, int duplicate_index = 0,
- bool all_duplicates = true) {
- if (m_record_size)
- memset(&m_data[m_record_size * slot], 0, m_record_size);
- }
-
- // Erases a whole slot by shifting all larger records to the "left"
- void erase(Context *context, size_t node_count, int slot) {
- if (slot < (int)node_count - 1)
- memmove(&m_data[m_record_size * slot],
- &m_data[m_record_size * (slot + 1)],
- m_record_size * (node_count - slot - 1));
- }
-
- // Creates space for one additional record
- void insert(Context *context, size_t node_count, int slot) {
- if (slot < (int)node_count) {
- memmove(&m_data[m_record_size * (slot + 1)],
- &m_data[m_record_size * slot],
- m_record_size * (node_count - slot));
- }
- memset(&m_data[m_record_size * slot], 0, m_record_size);
- }
-
- // Copies |count| records from this[sstart] to dest[dstart]
- void copy_to(int sstart, size_t node_count, InlineRecordList &dest,
- size_t other_count, int dstart) {
- memcpy(&dest.m_data[m_record_size * dstart],
- &m_data[m_record_size * sstart],
- m_record_size * (node_count - sstart));
- }
-
- // Returns the record id. Not required for fixed length leaf nodes
- uint64_t get_record_id(int slot, int duplicate_index = 0)
- const {
- ham_assert(!"shouldn't be here");
- return (0);
- }
-
- // Sets the record id. Not required for fixed length leaf nodes
- void set_record_id(int slot, uint64_t ptr) {
- ham_assert(!"shouldn't be here");
- }
-
- // Returns true if there's not enough space for another record
- bool requires_split(size_t node_count) const {
- if (m_range_size == 0)
- return (false);
- return ((node_count + 1) * m_record_size >= m_range_size);
- }
-
- // Change the capacity; for PAX layouts this just means copying the
- // data from one place to the other
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t capacity_hint) {
- memmove(new_data_ptr, m_data, node_count * m_record_size);
- m_data = new_data_ptr;
- m_range_size = new_range_size;
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BaseRecordList::fill_metrics(metrics, node_count);
- BtreeStatistics::update_min_max_avg(&metrics->recordlist_unused,
- m_range_size - get_required_range_size(node_count));
- }
-
- // Prints a slot to |out| (for debugging)
- void print(Context *context, int slot, std::stringstream &out) const {
- out << "(" << get_record_size(context, slot) << " bytes)";
- }
-
- private:
- // The parent database of this btree
- LocalDatabase *m_db;
-
- // The record size, as specified when the database was created
- size_t m_record_size;
-
- // The actual record data
- uint8_t *m_data;
-};
-
-} // namespace PaxLayout
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_RECORDS_INLINE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_internal.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_internal.h
deleted file mode 100644
index 9773119991..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_records_internal.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Internal RecordList
- *
- * Only for records of internal nodes. Internal nodes only store page IDs,
- * therefore this |InternalRecordList| is optimized for 64bit IDs
- * (and is implemented as a uint64_t[] array).
- *
- * For file-based databases the page IDs are stored modulo page size, which
- * results in smaller IDs. Small IDs can be compressed more efficiently
- * (-> hamsterdb pro).
- *
- * In-memory based databases just store the raw pointers.
- *
- * @exception_safe: nothrow
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_RECORDS_INTERNAL_H
-#define HAM_BTREE_RECORDS_INTERNAL_H
-
-#include "0root/root.h"
-
-#include <sstream>
-#include <iostream>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-#include "1base/dynamic_array.h"
-#include "2page/page.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_records_base.h"
-#include "3btree/btree_node.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// The template classes in this file are wrapped in a separate namespace
-// to avoid naming clashes with btree_impl_default.h
-//
-namespace PaxLayout {
-
-class InternalRecordList : public BaseRecordList
-{
- public:
- enum {
- // A flag whether this RecordList has sequential data
- kHasSequentialData = 1
- };
-
- // Constructor
- InternalRecordList(LocalDatabase *db, PBtreeNode *node)
- : m_db(db), m_data(0) {
- m_page_size = m_db->lenv()->config().page_size_bytes;
- m_store_raw_id = (m_db->lenv()->config().flags
- & HAM_IN_MEMORY) == HAM_IN_MEMORY;
- }
-
- // Sets the data pointer
- void create(uint8_t *data, size_t range_size) {
- m_data = (uint64_t *)data;
- m_range_size = range_size;
- }
-
- // Opens an existing RecordList
- void open(uint8_t *ptr, size_t range_size, size_t node_count) {
- m_data = (uint64_t *)ptr;
- m_range_size = range_size;
- }
-
- // Returns the actual size including overhead
- size_t get_full_record_size() const {
- return (sizeof(uint64_t));
- }
-
- // Calculates the required size for a range with the specified |capacity|
- size_t get_required_range_size(size_t node_count) const {
- return (node_count * sizeof(uint64_t));
- }
-
- // Returns the record counter of a key; this implementation does not
- // support duplicates, therefore the record count is always 1
- int get_record_count(Context *context, int slot) const {
- return (1);
- }
-
- // Returns the record size
- uint64_t get_record_size(Context *context, int slot,
- int duplicate_index = 0) const {
- return (sizeof(uint64_t));
- }
-
- // Returns the full record and stores it in |dest|; memory must be
- // allocated by the caller
- void get_record(Context *context, int slot, ByteArray *arena,
- ham_record_t *record, uint32_t flags,
- int duplicate_index) const {
- bool direct_access = (flags & HAM_DIRECT_ACCESS) != 0;
-
- // the record is stored inline
- record->size = sizeof(uint64_t);
-
- if (direct_access)
- record->data = (void *)&m_data[slot];
- else {
- if ((record->flags & HAM_RECORD_USER_ALLOC) == 0) {
- arena->resize(record->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, &m_data[slot], record->size);
- }
- }
-
- // Updates the record of a key
- void set_record(Context *context, int slot, int duplicate_index,
- ham_record_t *record, uint32_t flags,
- uint32_t *new_duplicate_index = 0) {
- ham_assert(record->size == sizeof(uint64_t));
- m_data[slot] = *(uint64_t *)record->data;
- }
-
- // Erases the record
- void erase_record(Context *context, int slot, int duplicate_index = 0,
- bool all_duplicates = true) {
- m_data[slot] = 0;
- }
-
- // Erases a whole slot by shifting all larger records to the "left"
- void erase(Context *context, size_t node_count, int slot) {
- if (slot < (int)node_count - 1)
- memmove(&m_data[slot], &m_data[slot + 1],
- sizeof(uint64_t) * (node_count - slot - 1));
- }
-
- // Creates space for one additional record
- void insert(Context *context, size_t node_count, int slot) {
- if (slot < (int)node_count) {
- memmove(&m_data[slot + 1], &m_data[slot],
- sizeof(uint64_t) * (node_count - slot));
- }
- m_data[slot] = 0;
- }
-
- // Copies |count| records from this[sstart] to dest[dstart]
- void copy_to(int sstart, size_t node_count, InternalRecordList &dest,
- size_t other_count, int dstart) {
- memcpy(&dest.m_data[dstart], &m_data[sstart],
- sizeof(uint64_t) * (node_count - sstart));
- }
-
- // Sets the record id
- void set_record_id(int slot, uint64_t value) {
- ham_assert(m_store_raw_id ? 1 : value % m_page_size == 0);
- m_data[slot] = m_store_raw_id ? value : value / m_page_size;
- }
-
- // Returns the record id
- uint64_t get_record_id(int slot,
- int duplicate_index = 0) const {
- ham_assert(duplicate_index == 0);
- return (m_store_raw_id ? m_data[slot] : m_page_size * m_data[slot]);
- }
-
- // Returns true if there's not enough space for another record
- bool requires_split(size_t node_count) const {
- return ((node_count + 1) * sizeof(uint64_t) >= m_range_size);
- }
-
- // Change the capacity; for PAX layouts this just means copying the
- // data from one place to the other
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t capacity_hint) {
- if ((uint64_t *)new_data_ptr != m_data) {
- memmove(new_data_ptr, m_data, node_count * sizeof(uint64_t));
- m_data = (uint64_t *)new_data_ptr;
- }
- m_range_size = new_range_size;
- }
-
- // Fills the btree_metrics structure
- void fill_metrics(btree_metrics_t *metrics, size_t node_count) {
- BaseRecordList::fill_metrics(metrics, node_count);
- BtreeStatistics::update_min_max_avg(&metrics->recordlist_unused,
- m_range_size - get_required_range_size(node_count));
- }
-
- // Prints a slot to |out| (for debugging)
- void print(Context *context, int slot, std::stringstream &out) const {
- out << "(" << get_record_id(slot);
- }
-
- private:
- // The parent database of this btree
- LocalDatabase *m_db;
-
- // The record data is an array of page IDs
- uint64_t *m_data;
-
- // The page size
- size_t m_page_size;
-
- // Store page ID % page size or the raw page ID?
- bool m_store_raw_id;
-};
-
-} // namespace PaxLayout
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_RECORDS_INTERNAL_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_stats.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_stats.cc
deleted file mode 100644
index edd8c7b7a1..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_stats.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-#include <stdio.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "2page/page.h"
-#include "3btree/btree_stats.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_node_proxy.h"
-#include "4db/db_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-BtreeStatistics::BtreeStatistics()
- : m_append_count(0), m_prepend_count(0)
-{
- memset(&m_last_leaf_pages[0], 0, sizeof(m_last_leaf_pages));
- memset(&m_last_leaf_count[0], 0, sizeof(m_last_leaf_count));
- memset(&m_keylist_range_size[0], 0, sizeof(m_keylist_range_size));
- memset(&m_keylist_capacities[0], 0, sizeof(m_keylist_capacities));
-}
-
-void
-BtreeStatistics::find_succeeded(Page *page)
-{
- uint64_t old = m_last_leaf_pages[kOperationFind];
- if (old != page->get_address()) {
- m_last_leaf_pages[kOperationFind] = 0;
- m_last_leaf_count[kOperationFind] = 0;
- }
- else
- m_last_leaf_count[kOperationFind]++;
-}
-
-void
-BtreeStatistics::find_failed()
-{
- m_last_leaf_pages[kOperationFind] = 0;
- m_last_leaf_count[kOperationFind] = 0;
-}
-
-void
-BtreeStatistics::insert_succeeded(Page *page, uint16_t slot)
-{
- uint64_t old = m_last_leaf_pages[kOperationInsert];
- if (old != page->get_address()) {
- m_last_leaf_pages[kOperationInsert] = page->get_address();
- m_last_leaf_count[kOperationInsert] = 0;
- }
- else
- m_last_leaf_count[kOperationInsert]++;
-
- BtreeNodeProxy *node;
- node = page->get_db()->btree_index()->get_node_from_page(page);
- ham_assert(node->is_leaf());
-
- if (!node->get_right() && slot == node->get_count() - 1)
- m_append_count++;
- else
- m_append_count = 0;
-
- if (!node->get_left() && slot == 0)
- m_prepend_count++;
- else
- m_prepend_count = 0;
-}
-
-void
-BtreeStatistics::insert_failed()
-{
- m_last_leaf_pages[kOperationInsert] = 0;
- m_last_leaf_count[kOperationInsert] = 0;
- m_append_count = 0;
- m_prepend_count = 0;
-}
-
-void
-BtreeStatistics::erase_succeeded(Page *page)
-{
- uint64_t old = m_last_leaf_pages[kOperationErase];
- if (old != page->get_address()) {
- m_last_leaf_pages[kOperationErase] = page->get_address();
- m_last_leaf_count[kOperationErase] = 0;
- }
- else
- m_last_leaf_count[kOperationErase]++;
-}
-
-void
-BtreeStatistics::erase_failed()
-{
- m_last_leaf_pages[kOperationErase] = 0;
- m_last_leaf_count[kOperationErase] = 0;
-}
-
-void
-BtreeStatistics::reset_page(Page *page)
-{
- for (int i = 0; i < kOperationMax; i++) {
- m_last_leaf_pages[i] = 0;
- m_last_leaf_count[i] = 0;
- }
-}
-
-BtreeStatistics::FindHints
-BtreeStatistics::get_find_hints(uint32_t flags)
-{
- BtreeStatistics::FindHints hints = {flags, flags, 0, false};
-
- /* if the last 5 lookups hit the same page: reuse that page */
- if (m_last_leaf_count[kOperationFind] >= 5) {
- hints.try_fast_track = true;
- hints.leaf_page_addr = m_last_leaf_pages[kOperationFind];
- }
-
- return (hints);
-}
-
-BtreeStatistics::InsertHints
-BtreeStatistics::get_insert_hints(uint32_t flags)
-{
- InsertHints hints = {flags, flags, 0, 0, 0, 0, 0};
-
- /* if the previous insert-operation replaced the upper bound (or
- * lower bound) key then it was actually an append (or prepend) operation.
- * in this case there's some probability that the next operation is also
- * appending/prepending.
- */
- if (m_append_count > 0)
- hints.flags |= HAM_HINT_APPEND;
- else if (m_prepend_count > 0)
- hints.flags |= HAM_HINT_PREPEND;
-
- hints.append_count = m_append_count;
- hints.prepend_count = m_prepend_count;
-
- /* if the last 5 inserts hit the same page: reuse that page */
- if (m_last_leaf_count[kOperationInsert] >= 5)
- hints.leaf_page_addr = m_last_leaf_pages[kOperationInsert];
-
- return (hints);
-}
-
-#define AVG(m) m._instances ? (m._total / m._instances) : 0
-
-void
-BtreeStatistics::finalize_metrics(btree_metrics_t *metrics)
-{
- metrics->keys_per_page.avg = AVG(metrics->keys_per_page);
- metrics->keylist_ranges.avg = AVG(metrics->keylist_ranges);
- metrics->recordlist_ranges.avg = AVG(metrics->recordlist_ranges);
- metrics->keylist_index.avg = AVG(metrics->keylist_index);
- metrics->recordlist_index.avg = AVG(metrics->recordlist_index);
- metrics->keylist_unused.avg = AVG(metrics->keylist_unused);
- metrics->recordlist_unused.avg = AVG(metrics->recordlist_unused);
- metrics->keylist_blocks_per_page.avg = AVG(metrics->keylist_blocks_per_page);
- metrics->keylist_block_sizes.avg = AVG(metrics->keylist_block_sizes);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_stats.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_stats.h
deleted file mode 100644
index 66c3f21ab9..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_stats.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * btree find/insert/erase statistical structures, functions and macros
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_STATS_H
-#define HAM_BTREE_STATS_H
-
-#include "0root/root.h"
-
-#include <limits>
-
-#include "ham/hamsterdb_int.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Page;
-
-class BtreeStatistics {
- public:
- // Indices into find/insert/erase specific statistics
- enum {
- kOperationFind = 0,
- kOperationInsert = 1,
- kOperationErase = 2,
- kOperationMax = 3
- };
-
- struct FindHints {
- // the original flags of ham_find
- uint32_t original_flags;
-
- // the modified flags
- uint32_t flags;
-
- // page/btree leaf to check first
- uint64_t leaf_page_addr;
-
- // check specified btree leaf node page first
- bool try_fast_track;
- };
-
- struct InsertHints {
- // the original flags of ham_insert
- uint32_t original_flags;
-
- // the modified flags
- uint32_t flags;
-
- // page/btree leaf to check first
- uint64_t leaf_page_addr;
-
- // the processed leaf page
- Page *processed_leaf_page;
-
- // the slot in that page
- uint16_t processed_slot;
-
- // count the number of appends
- size_t append_count;
-
- // count the number of prepends
- size_t prepend_count;
- };
-
- // Constructor
- BtreeStatistics();
-
- // Returns the btree hints for ham_find
- FindHints get_find_hints(uint32_t flags);
-
- // Returns the btree hints for insert
- InsertHints get_insert_hints(uint32_t flags);
-
- // Reports that a ham_find/ham_cusor_find succeeded
- void find_succeeded(Page *page);
-
- // Reports that a ham_find/ham_cursor_find failed
- void find_failed();
-
- // Reports that a ham_insert/ham_cursor_insert succeeded
- void insert_succeeded(Page *page, uint16_t slot);
-
- // Reports that a ham_insert/ham_cursor_insert failed
- void insert_failed();
-
- // Reports that a ham_erase/ham_cusor_erase succeeded
- void erase_succeeded(Page *page);
-
- // Reports that a ham_erase/ham_cursor_erase failed
- void erase_failed();
-
- // Resets the statistics for a single page
- void reset_page(Page *page);
-
- // Keep track of the KeyList range size
- void set_keylist_range_size(bool leaf, size_t size) {
- m_keylist_range_size[(int)leaf] = size;
- }
-
- // Retrieves the KeyList range size
- size_t get_keylist_range_size(bool leaf) const {
- return (m_keylist_range_size[(int)leaf]);
- }
-
- // Keep track of the KeyList capacities
- void set_keylist_capacities(bool leaf, size_t capacity) {
- m_keylist_capacities[(int)leaf] = capacity;
- }
-
- // Retrieves the KeyList capacities size
- size_t get_keylist_capacities(bool leaf) const {
- return (m_keylist_capacities[(int)leaf]);
- }
-
- // Calculate the "average" values
- static void finalize_metrics(btree_metrics_t *metrics);
-
- // Update a min_max_avg structure
- static void update_min_max_avg(min_max_avg_u32_t *data, uint32_t value) {
- // first update? then perform initialization
- if (data->_instances == 0)
- data->min = std::numeric_limits<uint32_t>::max();
-
- if (data->min > value)
- data->min = value;
- if (data->max < value)
- data->max = value;
- data->_total += value;
- data->_instances++;
- }
-
- private:
- // last leaf page for find/insert/erase
- uint64_t m_last_leaf_pages[kOperationMax];
-
- // count of how often this leaf page was used
- size_t m_last_leaf_count[kOperationMax];
-
- // count the number of appends
- size_t m_append_count;
-
- // count the number of prepends
- size_t m_prepend_count;
-
- // the range size of the KeyList
- size_t m_keylist_range_size[2];
-
- // the capacities of the KeyList
- size_t m_keylist_capacities[2];
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_STATS_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_update.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_update.cc
deleted file mode 100644
index 07d6cf61d4..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_update.cc
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "3page_manager/page_manager.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_stats.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_update.h"
-#include "3btree/btree_node_proxy.h"
-#include "4cursor/cursor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/* a unittest hook triggered when a page is split */
-void (*g_BTREE_INSERT_SPLIT_HOOK)(void);
-
-// Traverses the tree, looking for the leaf with the specified |key|. Will
-// split or merge nodes while descending.
-// Returns the leaf page and the |parent| of the leaf (can be null if
-// there is no parent).
-Page *
-BtreeUpdateAction::traverse_tree(const ham_key_t *key,
- BtreeStatistics::InsertHints &hints,
- Page **parent)
-{
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
-
- Page *page = env->page_manager()->fetch(m_context,
- m_btree->get_root_address());
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
-
- *parent = 0;
-
- // if the root page is empty with children then collapse it
- if (node->get_count() == 0 && !node->is_leaf()) {
- page = collapse_root(page);
- node = m_btree->get_node_from_page(page);
- }
-
- int slot;
-
- // now walk down the tree
- while (!node->is_leaf()) {
- // is a split required?
- if (node->requires_split(m_context)) {
- page = split_page(page, *parent, key, hints);
- node = m_btree->get_node_from_page(page);
- }
-
- // get the child page
- Page *sib_page = 0;
- Page *child_page = m_btree->find_child(m_context, page, key, 0, &slot);
- BtreeNodeProxy *child_node = m_btree->get_node_from_page(child_page);
-
- // We can merge this child with the RIGHT sibling iff...
- // 1. it's not the right-most slot (and therefore the right sibling has
- // the same parent as the child)
- // 2. the child is a leaf!
- // 3. it's empty or has too few elements
- // 4. its right sibling is also empty
- if (slot < (int)node->get_count() - 1
- && child_node->is_leaf()
- && child_node->requires_merge()
- && child_node->get_right() != 0) {
- sib_page = env->page_manager()->fetch(m_context,
- child_node->get_right(),
- PageManager::kOnlyFromCache);
- if (sib_page != 0) {
- BtreeNodeProxy *sib_node = m_btree->get_node_from_page(sib_page);
- if (sib_node->requires_merge()) {
- merge_page(child_page, sib_page);
- // also remove the link to the sibling from the parent
- node->erase(m_context, slot + 1);
- page->set_dirty(true);
- }
- }
- }
-
- // We can also merge this child with the LEFT sibling iff...
- // 1. it's not the left-most slot
- // 2. the child is a leaf!
- // 3. it's empty or has too few elements
- // 4. its left sibling is also empty
- else if (slot > 0
- && child_node->is_leaf()
- && child_node->requires_merge()
- && child_node->get_left() != 0) {
- sib_page = env->page_manager()->fetch(m_context,
- child_node->get_left(),
- PageManager::kOnlyFromCache);
- if (sib_page != 0) {
- BtreeNodeProxy *sib_node = m_btree->get_node_from_page(sib_page);
- if (sib_node->requires_merge()) {
- merge_page(sib_page, child_page);
- // also remove the link to the sibling from the parent
- node->erase(m_context, slot);
- page->set_dirty(true);
- // continue traversal with the sibling
- child_page = sib_page;
- child_node = sib_node;
- }
- }
- }
-
- *parent = page;
-
- // go down one level in the tree
- page = child_page;
- node = child_node;
- }
-
- return (page);
-}
-
-Page *
-BtreeUpdateAction::merge_page(Page *page, Page *sibling)
-{
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
- BtreeNodeProxy *sib_node = m_btree->get_node_from_page(sibling);
-
- if (sib_node->is_leaf())
- BtreeCursor::uncouple_all_cursors(m_context, sibling, 0);
-
- node->merge_from(m_context, sib_node);
- page->set_dirty(true);
-
- // fix the linked list
- node->set_right(sib_node->get_right());
- if (node->get_right()) {
- Page *new_right = env->page_manager()->fetch(m_context, node->get_right());
- BtreeNodeProxy *new_right_node = m_btree->get_node_from_page(new_right);
- new_right_node->set_left(page->get_address());
- new_right->set_dirty(true);
- }
-
- m_btree->get_statistics()->reset_page(sibling);
- m_btree->get_statistics()->reset_page(page);
- env->page_manager()->del(m_context, sibling);
-
- BtreeIndex::ms_btree_smo_merge++;
- return (page);
-}
-
-Page *
-BtreeUpdateAction::collapse_root(Page *root_page)
-{
- LocalEnvironment *env = root_page->get_db()->lenv();
- BtreeNodeProxy *node = m_btree->get_node_from_page(root_page);
- ham_assert(node->get_count() == 0);
-
- m_btree->get_statistics()->reset_page(root_page);
- m_btree->set_root_address(m_context, node->get_ptr_down());
- Page *header = env->page_manager()->fetch(m_context, 0);
- header->set_dirty(true);
-
- Page *new_root = env->page_manager()->fetch(m_context,
- m_btree->get_root_address());
- new_root->set_type(Page::kTypeBroot);
- env->page_manager()->del(m_context, root_page);
- return (new_root);
-}
-
-Page *
-BtreeUpdateAction::split_page(Page *old_page, Page *parent,
- const ham_key_t *key,
- BtreeStatistics::InsertHints &hints)
-{
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
-
- m_btree->get_statistics()->reset_page(old_page);
- BtreeNodeProxy *old_node = m_btree->get_node_from_page(old_page);
-
- /* allocate a new page and initialize it */
- Page *new_page = env->page_manager()->alloc(m_context, Page::kTypeBindex);
- {
- PBtreeNode *node = PBtreeNode::from_page(new_page);
- node->set_flags(old_node->is_leaf() ? PBtreeNode::kLeafNode : 0);
- }
- BtreeNodeProxy *new_node = m_btree->get_node_from_page(new_page);
-
- /* no parent page? then we're splitting the root page. allocate
- * a new root page */
- if (!parent)
- parent = allocate_new_root(old_page);
-
- Page *to_return = 0;
- ByteArray pivot_key_arena;
- ham_key_t pivot_key = {0};
-
- /* if the key is appended then don't split the page; simply allocate
- * a new page and insert the new key. */
- int pivot = 0;
- if (hints.flags & HAM_HINT_APPEND && old_node->is_leaf()) {
- int cmp = old_node->compare(m_context, key, old_node->get_count() - 1);
- if (cmp == +1) {
- to_return = new_page;
- pivot_key = *key;
- pivot = old_node->get_count();
- }
- }
-
- /* no append? then calculate the pivot key and perform the split */
- if (pivot != (int)old_node->get_count()) {
- pivot = get_pivot(old_node, key, hints);
-
- /* and store the pivot key for later */
- old_node->get_key(m_context, pivot, &pivot_key_arena, &pivot_key);
-
- /* leaf page: uncouple all cursors */
- if (old_node->is_leaf())
- BtreeCursor::uncouple_all_cursors(m_context, old_page, pivot);
- /* internal page: fix the ptr_down of the new page
- * (it must point to the ptr of the pivot key) */
- else
- new_node->set_ptr_down(old_node->get_record_id(m_context, pivot));
-
- /* now move some of the key/rid-tuples to the new page */
- old_node->split(m_context, new_node, pivot);
-
- // if the new key is >= the pivot key then continue with the right page,
- // otherwise continue with the left page
- to_return = m_btree->compare_keys((ham_key_t *)key, &pivot_key) >= 0
- ? new_page
- : old_page;
- }
-
- /* update the parent page */
- BtreeNodeProxy *parent_node = m_btree->get_node_from_page(parent);
- uint64_t rid = new_page->get_address();
- ham_record_t record = ham_make_record(&rid, sizeof(rid));
- ham_status_t st = insert_in_page(parent, &pivot_key, &record, hints);
- if (st)
- throw Exception(st);
- /* new root page? then also set ptr_down! */
- if (parent_node->get_count() == 0)
- parent_node->set_ptr_down(old_page->get_address());
-
- /* fix the double-linked list of pages, and mark the pages as dirty */
- if (old_node->get_right()) {
- Page *sib_page = env->page_manager()->fetch(m_context,
- old_node->get_right());
- BtreeNodeProxy *sib_node = m_btree->get_node_from_page(sib_page);
- sib_node->set_left(new_page->get_address());
- sib_page->set_dirty(true);
- }
- new_node->set_left(old_page->get_address());
- new_node->set_right(old_node->get_right());
- old_node->set_right(new_page->get_address());
- new_page->set_dirty(true);
- old_page->set_dirty(true);
-
- BtreeIndex::ms_btree_smo_split++;
-
- if (g_BTREE_INSERT_SPLIT_HOOK)
- g_BTREE_INSERT_SPLIT_HOOK();
-
- return (to_return);
-}
-
-Page *
-BtreeUpdateAction::allocate_new_root(Page *old_root)
-{
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
-
- Page *new_root = env->page_manager()->alloc(m_context, Page::kTypeBroot);
-
- /* insert the pivot element and set ptr_down */
- BtreeNodeProxy *new_node = m_btree->get_node_from_page(new_root);
- new_node->set_ptr_down(old_root->get_address());
-
- m_btree->set_root_address(m_context, new_root->get_address());
- Page *header = env->page_manager()->fetch(m_context, 0);
- header->set_dirty(true);
-
- old_root->set_type(Page::kTypeBindex);
-
- return (new_root);
-}
-
-int
-BtreeUpdateAction::get_pivot(BtreeNodeProxy *old_node, const ham_key_t *key,
- BtreeStatistics::InsertHints &hints) const
-{
- uint32_t old_count = old_node->get_count();
- ham_assert(old_count > 2);
-
- bool pivot_at_end = false;
- if (hints.flags & HAM_HINT_APPEND && hints.append_count > 5)
- pivot_at_end = true;
- else if (old_node->get_right() == 0) {
- int cmp = old_node->compare(m_context, key, old_node->get_count() - 1);
- if (cmp > 0)
- pivot_at_end = true;
- }
-
- /* The position of the pivot key depends on the previous inserts; if most
- * of them were appends then pick a pivot key at the "end" of the node */
- int pivot;
- if (pivot_at_end || hints.append_count > 30)
- pivot = old_count - 2;
- else if (hints.append_count > 10)
- pivot = (int)(old_count / 100.f * 66);
- else if (hints.prepend_count > 10)
- pivot = (int)(old_count / 100.f * 33);
- else if (hints.prepend_count > 30)
- pivot = 2;
- else
- pivot = old_count / 2;
-
- ham_assert(pivot > 0 && pivot <= (int)old_count - 2);
-
- return (pivot);
-}
-
-ham_status_t
-BtreeUpdateAction::insert_in_page(Page *page, ham_key_t *key,
- ham_record_t *record,
- BtreeStatistics::InsertHints &hints,
- bool force_prepend, bool force_append)
-{
- bool exists = false;
-
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
-
- int flags = 0;
- if (force_prepend)
- flags |= PBtreeNode::kInsertPrepend;
- if (force_append)
- flags |= PBtreeNode::kInsertAppend;
-
- PBtreeNode::InsertResult result = node->insert(m_context, key, flags);
- switch (result.status) {
- case HAM_DUPLICATE_KEY:
- if (hints.flags & HAM_OVERWRITE) {
- /* key already exists; only overwrite the data */
- if (!node->is_leaf())
- return (HAM_SUCCESS);
- }
- else if (!(hints.flags & HAM_DUPLICATE))
- return (HAM_DUPLICATE_KEY);
- /* do NOT shift keys up to make room; just overwrite the
- * current [slot] */
- exists = true;
- break;
- case HAM_SUCCESS:
- break;
- default:
- return (result.status);
- }
-
- uint32_t new_duplicate_id = 0;
- if (exists) {
- if (node->is_leaf()) {
- // overwrite record blob
- node->set_record(m_context, result.slot, record, m_duplicate_index,
- hints.flags, &new_duplicate_id);
-
- hints.processed_leaf_page = page;
- hints.processed_slot = result.slot;
- }
- else {
- // overwrite record id
- ham_assert(record->size == sizeof(uint64_t));
- node->set_record_id(m_context, result.slot, *(uint64_t *)record->data);
- }
- }
- // key does not exist and has to be inserted or appended
- else {
- try {
- if (node->is_leaf()) {
- // allocate record id
- node->set_record(m_context, result.slot, record, m_duplicate_index,
- hints.flags, &new_duplicate_id);
-
- hints.processed_leaf_page = page;
- hints.processed_slot = result.slot;
- }
- else {
- // set the internal record id
- ham_assert(record->size == sizeof(uint64_t));
- node->set_record_id(m_context, result.slot, *(uint64_t *)record->data);
- }
- }
- // In case of an error: undo the insert. This happens very rarely but
- // it's possible, i.e. if the BlobManager fails to allocate storage.
- catch (Exception &ex) {
- if (result.slot < (int)node->get_count())
- node->erase(m_context, result.slot);
- throw ex;
- }
- }
-
- page->set_dirty(true);
-
- // if this update was triggered with a cursor (and this is a leaf node):
- // couple it to the inserted key
- // TODO only when performing an insert(), not an erase()!
- if (m_cursor && node->is_leaf()) {
- m_cursor->get_parent()->set_to_nil(Cursor::kBtree);
- ham_assert(m_cursor->get_state() == BtreeCursor::kStateNil);
- m_cursor->couple_to_page(page, result.slot, new_duplicate_id);
- }
-
- return (HAM_SUCCESS);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_update.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_update.h
deleted file mode 100644
index 51176980fe..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_update.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_BTREE_UPDATE_H
-#define HAM_BTREE_UPDATE_H
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-class BtreeIndex;
-class BtreeCursor;
-
-/*
- * Base class for updates; derived for erasing and inserting keys.
- */
-class BtreeUpdateAction
-{
- public:
- // Constructor
- BtreeUpdateAction(BtreeIndex *btree, Context *context, BtreeCursor *cursor,
- uint32_t duplicate_index)
- : m_btree(btree), m_context(context), m_cursor(cursor),
- m_duplicate_index(duplicate_index) {
- }
-
- // Traverses the tree, looking for the leaf with the specified |key|. Will
- // split or merge nodes while descending.
- // Returns the leaf page and the |parent| of the leaf (can be null if
- // there is no parent).
- Page *traverse_tree(const ham_key_t *key,
- BtreeStatistics::InsertHints &hints, Page **parent);
-
- // Calculates the pivot index of a split.
- //
- // For databases with sequential access (this includes recno databases):
- // do not split in the middle, but at the very end of the page.
- //
- // If this page is the right-most page in the index, and the new key is
- // inserted at the very end, then we select the same pivot as for
- // sequential access.
- int get_pivot(BtreeNodeProxy *old_node, const ham_key_t *key,
- BtreeStatistics::InsertHints &hints) const;
-
- // Splits |page| and updates the |parent|. If |parent| is null then
- // it's assumed that |page| is the root node.
- // Returns the new page in the path for |key|; caller can immediately
- // continue the traversal.
- Page *split_page(Page *old_page, Page *parent, const ham_key_t *key,
- BtreeStatistics::InsertHints &hints);
-
- // Allocates a new root page and sets it up in the btree
- Page *allocate_new_root(Page *old_root);
-
- // Inserts a key in a page
- ham_status_t insert_in_page(Page *page, ham_key_t *key,
- ham_record_t *record,
- BtreeStatistics::InsertHints &hints,
- bool force_prepend = false, bool force_append = false);
-
- protected:
- // the current btree
- BtreeIndex *m_btree;
-
- // The caller's Context
- Context *m_context;
-
- // the current cursor
- BtreeCursor *m_cursor;
-
- // the duplicate index (in case the update is for a duplicate key)
- // 1-based (if 0 then this update is not for a duplicate)
- uint32_t m_duplicate_index;
-
- private:
- /* Merges the |sibling| into |page|, returns the merged page and moves
- * the sibling to the freelist */
- Page *merge_page(Page *page, Page *sibling);
-
- /* collapse the root node; returns the new root */
- Page *collapse_root(Page *root_page);
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_BTREE_UPDATE_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_visit.cc b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_visit.cc
deleted file mode 100644
index 05cd2603e5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_visit.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * btree enumeration; visits each node
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "3page_manager/page_manager.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_node_proxy.h"
-#include "3btree/btree_visitor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class BtreeVisitAction
-{
- public:
- BtreeVisitAction(BtreeIndex *btree, Context *context, BtreeVisitor &visitor,
- bool visit_internal_nodes)
- : m_btree(btree), m_context(context), m_visitor(visitor),
- m_visit_internal_nodes(visit_internal_nodes) {
- ham_assert(m_btree->get_root_address() != 0);
- }
-
- void run() {
- LocalDatabase *db = m_btree->get_db();
- LocalEnvironment *env = db->lenv();
-
- uint32_t pm_flags = 0;
- if (m_visitor.is_read_only())
- pm_flags = PageManager::kReadOnly;
-
- // get the root page of the tree
- Page *page = env->page_manager()->fetch(m_context,
- m_btree->get_root_address(), pm_flags);
-
- // go down to the leaf
- while (page) {
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
- uint64_t ptr_down = node->get_ptr_down();
-
- // visit internal nodes as well?
- if (ptr_down != 0 && m_visit_internal_nodes) {
- while (page) {
- node = m_btree->get_node_from_page(page);
- m_visitor(m_context, node);
-
- // load the right sibling
- uint64_t right = node->get_right();
- if (right)
- page = env->page_manager()->fetch(m_context, right, pm_flags);
- else
- page = 0;
- }
- }
-
- // follow the pointer to the smallest child
- if (ptr_down)
- page = env->page_manager()->fetch(m_context, ptr_down, pm_flags);
- else
- break;
- }
-
- ham_assert(page != 0);
-
- // now visit all leaf nodes
- while (page) {
- BtreeNodeProxy *node = m_btree->get_node_from_page(page);
- uint64_t right = node->get_right();
-
- m_visitor(m_context, node);
-
- /* follow the pointer to the right sibling */
- if (right)
- page = env->page_manager()->fetch(m_context, right, pm_flags);
- else
- break;
- }
- }
-
- private:
- BtreeIndex *m_btree;
- Context *m_context;
- BtreeVisitor &m_visitor;
- bool m_visit_internal_nodes;
-};
-
-void
-BtreeIndex::visit_nodes(Context *context, BtreeVisitor &visitor,
- bool visit_internal_nodes)
-{
- BtreeVisitAction bva(this, context, visitor, visit_internal_nodes);
- bva.run();
-}
-
-} // namespace hamsterdb
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_visitor.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_visitor.h
deleted file mode 100644
index 19770a9e70..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/btree_visitor.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_BTREE_VISITOR_H
-#define HAM_BTREE_VISITOR_H
-
-#include "0root/root.h"
-
-#include "ham/hamsterdb_ola.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// The ScanVisitor is the callback implementation for the scan call.
-// It will either receive single keys or multiple keys in an array.
-//
-struct ScanVisitor {
- // Operates on a single key
- virtual void operator()(const void *key_data, uint16_t key_size,
- size_t duplicate_count) = 0;
-
- // Operates on an array of keys
- virtual void operator()(const void *key_array, size_t key_count) = 0;
-
- // Assigns the internal result to |result|
- virtual void assign_result(hola_result_t *result) = 0;
-};
-
-struct Context;
-class BtreeNodeProxy;
-
-//
-// The BtreeVisitor is the callback implementation for the visit call.
-// It will visit each node instead of each key.
-//
-struct BtreeVisitor {
- // Specifies if the visitor modifies the node
- virtual bool is_read_only() const = 0;
-
- // called for each node
- virtual void operator()(Context *context, BtreeNodeProxy *node) = 0;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_VISITOR_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3btree/upfront_index.h b/plugins/Dbx_kv/src/hamsterdb/src/3btree/upfront_index.h
deleted file mode 100644
index b8aad1396d..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3btree/upfront_index.h
+++ /dev/null
@@ -1,684 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A small index which manages variable length buffers. Used to manage
- * variable length keys or records.
- *
- * The UpfrontIndex manages a range of bytes, organized in variable length
- * |chunks|, assigned at initialization time when calling |allocate()|
- * or |open()|.
- *
- * These chunks are organized in |slots|, each slot stores the offset and
- * the size of the chunk data. The offset is stored as 16- or 32-bit, depending
- * on the page size. The size is always a 16bit integer.
- *
- * The number of used slots is not stored in the UpfrontIndex, since it is
- * already managed in the caller (this is equal to |PBtreeNode::get_count()|).
- * Therefore you will see a lot of methods receiving a |node_count| parameter.
- *
- * Deleted chunks are moved to a |freelist|, which is simply a list of slots
- * directly following those slots that are in use.
- *
- * In addition, the UpfrontIndex keeps track of the unused space at the end
- * of the range (via |get_next_offset()|), in order to allow a fast
- * allocation of space.
- *
- * The UpfrontIndex stores metadata at the beginning:
- * [0..3] freelist count
- * [4..7] next offset
- * [8..11] capacity
- *
- * Data is stored in the following layout:
- * |metadata|slot1|slot2|...|slotN|free1|free2|...|freeM|data1|data2|...|dataN|
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_BTREE_UPFRONT_INDEX_H
-#define HAM_BTREE_UPFRONT_INDEX_H
-
-#include "0root/root.h"
-
-#include <algorithm>
-#include <vector>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1globals/globals.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-namespace DefLayout {
-
-/*
- * A helper class to sort ranges; used during validation of the up-front
- * index in check_index_integrity()
- */
-struct SortHelper {
- uint32_t offset;
- int slot;
-
- bool operator<(const SortHelper &rhs) const {
- return (offset < rhs.offset);
- }
-};
-
-static bool
-sort_by_offset(const SortHelper &lhs, const SortHelper &rhs) {
- return (lhs.offset < rhs.offset);
-}
-
-class UpfrontIndex
-{
- enum {
- // width of the 'size' field
- kSizeofSize = 1 // 1 byte - max chunk size is 255
- };
-
- public:
- enum {
- // for freelist_count, next_offset, capacity
- kPayloadOffset = 12,
-
- // minimum capacity of the index
- kMinimumCapacity = 16
- };
-
- // Constructor; creates an empty index which needs to be initialized
- // with |create()| or |open()|.
- UpfrontIndex(LocalDatabase *db)
- : m_data(0), m_range_size(0), m_vacuumize_counter(0) {
- size_t page_size = db->lenv()->config().page_size_bytes;
- if (page_size <= 64 * 1024)
- m_sizeof_offset = 2;
- else
- m_sizeof_offset = 4;
- }
-
- // Initialization routine; sets data pointer, range size and the
- // initial capacity.
- void create(uint8_t *data, size_t range_size, size_t capacity) {
- m_data = data;
- m_range_size = range_size;
- set_capacity(capacity);
- clear();
- }
-
- // "Opens" an existing index from memory. This method sets the data
- // pointer and initializes itself.
- void open(uint8_t *data, size_t range_size) {
- m_data = data;
- m_range_size = range_size;
- // the vacuumize-counter is not persisted, therefore
- // pretend that the counter is very high; in worst case this will cause
- // an invalid call to vacuumize(), which is not a problem
- if (get_freelist_count())
- m_vacuumize_counter = m_range_size;
- }
-
- // Changes the range size and capacity of the index; used to resize the
- // KeyList or RecordList
- void change_range_size(size_t node_count, uint8_t *new_data_ptr,
- size_t new_range_size, size_t new_capacity) {
- if (!new_data_ptr)
- new_data_ptr = m_data;
- if (!new_range_size)
- new_range_size = m_range_size;
-
- // get rid of the freelist and collect the garbage
- if (get_freelist_count() > 0)
- vacuumize(node_count);
- ham_assert(get_freelist_count() == 0);
-
- size_t used_data_size = get_next_offset(node_count);
- size_t old_capacity = get_capacity();
- uint8_t *src = &m_data[kPayloadOffset
- + old_capacity * get_full_index_size()];
- uint8_t *dst = &new_data_ptr[kPayloadOffset
- + new_capacity * get_full_index_size()];
-
- // if old range == new range then leave
- if (m_range_size == new_range_size
- && old_capacity == new_capacity
- && m_data == new_data_ptr )
- return;
-
- ham_assert(dst - new_data_ptr + used_data_size <= new_range_size);
-
- // shift "to the right"? Then first move the data and afterwards
- // the index
- if (dst > src) {
- memmove(dst, src, used_data_size);
- memmove(new_data_ptr, m_data,
- kPayloadOffset + new_capacity * get_full_index_size());
- }
- // vice versa otherwise
- else if (dst <= src) {
- if (new_data_ptr != m_data)
- memmove(new_data_ptr, m_data,
- kPayloadOffset + new_capacity * get_full_index_size());
- memmove(dst, src, used_data_size);
- }
-
- m_data = new_data_ptr;
- m_range_size = new_range_size;
- set_capacity(new_capacity);
- set_freelist_count(0);
- set_next_offset(used_data_size); // has dependency to get_freelist_count()
- }
-
- // Calculates the required size for a range
- size_t get_required_range_size(size_t node_count) const {
- return (UpfrontIndex::kPayloadOffset
- + get_capacity() * get_full_index_size()
- + get_next_offset(node_count));
- }
-
- // Returns the size of a single index entry
- size_t get_full_index_size() const {
- return (m_sizeof_offset + kSizeofSize);
- }
-
- // Transforms a relative offset of the payload data to an absolute offset
- // in |m_data|
- uint32_t get_absolute_offset(uint32_t offset) const {
- return (offset
- + kPayloadOffset
- + get_capacity() * get_full_index_size());
- }
-
- // Returns the absolute start offset of a chunk
- uint32_t get_absolute_chunk_offset(int slot) const {
- return (get_absolute_offset(get_chunk_offset(slot)));
- }
-
- // Returns the relative start offset of a chunk
- uint32_t get_chunk_offset(int slot) const {
- uint8_t *p = &m_data[kPayloadOffset + get_full_index_size() * slot];
- if (m_sizeof_offset == 2)
- return (*(uint16_t *)p);
- else {
- ham_assert(m_sizeof_offset == 4);
- return (*(uint32_t *)p);
- }
- }
-
- // Returns the size of a chunk
- uint16_t get_chunk_size(int slot) const {
- return (m_data[kPayloadOffset + get_full_index_size() * slot
- + m_sizeof_offset]);
- }
-
- // Sets the size of a chunk (does NOT actually resize the chunk!)
- void set_chunk_size(int slot, uint16_t size) {
- ham_assert(size <= 255);
- m_data[kPayloadOffset + get_full_index_size() * slot + m_sizeof_offset]
- = (uint8_t)size;
- }
-
- // Increases the "vacuumize-counter", which is an indicator whether
- // rearranging the node makes sense
- void increase_vacuumize_counter(size_t gap_size) {
- m_vacuumize_counter += gap_size;
- }
-
- // Vacuumizes the index, *if it makes sense*. Returns true if the
- // operation was successful, otherwise false
- bool maybe_vacuumize(size_t node_count) {
- if (m_vacuumize_counter > 0 || get_freelist_count() > 0) {
- vacuumize(node_count);
- return (true);
- }
- return (false);
- }
-
- // Returns true if this index has at least one free slot available.
- // |node_count| is the number of used slots (this is managed by the caller)
- bool can_insert(size_t node_count) {
- return (likely(node_count + get_freelist_count() < get_capacity()));
- }
-
- // Inserts a slot at the position |slot|. |node_count| is the number of
- // used slots (this is managed by the caller)
- void insert(size_t node_count, int slot) {
- ham_assert(can_insert(node_count) == true);
-
- size_t slot_size = get_full_index_size();
- size_t total_count = node_count + get_freelist_count();
- uint8_t *p = &m_data[kPayloadOffset + slot_size * slot];
- if (total_count > 0 && slot < (int)total_count) {
- // create a gap in the index
- memmove(p + slot_size, p, slot_size * (total_count - slot));
- }
-
- // now fill the gap
- memset(p, 0, slot_size);
- }
-
- // Erases a slot at the position |slot|
- // |node_count| is the number of used slots (this is managed by the caller)
- void erase(size_t node_count, int slot) {
- size_t slot_size = get_full_index_size();
- size_t total_count = node_count + get_freelist_count();
-
- ham_assert(slot < (int)total_count);
-
- set_freelist_count(get_freelist_count() + 1);
-
- size_t chunk_size = get_chunk_size(slot);
-
- increase_vacuumize_counter(chunk_size);
-
- // nothing to do if we delete the very last (used) slot; the freelist
- // counter was already incremented, the used counter is decremented
- // by the caller
- if (slot == (int)node_count - 1)
- return;
-
- size_t chunk_offset = get_chunk_offset(slot);
-
- // shift all items to the left
- uint8_t *p = &m_data[kPayloadOffset + slot_size * slot];
- memmove(p, p + slot_size, slot_size * (total_count - slot));
-
- // then copy the deleted chunk to the freelist
- set_chunk_offset(total_count - 1, chunk_offset);
- set_chunk_size(total_count - 1, chunk_size);
- }
-
- // Adds a chunk to the freelist. Will not do anything if the node
- // is already full.
- void add_to_freelist(size_t node_count, uint32_t chunk_offset,
- uint32_t chunk_size) {
- size_t total_count = node_count + get_freelist_count();
- if (likely(total_count < get_capacity())) {
- set_freelist_count(get_freelist_count() + 1);
- set_chunk_size(total_count, chunk_size);
- set_chunk_offset(total_count, chunk_offset);
- }
- }
-
- // Returns true if this page has enough space to store at least |num_bytes|
- // bytes.
- bool can_allocate_space(size_t node_count, size_t num_bytes) {
- // first check if we can append the data; this is the cheapest check,
- // therefore it comes first
- if (get_next_offset(node_count) + num_bytes <= get_usable_data_size())
- return (true);
-
- // otherwise check the freelist
- uint32_t total_count = node_count + get_freelist_count();
- for (uint32_t i = node_count; i < total_count; i++)
- if (get_chunk_size(i) >= num_bytes)
- return (true);
- return (false);
- }
-
- // Allocates space for a |slot| and returns the offset of that chunk
- uint32_t allocate_space(size_t node_count, int slot,
- size_t num_bytes) {
- ham_assert(can_allocate_space(node_count, num_bytes));
-
- size_t next_offset = get_next_offset(node_count);
-
- // try to allocate space at the end of the node
- if (next_offset + num_bytes <= get_usable_data_size()) {
- uint32_t offset = get_chunk_offset(slot);
- // if this slot's data is at the very end then maybe it can be
- // resized without actually moving the data
- if (unlikely(next_offset == offset + get_chunk_size(slot))) {
- set_next_offset(offset + num_bytes);
- set_chunk_size(slot, num_bytes);
- return (offset);
- }
- set_next_offset(next_offset + num_bytes);
- set_chunk_offset(slot, next_offset);
- set_chunk_size(slot, num_bytes);
- return (next_offset);
- }
-
- size_t slot_size = get_full_index_size();
-
- // otherwise check the freelist
- uint32_t total_count = node_count + get_freelist_count();
- for (uint32_t i = node_count; i < total_count; i++) {
- uint32_t chunk_size = get_chunk_size(i);
- uint32_t chunk_offset = get_chunk_offset(i);
- if (chunk_size >= num_bytes) {
- // update next_offset?
- if (unlikely(next_offset == chunk_offset + chunk_size))
- invalidate_next_offset();
- else if (unlikely(next_offset == get_chunk_offset(slot)
- + get_chunk_size(slot)))
- invalidate_next_offset();
- // copy the chunk to the new slot
- set_chunk_size(slot, num_bytes);
- set_chunk_offset(slot, chunk_offset);
- // remove from the freelist
- if (i < total_count - 1) {
- uint8_t *p = &m_data[kPayloadOffset + slot_size * i];
- memmove(p, p + slot_size, slot_size * (total_count - i - 1));
- }
- set_freelist_count(get_freelist_count() - 1);
- return (get_chunk_offset(slot));
- }
- }
-
- ham_assert(!"shouldn't be here");
- throw Exception(HAM_INTERNAL_ERROR);
- }
-
- // Returns true if |key| cannot be inserted because a split is required.
- // Unlike implied by the name, this function will try to re-arrange the
- // node in order for the key to fit in.
- bool requires_split(size_t node_count, size_t required_size) {
- return (!can_insert(node_count)
- || !can_allocate_space(node_count, required_size));
- }
-
- // Verifies that there are no overlapping chunks
- void check_integrity(size_t node_count) const {
- typedef std::pair<uint32_t, uint32_t> Range;
- //typedef std::vector<Range> RangeVec;
- uint32_t total_count = node_count + get_freelist_count();
-
- ham_assert(node_count > 1
- ? get_next_offset(node_count) > 0
- : true);
-
- if (total_count > get_capacity()) {
- ham_trace(("integrity violated: total count %u (%u+%u) > capacity %u",
- total_count, node_count, get_freelist_count(),
- get_capacity()));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
-
- //RangeVec ranges;
- //ranges.reserve(total_count);
- uint32_t next_offset = 0;
- for (uint32_t i = 0; i < total_count; i++) {
- Range range = std::make_pair(get_chunk_offset(i), get_chunk_size(i));
- uint32_t next = range.first + range.second;
- if (next >= next_offset)
- next_offset = next;
- //ranges.push_back(range);
- }
-
-#if 0
- std::sort(ranges.begin(), ranges.end());
-
- if (!ranges.empty()) {
- for (uint32_t i = 0; i < ranges.size() - 1; i++) {
- if (ranges[i].first + ranges[i].second > ranges[i + 1].first) {
- ham_trace(("integrity violated: slot %u/%u overlaps with %lu",
- ranges[i].first, ranges[i].second,
- ranges[i + 1].first));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- }
- }
-#endif
-
- if (next_offset != get_next_offset(node_count)) {
- ham_trace(("integrity violated: next offset %d, cached offset %d",
- next_offset, get_next_offset(node_count)));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- if (next_offset != calc_next_offset(node_count)) {
- ham_trace(("integrity violated: next offset %d, calculated offset %d",
- next_offset, calc_next_offset(node_count)));
- throw Exception(HAM_INTEGRITY_VIOLATED);
- }
- }
-
- // Splits an index and moves all chunks starting from position |pivot|
- // to the other index.
- // The other index *must* be empty!
- void split(UpfrontIndex *other, size_t node_count, int pivot) {
- other->clear();
-
- // now copy key by key
- for (size_t i = pivot; i < node_count; i++) {
- other->insert(i - pivot, i - pivot);
- uint32_t size = get_chunk_size(i);
- uint32_t offset = other->allocate_space(i - pivot, i - pivot, size);
- memcpy(other->get_chunk_data_by_offset(offset),
- get_chunk_data_by_offset(get_chunk_offset(i)),
- size);
- }
-
- // this node has lost lots of its data - make sure that it will be
- // vacuumized as soon as more data is allocated
- m_vacuumize_counter += node_count;
- set_freelist_count(0);
- set_next_offset((uint32_t)-1);
- }
-
- // Merges all chunks from the |other| index to this index
- void merge_from(UpfrontIndex *other, size_t node_count,
- size_t other_node_count) {
- vacuumize(node_count);
-
- for (size_t i = 0; i < other_node_count; i++) {
- insert(i + node_count, i + node_count);
- uint32_t size = other->get_chunk_size(i);
- uint32_t offset = allocate_space(i + node_count, i + node_count, size);
- memcpy(get_chunk_data_by_offset(offset),
- other->get_chunk_data_by_offset(other->get_chunk_offset(i)),
- size);
- }
-
- other->clear();
- }
-
- // Returns a pointer to the actual data of a chunk
- uint8_t *get_chunk_data_by_offset(uint32_t offset) {
- return (&m_data[kPayloadOffset
- + get_capacity() * get_full_index_size()
- + offset]);
- }
-
- // Returns a pointer to the actual data of a chunk
- uint8_t *get_chunk_data_by_offset(uint32_t offset) const {
- return (&m_data[kPayloadOffset
- + get_capacity() * get_full_index_size()
- + offset]);
- }
-
- // Reduces the capacity of the UpfrontIndex, if required
- void reduce_capacity(size_t node_count) {
- size_t old_capacity = get_capacity();
- if (node_count > 0 && old_capacity > node_count + 4) {
- size_t new_capacity = old_capacity - (old_capacity - node_count) / 2;
- if (new_capacity != old_capacity)
- change_range_size(node_count, m_data, m_range_size, new_capacity);
- }
- }
-
- // Re-arranges the node: moves all keys sequentially to the beginning
- // of the key space, removes the whole freelist.
- //
- // This call is extremely expensive! Try to avoid it as much as possible.
- void vacuumize(size_t node_count) {
- if (m_vacuumize_counter < 10) {
- if (get_freelist_count() > 0) {
- set_freelist_count(0);
- invalidate_next_offset();
- }
- return;
- }
-
- // get rid of the freelist - this node is now completely rewritten,
- // and the freelist would just complicate things
- set_freelist_count(0);
-
- // make a copy of all indices (excluding the freelist)
- bool requires_sort = false;
- SortHelper *s = (SortHelper *)::alloca(node_count * sizeof(SortHelper));
- for (size_t i = 0; i < node_count; i++) {
- s[i].slot = i;
- s[i].offset = get_chunk_offset(i);
- if (i > 0 && s[i].offset < s[i - 1].offset)
- requires_sort = true;
- }
-
- // sort them by offset; this is a very expensive call. only sort if
- // it's absolutely necessary!
- if (requires_sort)
- std::sort(&s[0], &s[node_count], sort_by_offset);
-
- // shift all keys to the left, get rid of all gaps at the front of the
- // key data or between the keys
- uint32_t next_offset = 0;
- uint32_t start = kPayloadOffset + get_capacity() * get_full_index_size();
- for (size_t i = 0; i < node_count; i++) {
- uint32_t offset = s[i].offset;
- int slot = s[i].slot;
- uint32_t size = get_chunk_size(slot);
- if (offset != next_offset) {
- // shift key to the left
- memmove(&m_data[start + next_offset],
- get_chunk_data_by_offset(offset), size);
- // store the new offset
- set_chunk_offset(slot, next_offset);
- }
- next_offset += size;
- }
-
- set_next_offset(next_offset);
- m_vacuumize_counter = 0;
- }
-
- // Invalidates the cached "next offset". In some cases it's necessary
- // that the caller forces a re-evaluation of the next offset. Although
- // i *think* that this method could become private, but the effort
- // is not worth the gain.
- void invalidate_next_offset() {
- set_next_offset((uint32_t)-1);
- }
-
- // Same as above, but only if the next_offset equals |new_offset|
- void maybe_invalidate_next_offset(size_t new_offset) {
- if (get_next_offset(0) == new_offset)
- invalidate_next_offset();
- }
-
- // Returns the capacity
- size_t get_capacity() const {
- return (*(uint32_t *)(m_data + 8));
- }
-
- // Returns the offset of the unused space at the end of the page
- uint32_t get_next_offset(size_t node_count) {
- uint32_t ret = *(uint32_t *)(m_data + 4);
- if (unlikely(ret == (uint32_t)-1 && node_count > 0)) {
- ret = calc_next_offset(node_count);
- set_next_offset(ret);
- }
- return (ret);
- }
-
- private:
- friend class UpfrontIndexFixture;
-
- // Resets the page
- void clear() {
- set_freelist_count(0);
- set_next_offset(0);
- m_vacuumize_counter = 0;
- }
-
- // Returns the offset of the unused space at the end of the page
- // (const version)
- uint32_t get_next_offset(size_t node_count) const {
- uint32_t ret = *(uint32_t *)(m_data + 4);
- if (unlikely(ret == (uint32_t)-1))
- return (calc_next_offset(node_count));
- return (ret);
- }
-
- // Returns the size (in bytes) where payload data can be stored
- size_t get_usable_data_size() const {
- return (m_range_size - kPayloadOffset
- - get_capacity() * get_full_index_size());
- }
-
- // Sets the chunk offset of a slot
- void set_chunk_offset(int slot, uint32_t offset) {
- uint8_t *p = &m_data[kPayloadOffset + get_full_index_size() * slot];
- if (m_sizeof_offset == 2)
- *(uint16_t *)p = (uint16_t)offset;
- else
- *(uint32_t *)p = offset;
- }
-
- // Returns the number of freelist entries
- size_t get_freelist_count() const {
- return (*(uint32_t *)m_data);
- }
-
- // Sets the number of freelist entries
- void set_freelist_count(size_t freelist_count) {
- ham_assert(freelist_count <= get_capacity());
- *(uint32_t *)m_data = freelist_count;
- }
-
- // Calculates and returns the next offset; does not store it
- uint32_t calc_next_offset(size_t node_count) const {
- uint32_t total_count = node_count + get_freelist_count();
- uint32_t next_offset = 0;
- for (uint32_t i = 0; i < total_count; i++) {
- uint32_t next = get_chunk_offset(i) + get_chunk_size(i);
- if (next >= next_offset)
- next_offset = next;
- }
- return (next_offset);
- }
-
- // Sets the offset of the unused space at the end of the page
- void set_next_offset(uint32_t next_offset) {
- *(uint32_t *)(m_data + 4) = next_offset;
- }
-
- // Sets the capacity (number of slots)
- void set_capacity(size_t capacity) {
- ham_assert(capacity > 0);
- *(uint32_t *)(m_data + 8) = (uint32_t)capacity;
- }
-
- // The physical data in the node
- uint8_t *m_data;
-
- // The size of the offset; either 16 or 32 bits, depending on page size
- size_t m_sizeof_offset;
-
- // The size of the range, in bytes
- size_t m_range_size;
-
- // A counter to indicate when rearranging the data makes sense
- int m_vacuumize_counter;
-};
-
-} // namespace DefLayout
-
-} // namespace hamsterdb
-
-#endif /* HAM_BTREE_UPFRONT_INDEX_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3cache/cache.h b/plugins/Dbx_kv/src/hamsterdb/src/3cache/cache.h
deleted file mode 100644
index a24daf3828..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3cache/cache.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The Cache Manager
- *
- * Stores pages in a non-intrusive hash table (each Page instance keeps
- * next/previous pointers for the overflow bucket). Can efficiently purge
- * unused pages, because all pages are also stored in a (non-intrusive)
- * linked list, and whenever a page is accessed it is removed and re-inserted
- * at the head. The tail therefore points to the page which was not used
- * in a long time, and is the primary candidate for purging.
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_CACHE_H
-#define HAM_CACHE_H
-
-#include "0root/root.h"
-
-#include <vector>
-
-#include "ham/hamsterdb_int.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "2page/page.h"
-#include "2page/page_collection.h"
-#include "2config/env_config.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Cache
-{
- enum {
- // The number of buckets should be a prime number or similar, as it
- // is used in a MODULO hash scheme
- kBucketSize = 10317,
- };
-
- template<typename Purger>
- struct PurgeIfSelector
- {
- PurgeIfSelector(Cache *cache, Purger &purger)
- : m_cache(cache), m_purger(purger) {
- }
-
- bool operator()(Page *page) {
- if (m_purger(page)) {
- m_cache->del(page);
- delete page;
- }
- // don't remove page from list; it was already removed above
- return (false);
- }
-
- Cache *m_cache;
- Purger &m_purger;
- };
-
- public:
- // The default constructor
- Cache(const EnvironmentConfiguration &config)
- : m_capacity_bytes(config.flags & HAM_CACHE_UNLIMITED
- ? 0xffffffffffffffffull
- : config.cache_size_bytes),
- m_page_size_bytes(config.page_size_bytes),
- m_alloc_elements(0), m_totallist(Page::kListCache),
- m_buckets(kBucketSize, PageCollection(Page::kListBucket)),
- m_cache_hits(0), m_cache_misses(0) {
- ham_assert(m_capacity_bytes > 0);
- }
-
- // Fills in the current metrics
- void fill_metrics(ham_env_metrics_t *metrics) const {
- metrics->cache_hits = m_cache_hits;
- metrics->cache_misses = m_cache_misses;
- }
-
- // Retrieves a page from the cache, also removes the page from the cache
- // and re-inserts it at the front. Returns null if the page was not cached.
- Page *get(uint64_t address) {
- size_t hash = calc_hash(address);
-
- Page *page = m_buckets[hash].get(address);;
- if (!page) {
- m_cache_misses++;
- return (0);
- }
-
- // Now re-insert the page at the head of the "totallist", and
- // thus move far away from the tail. The pages at the tail are highest
- // candidates to be deleted when the cache is purged.
- m_totallist.del(page);
- m_totallist.put(page);
- m_cache_hits++;
- return (page);
- }
-
- // Stores a page in the cache
- void put(Page *page) {
- size_t hash = calc_hash(page->get_address());
- ham_assert(page->get_data());
-
- /* First remove the page from the cache, if it's already cached
- *
- * Then re-insert the page at the head of the list. The tail will
- * point to the least recently used page.
- */
- m_totallist.del(page);
- m_totallist.put(page);
-
- if (page->is_allocated())
- m_alloc_elements++;
- m_buckets[hash].put(page);
- }
-
- // Removes a page from the cache
- void del(Page *page) {
- ham_assert(page->get_address() != 0);
- size_t hash = calc_hash(page->get_address());
- /* remove the page from the cache buckets */
- m_buckets[hash].del(page);
-
- /* remove it from the list of all cached pages */
- if (m_totallist.del(page) && page->is_allocated())
- m_alloc_elements--;
- }
-
- // Purges the cache. Implements a LRU eviction algorithm. Dirty pages are
- // forwarded to the |processor()| for flushing.
- //
- // Tries to purge at least 20 pages. In benchmarks this has proven to
- // be a good limit.
- template<typename Processor>
- void purge(Processor &processor, Page *ignore_page) {
- int limit = int(current_elements()
- - (m_capacity_bytes / m_page_size_bytes));
-
- Page *page = m_totallist.tail();
- for (int i = 0; i < limit && page != 0; i++) {
- Page *next = page->get_previous(Page::kListCache);
-
- // dirty pages are flushed by the worker thread
- if (page->is_dirty()) {
- processor(page);
- page = next;
- continue;
- }
- // non-dirty pages are deleted if possible
- if (!page->is_dirty()
- && page->cursor_list() == 0
- && page != ignore_page
- && page->mutex().try_lock()) {
- del(page);
- page->mutex().unlock();
- delete page;
- }
-
- page = next;
- }
- }
-
- // Visits all pages in the "totallist". If |cb| returns true then the
- // page is removed and deleted. This is used by the Environment
- // to flush (and delete) pages.
- template<typename Purger>
- void purge_if(Purger &purger) {
- PurgeIfSelector<Purger> selector(this, purger);
- m_totallist.extract(selector);
- }
-
- // Returns true if the capacity limits are exceeded
- bool is_cache_full() const {
- return (current_elements() * m_page_size_bytes
- > m_capacity_bytes);
- }
-
- // Returns the capacity (in bytes)
- uint64_t capacity() const {
- return (m_capacity_bytes);
- }
-
- // Returns the number of currently cached elements
- size_t current_elements() const {
- return (m_totallist.size());
- }
-
- // Returns the number of currently cached elements (excluding those that
- // are mmapped)
- size_t allocated_elements() const {
- return (m_alloc_elements);
- }
-
- private:
- // Calculates the hash of a page address
- size_t calc_hash(uint64_t value) const {
- return ((size_t)(value % Cache::kBucketSize));
- }
-
- // the capacity (in bytes)
- uint64_t m_capacity_bytes;
-
- // the current page size (in bytes)
- uint64_t m_page_size_bytes;
-
- // the current number of cached elements that were allocated (and not
- // mapped)
- size_t m_alloc_elements;
-
- // linked list of ALL cached pages
- PageCollection m_totallist;
-
- // The hash table buckets - each is a linked list of Page pointers
- std::vector<PageCollection> m_buckets;
-
- // counts the cache hits
- uint64_t m_cache_hits;
-
- // counts the cache misses
- uint64_t m_cache_misses;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_CACHE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3changeset/changeset.cc b/plugins/Dbx_kv/src/hamsterdb/src/3changeset/changeset.cc
deleted file mode 100644
index 2e5ace06f5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3changeset/changeset.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// Always verify that a file of level N does not include headers > N!
-#include "1errorinducer/errorinducer.h"
-#include "2device/device.h"
-#include "2page/page.h"
-#include "3changeset/changeset.h"
-#include "3journal/journal.h"
-#include "3page_manager/page_manager.h"
-#include "4db/db.h"
-#include "4env/env_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/* a unittest hook for Changeset::flush() */
-void (*g_CHANGESET_POST_LOG_HOOK)(void);
-
-struct PageCollectionVisitor
-{
- PageCollectionVisitor(Page **pages)
- : num_pages(0), pages(pages) {
- }
-
- void prepare(size_t size) {
- }
-
- bool operator()(Page *page) {
- if (page->is_dirty() == true) {
- pages[num_pages] = page;
- ++num_pages;
- }
- // |page| is now removed from the Changeset
- page->mutex().unlock();
- return (true);
- }
-
- int num_pages;
- Page **pages;
-};
-
-void
-Changeset::flush(uint64_t lsn)
-{
- // now flush all modified pages to disk
- if (m_collection.is_empty())
- return;
-
- HAM_INDUCE_ERROR(ErrorInducer::kChangesetFlush);
-
- // Fetch the pages, ignoring all pages that are not dirty
- Page **pages = (Page **)::alloca(sizeof(Page *) * m_collection.size());
- PageCollectionVisitor visitor(pages);
- m_collection.extract(visitor);
-
- // TODO sort by address (really?)
-
- if (visitor.num_pages == 0)
- return;
-
- // If only one page is modified then the modification is atomic. The page
- // is written to the btree (no log required).
- //
- // If more than one page is modified then the modification is no longer
- // atomic. All dirty pages are written to the log.
- if (visitor.num_pages > 1) {
- m_env->journal()->append_changeset((const Page **)visitor.pages,
- visitor.num_pages, lsn);
- }
-
- HAM_INDUCE_ERROR(ErrorInducer::kChangesetFlush);
-
- /* execute a post-log hook; this hook is set by the unittest framework
- * and can be used to make a backup copy of the logfile */
- if (g_CHANGESET_POST_LOG_HOOK)
- g_CHANGESET_POST_LOG_HOOK();
-
- /* now write all the pages to the file; if any of these writes fail,
- * we can still recover from the log */
- for (int i = 0; i < visitor.num_pages; i++) {
- Page *p = visitor.pages[i];
- if (p->is_without_header() == false)
- p->set_lsn(lsn);
- p->flush();
-
- HAM_INDUCE_ERROR(ErrorInducer::kChangesetFlush);
- }
-
- /* flush the file handle (if required) */
- if (m_env->get_flags() & HAM_ENABLE_FSYNC)
- m_env->device()->flush();
-
- HAM_INDUCE_ERROR(ErrorInducer::kChangesetFlush);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3changeset/changeset.h b/plugins/Dbx_kv/src/hamsterdb/src/3changeset/changeset.h
deleted file mode 100644
index a21c6f45f9..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3changeset/changeset.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A changeset collects all pages that are modified during a single
- * operation.
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_CHANGESET_H
-#define HAM_CHANGESET_H
-
-#include "0root/root.h"
-
-#include <stdlib.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "2page/page.h"
-#include "2page/page_collection.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class LocalEnvironment;
-
-class Changeset
-{
- struct UnlockPage
- {
- bool operator()(Page *page) {
- #ifdef HAM_ENABLE_HELGRIND
- page->mutex().try_lock();
- #endif
- page->mutex().unlock();
- return (true);
- }
- };
-
- public:
- Changeset(LocalEnvironment *env)
- : m_env(env), m_collection(Page::kListChangeset) {
- }
-
- /*
- * Returns a page from the changeset, or NULL if the page is not part
- * of the changeset
- */
- Page *get(uint64_t address) {
- return (m_collection.get(address));
- }
-
- /* Append a new page to the changeset. The page is locked. */
- void put(Page *page) {
- if (!has(page)) {
- page->mutex().lock();
- }
- m_collection.put(page);
- }
-
- /* Removes a page from the changeset. The page is unlocked. */
- void del(Page *page) {
- page->mutex().unlock();
- m_collection.del(page);
- }
-
- /* Check if the page is already part of the changeset */
- bool has(Page *page) const {
- return (m_collection.has(page));
- }
-
- /* Returns true if the changeset is empty */
- bool is_empty() const {
- return (m_collection.is_empty());
- }
-
- /* Removes all pages from the changeset. The pages are unlocked. */
- void clear() {
- UnlockPage unlocker;
- m_collection.for_each(unlocker);
- m_collection.clear();
- }
-
- /*
- * Flush all pages in the changeset - first write them to the log, then
- * write them to the disk.
- * On success: will clear the changeset and the journal
- */
- void flush(uint64_t lsn);
-
- private:
- /* The Environment */
- LocalEnvironment *m_env;
-
- /* The pages which were added to this Changeset */
- PageCollection m_collection;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_CHANGESET_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal.cc b/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal.cc
deleted file mode 100644
index 50e749240f..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal.cc
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-#ifndef HAM_OS_WIN32
-# include <libgen.h>
-#endif
-
-#include "1base/error.h"
-#include "1errorinducer/errorinducer.h"
-#include "1os/os.h"
-#include "2device/device.h"
-#include "3journal/journal.h"
-#include "3page_manager/page_manager.h"
-#include "4db/db.h"
-#include "4txn/txn_local.h"
-#include "4env/env_local.h"
-#include "4context/context.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-Journal::Journal(LocalEnvironment *env)
- : m_state(env)
-{
-}
-
-void
-Journal::create()
-{
- // create the two files
- for (int i = 0; i < 2; i++) {
- std::string path = get_path(i);
- m_state.files[i].create(path.c_str(), 0644);
- }
-}
-
-void
-Journal::open()
-{
- // open the two files
- try {
- std::string path = get_path(0);
- m_state.files[0].open(path.c_str(), false);
- path = get_path(1);
- m_state.files[1].open(path.c_str(), 0);
- }
- catch (Exception &ex) {
- m_state.files[1].close();
- m_state.files[0].close();
- throw ex;
- }
-}
-
-int
-Journal::switch_files_maybe()
-{
- int other = m_state.current_fd ? 0 : 1;
-
- // determine the journal file which is used for this transaction
- // if the "current" file is not yet full, continue to write to this file
- if (m_state.open_txn[m_state.current_fd]
- + m_state.closed_txn[m_state.current_fd]
- < m_state.threshold)
- return (m_state.current_fd);
-
- // If the other file does no longer have open Transactions then
- // delete the other file and use the other file as the current file
- if (m_state.open_txn[other] == 0) {
- clear_file(other);
- m_state.current_fd = other;
- // fall through
- }
-
- // Otherwise just continue using the current file
- return (m_state.current_fd);
-}
-
-void
-Journal::append_txn_begin(LocalTransaction *txn, const char *name, uint64_t lsn)
-{
- if (m_state.disable_logging)
- return;
-
- ham_assert((txn->get_flags() & HAM_TXN_TEMPORARY) == 0);
-
- PJournalEntry entry;
- entry.txn_id = txn->get_id();
- entry.type = kEntryTypeTxnBegin;
- entry.lsn = lsn;
- if (name)
- entry.followup_size = strlen(name) + 1;
-
- txn->set_log_desc(switch_files_maybe());
-
- int cur = txn->get_log_desc();
-
- if (txn->get_name().size())
- append_entry(cur, (uint8_t *)&entry, (uint32_t)sizeof(entry),
- (uint8_t *)txn->get_name().c_str(),
- (uint32_t)txn->get_name().size() + 1);
- else
- append_entry(cur, (uint8_t *)&entry, (uint32_t)sizeof(entry));
- maybe_flush_buffer(cur);
-
- m_state.open_txn[cur]++;
-
- // store the fp-index in the journal structure; it's needed for
- // journal_append_checkpoint() to quickly find out which file is
- // the newest
- m_state.current_fd = cur;
-}
-
-void
-Journal::append_txn_abort(LocalTransaction *txn, uint64_t lsn)
-{
- if (m_state.disable_logging)
- return;
-
- ham_assert((txn->get_flags() & HAM_TXN_TEMPORARY) == 0);
-
- int idx;
- PJournalEntry entry;
- entry.lsn = lsn;
- entry.txn_id = txn->get_id();
- entry.type = kEntryTypeTxnAbort;
-
- // update the transaction counters of this logfile
- idx = txn->get_log_desc();
- m_state.open_txn[idx]--;
- m_state.closed_txn[idx]++;
-
- append_entry(idx, (uint8_t *)&entry, sizeof(entry));
- maybe_flush_buffer(idx);
- // no need for fsync - incomplete transactions will be aborted anyway
-}
-
-void
-Journal::append_txn_commit(LocalTransaction *txn, uint64_t lsn)
-{
- if (m_state.disable_logging)
- return;
-
- ham_assert((txn->get_flags() & HAM_TXN_TEMPORARY) == 0);
-
- PJournalEntry entry;
- entry.lsn = lsn;
- entry.txn_id = txn->get_id();
- entry.type = kEntryTypeTxnCommit;
-
- // do not yet update the transaction counters of this logfile; just
- // because the txn was committed does not mean that it will be flushed
- // immediately. The counters will be modified in transaction_flushed().
- int idx = txn->get_log_desc();
-
- append_entry(idx, (uint8_t *)&entry, sizeof(entry));
-
- // and flush the file
- flush_buffer(idx, m_state.env->get_flags() & HAM_ENABLE_FSYNC);
-}
-
-void
-Journal::append_insert(Database *db, LocalTransaction *txn,
- ham_key_t *key, ham_record_t *record, uint32_t flags,
- uint64_t lsn)
-{
- if (m_state.disable_logging)
- return;
-
- PJournalEntry entry;
- PJournalEntryInsert insert;
- uint32_t size = sizeof(PJournalEntryInsert)
- + key->size
- + (flags & HAM_PARTIAL
- ? record->partial_size
- : record->size)
- - 1;
-
- entry.lsn = lsn;
- entry.dbname = db->name();
- entry.type = kEntryTypeInsert;
- entry.followup_size = size;
-
- int idx;
- if (txn->get_flags() & HAM_TXN_TEMPORARY) {
- entry.txn_id = 0;
- idx = switch_files_maybe();
- m_state.closed_txn[idx]++;
- }
- else {
- entry.txn_id = txn->get_id();
- idx = txn->get_log_desc();
- }
-
- insert.key_size = key->size;
- insert.record_size = record->size;
- insert.record_partial_size = record->partial_size;
- insert.record_partial_offset = record->partial_offset;
- insert.insert_flags = flags;
-
- // append the entry to the logfile
- append_entry(idx, (uint8_t *)&entry, sizeof(entry),
- (uint8_t *)&insert, sizeof(PJournalEntryInsert) - 1,
- (uint8_t *)key->data, key->size,
- (uint8_t *)record->data, (flags & HAM_PARTIAL
- ? record->partial_size
- : record->size));
- maybe_flush_buffer(idx);
-}
-
-void
-Journal::append_erase(Database *db, LocalTransaction *txn, ham_key_t *key,
- int duplicate_index, uint32_t flags, uint64_t lsn)
-{
- if (m_state.disable_logging)
- return;
-
- PJournalEntry entry;
- PJournalEntryErase erase;
- uint32_t size = sizeof(PJournalEntryErase) + key->size - 1;
-
- entry.lsn = lsn;
- entry.dbname = db->name();
- entry.type = kEntryTypeErase;
- entry.followup_size = size;
- erase.key_size = key->size;
- erase.erase_flags = flags;
- erase.duplicate = duplicate_index;
-
- int idx;
- if (txn->get_flags() & HAM_TXN_TEMPORARY) {
- entry.txn_id = 0;
- idx = switch_files_maybe();
- m_state.closed_txn[idx]++;
- }
- else {
- entry.txn_id = txn->get_id();
- idx = txn->get_log_desc();
- }
-
- // append the entry to the logfile
- append_entry(idx, (uint8_t *)&entry, sizeof(entry),
- (uint8_t *)&erase, sizeof(PJournalEntryErase) - 1,
- (uint8_t *)key->data, key->size);
- maybe_flush_buffer(idx);
-}
-
-void
-Journal::append_changeset(const Page **pages, int num_pages, uint64_t lsn)
-{
- if (m_state.disable_logging)
- return;
-
- PJournalEntry entry;
- PJournalEntryChangeset changeset;
-
- entry.lsn = lsn;
- entry.dbname = 0;
- entry.txn_id = 0;
- entry.type = kEntryTypeChangeset;
- // followup_size is incomplete - the actual page sizes are added later
- entry.followup_size = sizeof(PJournalEntryChangeset);
- changeset.num_pages = num_pages;
-
- // we need the current position in the file buffer. if compression is enabled
- // then we do not know the actual followup-size of this entry. it will be
- // patched in later.
- uint32_t entry_position = m_state.buffer[m_state.current_fd].get_size();
-
- // write the data to the file
- append_entry(m_state.current_fd, (uint8_t *)&entry, sizeof(entry),
- (uint8_t *)&changeset, sizeof(PJournalEntryChangeset));
-
- size_t page_size = m_state.env->config().page_size_bytes;
- for (int i = 0; i < num_pages; i++) {
- entry.followup_size += append_changeset_page(pages[i], page_size);
- }
-
- HAM_INDUCE_ERROR(ErrorInducer::kChangesetFlush);
-
- // and patch in the followup-size
- m_state.buffer[m_state.current_fd].overwrite(entry_position,
- (uint8_t *)&entry, sizeof(entry));
-
- HAM_INDUCE_ERROR(ErrorInducer::kChangesetFlush);
-
- // and flush the file
- flush_buffer(m_state.current_fd, m_state.env->get_flags() & HAM_ENABLE_FSYNC);
-
- HAM_INDUCE_ERROR(ErrorInducer::kChangesetFlush);
-
- // if recovery is enabled (w/o transactions) then simulate a "commit" to
- // make sure that the log files are switched properly
- m_state.closed_txn[m_state.current_fd]++;
- (void)switch_files_maybe();
-}
-
-uint32_t
-Journal::append_changeset_page(const Page *page, uint32_t page_size)
-{
- PJournalEntryPageHeader header(page->get_address());
-
- append_entry(m_state.current_fd, (uint8_t *)&header, sizeof(header),
- page->get_raw_payload(), page_size);
- return (page_size + sizeof(header));
-}
-
-void
-Journal::transaction_flushed(LocalTransaction *txn)
-{
- ham_assert((txn->get_flags() & HAM_TXN_TEMPORARY) == 0);
- if (m_state.disable_logging) // ignore this call during recovery
- return;
-
- int idx = txn->get_log_desc();
- ham_assert(m_state.open_txn[idx] > 0);
- m_state.open_txn[idx]--;
- m_state.closed_txn[idx]++;
-}
-
-void
-Journal::get_entry(Iterator *iter, PJournalEntry *entry, ByteArray *auxbuffer)
-{
- uint64_t filesize;
-
- auxbuffer->clear();
-
- // if iter->offset is 0, then the iterator was created from scratch
- // and we start reading from the first (oldest) entry.
- //
- // The oldest of the two logfiles is always the "other" one (the one
- // NOT in current_fd).
- if (iter->offset == 0) {
- iter->fdstart = iter->fdidx =
- m_state.current_fd == 0
- ? 1
- : 0;
- }
-
- // get the size of the journal file
- filesize = m_state.files[iter->fdidx].get_file_size();
-
- // reached EOF? then either skip to the next file or we're done
- if (filesize == iter->offset) {
- if (iter->fdstart == iter->fdidx) {
- iter->fdidx = iter->fdidx == 1 ? 0 : 1;
- iter->offset = 0;
- filesize = m_state.files[iter->fdidx].get_file_size();
- }
- else {
- entry->lsn = 0;
- return;
- }
- }
-
- // second file is also empty? then return
- if (filesize == iter->offset) {
- entry->lsn = 0;
- return;
- }
-
- // now try to read the next entry
- try {
- m_state.files[iter->fdidx].pread(iter->offset, entry, sizeof(*entry));
-
- iter->offset += sizeof(*entry);
-
- // read auxiliary data if it's available
- if (entry->followup_size) {
- auxbuffer->resize((uint32_t)entry->followup_size);
-
- m_state.files[iter->fdidx].pread(iter->offset, auxbuffer->get_ptr(),
- (size_t)entry->followup_size);
- iter->offset += entry->followup_size;
- }
- }
- catch (Exception &) {
- ham_trace(("failed to read journal entry, aborting recovery"));
- entry->lsn = 0; // this triggers the end of recovery
- }
-}
-
-void
-Journal::close(bool noclear)
-{
- int i;
-
- // the noclear flag is set during testing, for checking whether the files
- // contain the correct data. Flush the buffers, otherwise the tests will
- // fail because data is missing
- if (noclear) {
- flush_buffer(0);
- flush_buffer(1);
- }
-
- if (!noclear)
- clear();
-
- for (i = 0; i < 2; i++) {
- m_state.files[i].close();
- m_state.buffer[i].clear();
- }
-}
-
-Database *
-Journal::get_db(uint16_t dbname)
-{
- // first check if the Database is already open
- JournalState::DatabaseMap::iterator it = m_state.database_map.find(dbname);
- if (it != m_state.database_map.end())
- return (it->second);
-
- // not found - open it
- Database *db = 0;
- DatabaseConfiguration config;
- config.db_name = dbname;
- ham_status_t st = m_state.env->open_db(&db, config, 0);
- if (st)
- throw Exception(st);
- m_state.database_map[dbname] = db;
- return (db);
-}
-
-Transaction *
-Journal::get_txn(LocalTransactionManager *txn_manager, uint64_t txn_id)
-{
- Transaction *txn = txn_manager->get_oldest_txn();
- while (txn) {
- if (txn->get_id() == txn_id)
- return (txn);
- txn = txn->get_next();
- }
-
- return (0);
-}
-
-void
-Journal::close_all_databases()
-{
- ham_status_t st = 0;
-
- JournalState::DatabaseMap::iterator it = m_state.database_map.begin();
- while (it != m_state.database_map.end()) {
- JournalState::DatabaseMap::iterator it2 = it; it++;
- st = ham_db_close((ham_db_t *)it2->second, HAM_DONT_LOCK);
- if (st) {
- ham_log(("ham_db_close() failed w/ error %d (%s)", st, ham_strerror(st)));
- throw Exception(st);
- }
- }
- m_state.database_map.clear();
-}
-
-void
-Journal::abort_uncommitted_txns(LocalTransactionManager *txn_manager)
-{
- Transaction *txn = txn_manager->get_oldest_txn();
-
- while (txn) {
- if (!txn->is_committed())
- txn->abort();
- txn = txn->get_next();
- }
-}
-
-void
-Journal::recover(LocalTransactionManager *txn_manager)
-{
- Context context(m_state.env, 0, 0);
-
- // first re-apply the last changeset
- uint64_t start_lsn = recover_changeset();
-
- // load the state of the PageManager; the PageManager state is loaded AFTER
- // physical recovery because its page might have been restored in
- // recover_changeset()
- uint64_t page_manager_blobid = m_state.env->header()->get_page_manager_blobid();
- if (page_manager_blobid != 0) {
- m_state.env->page_manager()->initialize(page_manager_blobid);
- }
-
- // then start the normal recovery
- if (m_state.env->get_flags() & HAM_ENABLE_TRANSACTIONS)
- recover_journal(&context, txn_manager, start_lsn);
-}
-
-uint64_t
-Journal::scan_for_newest_changeset(File *file, uint64_t *position)
-{
- Iterator it;
- PJournalEntry entry;
- ByteArray buffer;
- uint64_t result = 0;
-
- // get the next entry
- try {
- uint64_t filesize = file->get_file_size();
-
- while (it.offset < filesize) {
- file->pread(it.offset, &entry, sizeof(entry));
-
- if (entry.lsn == 0)
- break;
-
- if (entry.type == kEntryTypeChangeset) {
- *position = it.offset;
- result = entry.lsn;
- }
-
- // increment the offset
- it.offset += sizeof(entry);
- if (entry.followup_size)
- it.offset += entry.followup_size;
- }
- }
- catch (Exception &ex) {
- ham_log(("exception (error %d) while reading journal", ex.code));
- }
-
- return (result);
-}
-
-uint64_t
-Journal::recover_changeset()
-{
- // scan through both files, look for the file with the newest changeset
- uint64_t position0, position1, position;
- uint64_t lsn1 = scan_for_newest_changeset(&m_state.files[0], &position0);
- uint64_t lsn2 = scan_for_newest_changeset(&m_state.files[1], &position1);
-
- // both files are empty or do not contain a changeset?
- if (lsn1 == 0 && lsn2 == 0)
- return (0);
-
- // re-apply the newest changeset
- m_state.current_fd = lsn1 > lsn2 ? 0 : 1;
- position = lsn1 > lsn2 ? position0 : position1;
-
- PJournalEntry entry;
- uint64_t start_lsn = 0;
-
- try {
- m_state.files[m_state.current_fd].pread(position, &entry, sizeof(entry));
- position += sizeof(entry);
- ham_assert(entry.type == kEntryTypeChangeset);
-
- // Read the Changeset header
- PJournalEntryChangeset changeset;
- m_state.files[m_state.current_fd].pread(position, &changeset,
- sizeof(changeset));
- position += sizeof(changeset);
-
- uint32_t page_size = m_state.env->config().page_size_bytes;
- ByteArray arena(page_size);
-
- uint64_t file_size = m_state.env->device()->file_size();
-
- // for each page in this changeset...
- for (uint32_t i = 0; i < changeset.num_pages; i++) {
- PJournalEntryPageHeader page_header;
- m_state.files[m_state.current_fd].pread(position, &page_header,
- sizeof(page_header));
- position += sizeof(page_header);
- m_state.files[m_state.current_fd].pread(position, arena.get_ptr(),
- page_size);
- position += page_size;
-
- Page *page;
-
- // now write the page to disk
- if (page_header.address == file_size) {
- file_size += page_size;
-
- page = new Page(m_state.env->device());
- page->alloc(0);
- }
- else if (page_header.address > file_size) {
- file_size = (size_t)page_header.address + page_size;
- m_state.env->device()->truncate(file_size);
-
- page = new Page(m_state.env->device());
- page->fetch(page_header.address);
- }
- else {
- page = new Page(m_state.env->device());
- page->fetch(page_header.address);
- }
-
- // only overwrite the page data if the page's last modification
- // is OLDER than the changeset!
- bool skip = false;
- if (page->is_without_header() == false) {
- if (page->get_lsn() > entry.lsn) {
- skip = true;
- start_lsn = page->get_lsn();
- }
- }
-
- if (!skip) {
- // overwrite the page data
- memcpy(page->get_data(), arena.get_ptr(), page_size);
-
- ham_assert(page->get_address() == page_header.address);
-
- // flush the modified page to disk
- page->set_dirty(true);
- page->flush();
- }
-
- delete page;
- }
- }
- catch (Exception &) {
- ham_trace(("Exception when applying changeset; skipping changeset"));
- // fall through
- }
-
- return (std::max(start_lsn, entry.lsn));
-}
-
-void
-Journal::recover_journal(Context *context,
- LocalTransactionManager *txn_manager, uint64_t start_lsn)
-{
- ham_status_t st = 0;
- Iterator it;
- ByteArray buffer;
-
- /* recovering the journal is rather simple - we iterate over the
- * files and re-apply EVERY operation (incl. txn_begin and txn_abort),
- * that was not yet flushed with a Changeset.
- *
- * Basically we iterate over both log files and skip everything with
- * a sequence number (lsn) smaller the one of the last Changeset.
- *
- * When done then auto-abort all transactions that were not yet
- * committed.
- */
-
- // make sure that there are no pending transactions - start with
- // a clean state!
- ham_assert(txn_manager->get_oldest_txn() == 0);
- ham_assert(m_state.env->get_flags() & HAM_ENABLE_TRANSACTIONS);
- ham_assert(m_state.env->get_flags() & HAM_ENABLE_RECOVERY);
-
- // do not append to the journal during recovery
- m_state.disable_logging = true;
-
- do {
- PJournalEntry entry;
-
- // get the next entry
- get_entry(&it, &entry, &buffer);
-
- // reached end of logfile?
- if (!entry.lsn)
- break;
-
- // re-apply this operation
- switch (entry.type) {
- case kEntryTypeTxnBegin: {
- Transaction *txn = 0;
- st = ham_txn_begin((ham_txn_t **)&txn, (ham_env_t *)m_state.env,
- (const char *)buffer.get_ptr(), 0, HAM_DONT_LOCK);
- // on success: patch the txn ID
- if (st == 0) {
- txn->set_id(entry.txn_id);
- txn_manager->set_txn_id(entry.txn_id);
- }
- break;
- }
- case kEntryTypeTxnAbort: {
- Transaction *txn = get_txn(txn_manager, entry.txn_id);
- st = ham_txn_abort((ham_txn_t *)txn, HAM_DONT_LOCK);
- break;
- }
- case kEntryTypeTxnCommit: {
- Transaction *txn = get_txn(txn_manager, entry.txn_id);
- st = ham_txn_commit((ham_txn_t *)txn, HAM_DONT_LOCK);
- break;
- }
- case kEntryTypeInsert: {
- PJournalEntryInsert *ins = (PJournalEntryInsert *)buffer.get_ptr();
- Transaction *txn = 0;
- Database *db;
- ham_key_t key = {0};
- ham_record_t record = {0};
- if (!ins) {
- st = HAM_IO_ERROR;
- goto bail;
- }
-
- // do not insert if the key was already flushed to disk
- if (entry.lsn <= start_lsn)
- continue;
-
- key.data = ins->get_key_data();
- key.size = ins->key_size;
- record.data = ins->get_record_data();
- record.size = ins->record_size;
- record.partial_size = ins->record_partial_size;
- record.partial_offset = ins->record_partial_offset;
- if (entry.txn_id)
- txn = get_txn(txn_manager, entry.txn_id);
- db = get_db(entry.dbname);
- st = ham_db_insert((ham_db_t *)db, (ham_txn_t *)txn,
- &key, &record, ins->insert_flags | HAM_DONT_LOCK);
- break;
- }
- case kEntryTypeErase: {
- PJournalEntryErase *e = (PJournalEntryErase *)buffer.get_ptr();
- Transaction *txn = 0;
- Database *db;
- ham_key_t key = {0};
- if (!e) {
- st = HAM_IO_ERROR;
- goto bail;
- }
-
- // do not erase if the key was already erased from disk
- if (entry.lsn <= start_lsn)
- continue;
-
- if (entry.txn_id)
- txn = get_txn(txn_manager, entry.txn_id);
- db = get_db(entry.dbname);
- key.data = e->get_key_data();
- key.size = e->key_size;
- st = ham_db_erase((ham_db_t *)db, (ham_txn_t *)txn, &key,
- e->erase_flags | HAM_DONT_LOCK);
- // key might have already been erased when the changeset
- // was flushed
- if (st == HAM_KEY_NOT_FOUND)
- st = 0;
- break;
- }
- case kEntryTypeChangeset: {
- // skip this; the changeset was already applied
- break;
- }
- default:
- ham_log(("invalid journal entry type or journal is corrupt"));
- st = HAM_IO_ERROR;
- }
-
- if (st)
- goto bail;
- } while (1);
-
-bail:
- // all transactions which are not yet committed will be aborted
- abort_uncommitted_txns(txn_manager);
-
- // also close and delete all open databases - they were created in get_db()
- close_all_databases();
-
- // flush all committed transactions
- if (st == 0)
- st = m_state.env->flush(HAM_FLUSH_COMMITTED_TRANSACTIONS);
-
- // re-enable the logging
- m_state.disable_logging = false;
-
- if (st)
- throw Exception(st);
-
- // clear the journal files
- clear();
-}
-
-void
-Journal::clear_file(int idx)
-{
- if (m_state.files[idx].is_open()) {
- m_state.files[idx].truncate(0);
-
- // after truncate, the file pointer is far beyond the new end of file;
- // reset the file pointer, or the next write will resize the file to
- // the original size
- m_state.files[idx].seek(0, File::kSeekSet);
- }
-
- // clear the transaction counters
- m_state.open_txn[idx] = 0;
- m_state.closed_txn[idx] = 0;
-
- // also clear the buffer with the outstanding data
- m_state.buffer[idx].clear();
-}
-
-std::string
-Journal::get_path(int i)
-{
- std::string path;
-
- if (m_state.env->config().log_filename.empty()) {
- path = m_state.env->config().filename;
- }
- else {
- path = m_state.env->config().log_filename;
-#ifdef HAM_OS_WIN32
- path += "\\";
- char fname[_MAX_FNAME];
- char ext[_MAX_EXT];
- _splitpath(m_state.env->config().filename.c_str(), 0, 0, fname, ext);
- path += fname;
- path += ext;
-#else
- path += "/";
- path += ::basename((char *)m_state.env->config().filename.c_str());
-#endif
- }
- if (i == 0)
- path += ".jrn0";
- else if (i == 1)
- path += ".jrn1";
- else
- ham_assert(!"invalid index");
- return (path);
-}
-
-JournalTest
-Journal::test()
-{
- return (JournalTest(&m_state));
-}
-
-JournalState::JournalState(LocalEnvironment *env)
- : env(env), current_fd(0), threshold(env->config().journal_switch_threshold),
- disable_logging(false), count_bytes_flushed(0),
- count_bytes_before_compression(0), count_bytes_after_compression(0)
-{
- if (threshold == 0)
- threshold = kSwitchTxnThreshold;
-
- open_txn[0] = 0;
- open_txn[1] = 0;
- closed_txn[0] = 0;
- closed_txn[1] = 0;
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal.h b/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal.h
deleted file mode 100644
index dd55b66fea..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Routines for the journal - writing, reading, recovering
- *
- * The journal is a facility for storing logical and physical redo-information.
- *
- * The logical information describes the database operation (i.e. insert/erase),
- * the physical information describes the modified pages.
- *
- * "Undo" information is not required because aborted Transactions are never
- * written to disk. The journal only can "redo" operations.
- *
- * The journal is organized in two files. If one of the files grows too large
- * then all new Transactions are stored in the other file
- * ("Log file switching"). When all Transactions from file #0 are committed,
- * and file #1 exceeds a limit, then the files are switched back again.
- *
- * For writing, files are buffered. The buffers are flushed when they
- * exceed a certain threshold, when a Transaction is committed or a Changeset
- * was written. In case of a commit or a changeset there will also be an
- * fsync, if HAM_ENABLE_FSYNC is enabled.
- *
- * The physical information is a collection of pages which are modified in
- * one or more database operations (i.e. ham_db_erase). This collection is
- * called a "changeset" and implemented in changeset.h/.cc. As soon as the
- * operation is finished, the changeset is flushed: if the changeset contains
- * just a single page, then this operation is atomic and is NOT logged.
- * Otherwise the whole changeset is appended to the journal, and afterwards
- * the database file is modified.
- *
- * For recovery to work, each page stores the lsn of its last modification.
- *
- * When recovering, the Journal first extracts the newest/latest entry.
- * If this entry is a changeset then the changeset is reapplied, because
- * we assume that there was a crash immediately AFTER the changeset was
- * written, but BEFORE the database file was modified. (The changeset is
- * idempotent; if the database file was successfully modified then the
- * changes are re-applied; this is not a problem.)
- *
- * Afterwards, hamsterdb uses the lsn's to figure out whether an update
- * was already applied or not. If the journal's last entry is a changeset then
- * this changeset's lsn marks the beginning of the sequence. Otherwise the lsn
- * is fetched from the journal file headers. All journal entries with an lsn
- * *older* than this start-lsn will be skipped, all others are re-applied.
- *
- * In this phase all changesets are skipped because the newest changeset was
- * already applied, and we know that all older changesets
- * have already been written successfully to the database file.
- *
- * @exception_safe: basic
- * @thread_safe: no
- */
-
-#ifndef HAM_JOURNAL_H
-#define HAM_JOURNAL_H
-
-#include "0root/root.h"
-
-#include <map>
-#include <cstdio>
-#include <string>
-
-#include "ham/hamsterdb_int.h" // for metrics
-
-#include "1base/dynamic_array.h"
-#include "1os/file.h"
-#include "1errorinducer/errorinducer.h"
-#include "2page/page_collection.h"
-#include "3journal/journal_entries.h"
-#include "3journal/journal_state.h"
-#include "3journal/journal_test.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-class Page;
-class Database;
-class Transaction;
-class LocalEnvironment;
-class LocalTransaction;
-class LocalTransactionManager;
-
-#include "1base/packstart.h"
-
-//
-// The Journal object
-//
-class Journal
-{
- public:
- enum {
- // marks the start of a new transaction
- kEntryTypeTxnBegin = 1,
-
- // marks the end of an aborted transaction
- kEntryTypeTxnAbort = 2,
-
- // marks the end of an committed transaction
- kEntryTypeTxnCommit = 3,
-
- // marks an insert operation
- kEntryTypeInsert = 4,
-
- // marks an erase operation
- kEntryTypeErase = 5,
-
- // marks a whole changeset operation (writes modified pages)
- kEntryTypeChangeset = 6
- };
-
- //
- // An "iterator" structure for traversing the journal files
- //
- struct Iterator {
- Iterator()
- : fdidx(0), fdstart(0), offset(0) {
- }
-
- // selects the file descriptor [0..1]
- int fdidx;
-
- // which file descriptor did we start with? [0..1]
- int fdstart;
-
- // the offset in the file of the NEXT entry
- uint64_t offset;
- };
-
- // Constructor
- Journal(LocalEnvironment *env);
-
- // Creates a new journal
- void create();
-
- // Opens an existing journal
- void open();
-
- // Returns true if the journal is empty
- bool is_empty() {
- if (!m_state.files[0].is_open() && !m_state.files[1].is_open())
- return (true);
-
- for (int i = 0; i < 2; i++) {
- uint64_t size = m_state.files[i].get_file_size();
- if (size > 0)
- return (false);
- }
-
- return (true);
- }
-
- // Appends a journal entry for ham_txn_begin/kEntryTypeTxnBegin
- void append_txn_begin(LocalTransaction *txn, const char *name,
- uint64_t lsn);
-
- // Appends a journal entry for ham_txn_abort/kEntryTypeTxnAbort
- void append_txn_abort(LocalTransaction *txn, uint64_t lsn);
-
- // Appends a journal entry for ham_txn_commit/kEntryTypeTxnCommit
- void append_txn_commit(LocalTransaction *txn, uint64_t lsn);
-
- // Appends a journal entry for ham_insert/kEntryTypeInsert
- void append_insert(Database *db, LocalTransaction *txn,
- ham_key_t *key, ham_record_t *record, uint32_t flags,
- uint64_t lsn);
-
- // Appends a journal entry for ham_erase/kEntryTypeErase
- void append_erase(Database *db, LocalTransaction *txn,
- ham_key_t *key, int duplicate_index, uint32_t flags,
- uint64_t lsn);
-
- // Appends a journal entry for a whole changeset/kEntryTypeChangeset
- void append_changeset(const Page **pages, int num_pages, uint64_t lsn);
-
- // Adjusts the transaction counters; called whenever |txn| is flushed.
- void transaction_flushed(LocalTransaction *txn);
-
- // Empties the journal, removes all entries
- void clear() {
- for (int i = 0; i < 2; i++)
- clear_file(i);
- }
-
- // Closes the journal, frees all allocated resources
- void close(bool noclear = false);
-
- // Performs the recovery! All committed Transactions will be re-applied,
- // all others are automatically aborted
- void recover(LocalTransactionManager *txn_manager);
-
- // Fills the metrics
- void fill_metrics(ham_env_metrics_t *metrics) {
- metrics->journal_bytes_flushed = m_state.count_bytes_flushed;
- }
-
- private:
- friend struct JournalFixture;
-
- // Returns a pointer to database. If the database was not yet opened then
- // it is opened implicitly.
- Database *get_db(uint16_t dbname);
-
- // Returns a pointer to a Transaction object.
- Transaction *get_txn(LocalTransactionManager *txn_manager, uint64_t txn_id);
-
- // Closes all databases.
- void close_all_databases();
-
- // Aborts all transactions which are still active.
- void abort_uncommitted_txns(LocalTransactionManager *txn_manager);
-
- // Helper function which adds a single page from the changeset to
- // the Journal; returns the page size (or compressed size, if compression
- // was enabled)
- uint32_t append_changeset_page(const Page *page, uint32_t page_size);
-
- // Recovers (re-applies) the physical changelog; returns the lsn of the
- // Changelog
- uint64_t recover_changeset();
-
- // Scans a file for the newest changeset. Returns the lsn of this
- // changeset, and the position (offset) in the file
- uint64_t scan_for_newest_changeset(File *file, uint64_t *position);
-
- // Recovers the logical journal
- void recover_journal(Context *context,
- LocalTransactionManager *txn_manager, uint64_t start_lsn);
-
- // Switches the log file if necessary; returns the new log descriptor in the
- // transaction
- int switch_files_maybe();
-
- // returns the path of the journal file
- std::string get_path(int i);
-
- // Sequentially returns the next journal entry, starting with
- // the oldest entry.
- //
- // |iter| must be initialized with zeroes for the first call.
- // |auxbuffer| returns the auxiliary data of the entry and is either
- // a structure of type PJournalEntryInsert or PJournalEntryErase.
- //
- // Returns an empty entry (lsn is zero) after the last element.
- void get_entry(Iterator *iter, PJournalEntry *entry,
- ByteArray *auxbuffer);
-
- // Appends an entry to the journal
- void append_entry(int idx,
- const uint8_t *ptr1 = 0, size_t ptr1_size = 0,
- const uint8_t *ptr2 = 0, size_t ptr2_size = 0,
- const uint8_t *ptr3 = 0, size_t ptr3_size = 0,
- const uint8_t *ptr4 = 0, size_t ptr4_size = 0,
- const uint8_t *ptr5 = 0, size_t ptr5_size = 0) {
- if (ptr1_size)
- m_state.buffer[idx].append(ptr1, ptr1_size);
- if (ptr2_size)
- m_state.buffer[idx].append(ptr2, ptr2_size);
- if (ptr3_size)
- m_state.buffer[idx].append(ptr3, ptr3_size);
- if (ptr4_size)
- m_state.buffer[idx].append(ptr4, ptr4_size);
- if (ptr5_size)
- m_state.buffer[idx].append(ptr5, ptr5_size);
- }
-
- // flush buffer if size limit is exceeded
- void maybe_flush_buffer(int idx) {
- if (m_state.buffer[idx].get_size() >= JournalState::kBufferLimit)
- flush_buffer(idx);
- }
-
- // Flushes a buffer to disk
- void flush_buffer(int idx, bool fsync = false) {
- if (m_state.buffer[idx].get_size() > 0) {
- // error inducer? then write only a part of the buffer and return
- if (ErrorInducer::is_active()
- && ErrorInducer::get_instance()->induce(ErrorInducer::kChangesetFlush)) {
- m_state.files[idx].write(m_state.buffer[idx].get_ptr(),
- m_state.buffer[idx].get_size() - 5);
- throw Exception(HAM_INTERNAL_ERROR);
- }
-
- m_state.files[idx].write(m_state.buffer[idx].get_ptr(),
- m_state.buffer[idx].get_size());
- m_state.count_bytes_flushed += m_state.buffer[idx].get_size();
-
- m_state.buffer[idx].clear();
- if (fsync)
- m_state.files[idx].flush();
- }
- }
-
- // Clears a single file
- void clear_file(int idx);
-
- // Returns the test object
- JournalTest test();
-
- private:
- // The mutable state
- JournalState m_state;
-};
-
-#include "1base/packstop.h"
-
-} // namespace hamsterdb
-
-#endif /* HAM_JOURNAL_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_entries.h b/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_entries.h
deleted file mode 100644
index b32f53693b..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_entries.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * journal entries for insert, erase, begin, commit, abort...
- *
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_JOURNAL_ENTRIES_H
-#define HAM_JOURNAL_ENTRIES_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-#include "1base/packstart.h"
-
-/*
- * A journal entry for all txn related operations (begin, commit, abort)
- *
- * This structure can be followed by one of the structures below
- * (PJournalEntryInsert or PJournalEntryERASE); the field |followup_size|
- * is the structure size of this follow-up structure.
- */
-HAM_PACK_0 struct HAM_PACK_1 PJournalEntry {
- // Constructor - sets all fields to 0
- PJournalEntry()
- : lsn(0), followup_size(0), txn_id(0), type(0),
- dbname(0), _reserved(0) {
- }
-
- // the lsn of this entry
- uint64_t lsn;
-
- // the size of the follow-up entry in bytes (may be padded)
- uint64_t followup_size;
-
- // the transaction id
- uint64_t txn_id;
-
- // the type of this entry
- uint32_t type;
-
- // the name of the database which is modified by this entry
- uint16_t dbname;
-
- // a reserved value - reqd for padding
- uint16_t _reserved;
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-
-#include "1base/packstart.h"
-
-//
-// a Journal entry for an 'insert' operation
-//
-HAM_PACK_0 struct HAM_PACK_1 PJournalEntryInsert {
- // Constructor - sets all fields to 0
- PJournalEntryInsert()
- : key_size(0), compressed_key_size(0), record_size(0),
- compressed_record_size(0), record_partial_size(0),
- record_partial_offset(0), insert_flags(0) {
- data[0] = 0;
- }
-
- // key size
- uint16_t key_size;
-
- // PRO: compressed key size
- uint16_t compressed_key_size;
-
- // record size
- uint32_t record_size;
-
- // PRO: compressed record size
- uint32_t compressed_record_size;
-
- // record partial size
- uint32_t record_partial_size;
-
- // record partial offset
- uint32_t record_partial_offset;
-
- // flags of ham_insert(), ham_cursor_insert()
- uint32_t insert_flags;
-
- // data follows here - first |key_size| bytes for the key, then
- // |record_size| bytes for the record (and maybe some padding)
- //
- // PRO: this data can be compressed
- uint8_t data[1];
-
- // Returns a pointer to the key data
- uint8_t *get_key_data() {
- return (&data[0]);
- }
-
- // Returns a pointer to the record data
- uint8_t *get_record_data() {
- return (&data[key_size]);
- }
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-
-#include "1base/packstart.h"
-
-//
-// a Journal entry for 'erase' operations
-//
-HAM_PACK_0 struct HAM_PACK_1 PJournalEntryErase {
- // Constructor - sets all fields to 0
- PJournalEntryErase()
- : key_size(0), compressed_key_size(0), erase_flags(0), duplicate(0) {
- data[0] = 0;
- }
-
- // key size
- uint16_t key_size;
-
- // PRO: compressed key size
- uint16_t compressed_key_size;
-
- // flags of ham_erase(), ham_cursor_erase()
- uint32_t erase_flags;
-
- // which duplicate to erase
- int duplicate;
-
- // the key data
- //
- // PRO: this data can be compressed
- uint8_t data[1];
-
- // Returns a pointer to the key data
- uint8_t *get_key_data() {
- return (&data[0]);
- }
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-
-#include "1base/packstart.h"
-
-//
-// a Journal entry for a 'changeset' group
-//
-HAM_PACK_0 struct HAM_PACK_1 PJournalEntryChangeset {
- // Constructor - sets all fields to 0
- PJournalEntryChangeset()
- : num_pages(0) {
- }
-
- // number of pages in this changeset
- uint32_t num_pages;
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-
-#include "1base/packstart.h"
-
-//
-// a Journal entry for a single page
-//
-HAM_PACK_0 struct HAM_PACK_1 PJournalEntryPageHeader {
- // Constructor - sets all fields to 0
- PJournalEntryPageHeader(uint64_t _address = 0)
- : address(_address), compressed_size(0) {
- }
-
- // the page address
- uint64_t address;
-
- // PRO: the compressed size, if compression is enabled
- uint32_t compressed_size;
-} HAM_PACK_2;
-
-#include "1base/packstop.h"
-
-} // namespace hamsterdb
-
-#endif /* HAM_JOURNAL_ENTRIES_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_state.h b/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_state.h
deleted file mode 100644
index 817fcac1d5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_state.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The Journal's state
- *
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_JOURNAL_STATE_H
-#define HAM_JOURNAL_STATE_H
-
-#include "0root/root.h"
-
-#include <map>
-#include <string>
-
-#include "ham/hamsterdb_int.h" // for metrics
-
-#include "1base/dynamic_array.h"
-#include "1os/file.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Database;
-class LocalEnvironment;
-
-struct JournalState
-{
- enum {
- // switch log file after |kSwitchTxnThreshold| transactions
- kSwitchTxnThreshold = 32,
-
- // flush buffers if this limit is exceeded
- kBufferLimit = 1024 * 1024 // 1 mb
- };
-
- JournalState(LocalEnvironment *env);
-
- // References the Environment this journal file is for
- LocalEnvironment *env;
-
- // The index of the file descriptor we are currently writing to (0 or 1)
- uint32_t current_fd;
-
- // The two file descriptors
- File files[2];
-
- // Buffers for writing data to the files
- ByteArray buffer[2];
-
- // For counting all open transactions in the files
- size_t open_txn[2];
-
- // For counting all closed transactions in the files
- size_t closed_txn[2];
-
- // The lsn of the previous checkpoint
- uint64_t last_cp_lsn;
-
- // When having more than these Transactions in one file, we
- // swap the files
- size_t threshold;
-
- // Set to false to disable logging; used during recovery
- bool disable_logging;
-
- // Counting the flushed bytes (for ham_env_get_metrics)
- uint64_t count_bytes_flushed;
-
- // Counting the bytes before compression (for ham_env_get_metrics)
- uint64_t count_bytes_before_compression;
-
- // Counting the bytes after compression (for ham_env_get_metrics)
- uint64_t count_bytes_after_compression;
-
- // A map of all opened Databases
- typedef std::map<uint16_t, Database *> DatabaseMap;
- DatabaseMap database_map;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_JOURNAL_STATE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_test.h b/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_test.h
deleted file mode 100644
index 464d8fa43c..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3journal/journal_test.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * Test gateway for the Journal
- *
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_JOURNAL_TEST_H
-#define HAM_JOURNAL_TEST_H
-
-#include "0root/root.h"
-
-#include "ham/hamsterdb_int.h" // for metrics
-
-#include "3journal/journal_state.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class JournalTest
-{
- public:
- JournalTest(JournalState *state)
- : m_state(state) {
- }
-
- // Returns the state
- JournalState *state() { return (m_state); }
-
- private:
- // The journal's state
- JournalState *m_state;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_JOURNAL_TEST_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager.cc b/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager.cc
deleted file mode 100644
index bec3cc32e0..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager.cc
+++ /dev/null
@@ -1,798 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/dynamic_array.h"
-#include "1base/pickle.h"
-#include "2page/page.h"
-#include "2device/device.h"
-#include "2queue/queue.h"
-#include "3page_manager/page_manager.h"
-#include "3page_manager/page_manager_worker.h"
-#include "3page_manager/page_manager_test.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_node_proxy.h"
-#include "4context/context.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-enum {
- kPurgeAtLeast = 20
-};
-
-PageManagerState::PageManagerState(LocalEnvironment *env)
- : config(env->config()), header(env->header()),
- device(env->device()), lsn_manager(env->lsn_manager()),
- cache(env->config()), needs_flush(false), purge_cache_pending(false),
- state_page(0), last_blob_page(0), last_blob_page_id(0),
- page_count_fetched(0), page_count_index(0), page_count_blob(0),
- page_count_page_manager(0), cache_hits(0), cache_misses(0),
- freelist_hits(0), freelist_misses(0)
-{
-}
-
-PageManager::PageManager(LocalEnvironment *env)
- : m_state(env)
-{
- /* start the worker thread */
- m_worker.reset(new PageManagerWorker(&m_state.cache));
-}
-
-void
-PageManager::initialize(uint64_t pageid)
-{
- Context context(0, 0, 0);
-
- m_state.free_pages.clear();
- if (m_state.state_page)
- delete m_state.state_page;
- m_state.state_page = new Page(m_state.device);
- m_state.state_page->fetch(pageid);
-
- Page *page = m_state.state_page;
- uint32_t page_size = m_state.config.page_size_bytes;
-
- // the first page stores the page ID of the last blob
- m_state.last_blob_page_id = *(uint64_t *)page->get_payload();
-
- while (1) {
- ham_assert(page->get_type() == Page::kTypePageManager);
- uint8_t *p = page->get_payload();
- // skip m_state.last_blob_page_id?
- if (page == m_state.state_page)
- p += sizeof(uint64_t);
-
- // get the overflow address
- uint64_t overflow = *(uint64_t *)p;
- p += 8;
-
- // get the number of stored elements
- uint32_t counter = *(uint32_t *)p;
- p += 4;
-
- // now read all pages
- for (uint32_t i = 0; i < counter; i++) {
- // 4 bits page_counter, 4 bits for number of following bytes
- int page_counter = (*p & 0xf0) >> 4;
- int num_bytes = *p & 0x0f;
- ham_assert(page_counter > 0);
- ham_assert(num_bytes <= 8);
- p += 1;
-
- uint64_t id = Pickle::decode_u64(num_bytes, p);
- p += num_bytes;
-
- m_state.free_pages[id * page_size] = page_counter;
- }
-
- // load the overflow page
- if (overflow)
- page = fetch(&context, overflow, 0);
- else
- break;
- }
-}
-
-Page *
-PageManager::fetch(Context *context, uint64_t address, uint32_t flags)
-{
- /* fetch the page from the cache */
- Page *page;
-
- if (address == 0)
- page = m_state.header->get_header_page();
- else
- page = m_state.cache.get(address);
-
- if (page) {
- if (flags & PageManager::kNoHeader)
- page->set_without_header(true);
- return (safely_lock_page(context, page, true));
- }
-
- if ((flags & PageManager::kOnlyFromCache)
- || m_state.config.flags & HAM_IN_MEMORY)
- return (0);
-
- page = new Page(m_state.device, context->db);
- try {
- page->fetch(address);
- }
- catch (Exception &ex) {
- delete page;
- throw ex;
- }
-
- ham_assert(page->get_data());
-
- /* store the page in the list */
- m_state.cache.put(page);
-
- /* write to disk (if necessary) */
- if (!(flags & PageManager::kDisableStoreState)
- && !(flags & PageManager::kReadOnly))
- maybe_store_state(context, false);
-
- if (flags & PageManager::kNoHeader)
- page->set_without_header(true);
-
- m_state.page_count_fetched++;
- return (safely_lock_page(context, page, false));
-}
-
-Page *
-PageManager::alloc(Context *context, uint32_t page_type, uint32_t flags)
-{
- uint64_t address = 0;
- Page *page = 0;
- uint32_t page_size = m_state.config.page_size_bytes;
- bool allocated = false;
-
- /* first check the internal list for a free page */
- if ((flags & PageManager::kIgnoreFreelist) == 0
- && !m_state.free_pages.empty()) {
- PageManagerState::FreeMap::iterator it = m_state.free_pages.begin();
-
- address = it->first;
- ham_assert(address % page_size == 0);
- /* remove the page from the freelist */
- m_state.free_pages.erase(it);
- m_state.needs_flush = true;
-
- m_state.freelist_hits++;
-
- /* try to fetch the page from the cache */
- page = m_state.cache.get(address);
- if (page)
- goto done;
- /* allocate a new page structure and read the page from disk */
- page = new Page(m_state.device, context->db);
- page->fetch(address);
- goto done;
- }
-
- m_state.freelist_misses++;
-
- try {
- if (!page) {
- allocated = true;
- page = new Page(m_state.device, context->db);
- }
-
- page->alloc(page_type);
- }
- catch (Exception &ex) {
- if (allocated)
- delete page;
- throw ex;
- }
-
-done:
- /* clear the page with zeroes? */
- if (flags & PageManager::kClearWithZero)
- memset(page->get_data(), 0, page_size);
-
- /* initialize the page; also set the 'dirty' flag to force logging */
- page->set_type(page_type);
- page->set_dirty(true);
- page->set_db(context->db);
-
- if (page->get_node_proxy()) {
- delete page->get_node_proxy();
- page->set_node_proxy(0);
- }
-
- /* store the page in the cache and the Changeset */
- m_state.cache.put(page);
- safely_lock_page(context, page, false);
-
- /* write to disk (if necessary) */
- if (!(flags & PageManager::kDisableStoreState)
- && !(flags & PageManager::kReadOnly))
- maybe_store_state(context, false);
-
- switch (page_type) {
- case Page::kTypeBindex:
- case Page::kTypeBroot: {
- memset(page->get_payload(), 0, sizeof(PBtreeNode));
- m_state.page_count_index++;
- break;
- }
- case Page::kTypePageManager:
- m_state.page_count_page_manager++;
- break;
- case Page::kTypeBlob:
- m_state.page_count_blob++;
- break;
- default:
- break;
- }
-
- return (page);
-}
-
-Page *
-PageManager::alloc_multiple_blob_pages(Context *context, size_t num_pages)
-{
- // allocate only one page? then use the normal ::alloc() method
- if (num_pages == 1)
- return (alloc(context, Page::kTypeBlob, 0));
-
- Page *page = 0;
- uint32_t page_size = m_state.config.page_size_bytes;
-
- // Now check the freelist
- if (!m_state.free_pages.empty()) {
- for (PageManagerState::FreeMap::iterator it = m_state.free_pages.begin();
- it != m_state.free_pages.end();
- it++) {
- if (it->second >= num_pages) {
- for (size_t i = 0; i < num_pages; i++) {
- if (i == 0) {
- page = fetch(context, it->first, 0);
- page->set_type(Page::kTypeBlob);
- page->set_without_header(false);
- }
- else {
- Page *p = fetch(context, it->first + (i * page_size), 0);
- p->set_type(Page::kTypeBlob);
- p->set_without_header(true);
- }
- }
- if (it->second > num_pages) {
- m_state.free_pages[it->first + num_pages * page_size]
- = it->second - num_pages;
- }
- m_state.free_pages.erase(it);
- return (page);
- }
- }
- }
-
- // Freelist lookup was not successful -> allocate new pages. Only the first
- // page is a regular page; all others do not have page headers.
- //
- // disable "store state": the PageManager otherwise could alloc overflow
- // pages in the middle of our blob sequence.
- uint32_t flags = PageManager::kIgnoreFreelist
- | PageManager::kDisableStoreState;
- for (size_t i = 0; i < num_pages; i++) {
- if (page == 0)
- page = alloc(context, Page::kTypeBlob, flags);
- else {
- Page *p = alloc(context, Page::kTypeBlob, flags);
- p->set_without_header(true);
- }
- }
-
- // now store the state
- maybe_store_state(context, false);
- return (page);
-}
-
-void
-PageManager::fill_metrics(ham_env_metrics_t *metrics) const
-{
- metrics->page_count_fetched = m_state.page_count_fetched;
- metrics->page_count_flushed = Page::ms_page_count_flushed;
- metrics->page_count_type_index = m_state.page_count_index;
- metrics->page_count_type_blob = m_state.page_count_blob;
- metrics->page_count_type_page_manager = m_state.page_count_page_manager;
- metrics->freelist_hits = m_state.freelist_hits;
- metrics->freelist_misses = m_state.freelist_misses;
- m_state.cache.fill_metrics(metrics);
-}
-
-struct FlushAllPagesPurger
-{
- FlushAllPagesPurger(bool delete_pages)
- : delete_pages(delete_pages) {
- }
-
- bool operator()(Page *page) {
- ScopedSpinlock lock(page->mutex());
- page->flush();
- return (delete_pages);
- }
-
- bool delete_pages;
-};
-
-void
-PageManager::flush(bool delete_pages)
-{
- FlushAllPagesPurger purger(delete_pages);
- m_state.cache.purge_if(purger);
-
- if (m_state.state_page) {
- ScopedSpinlock lock(m_state.state_page->mutex());
- m_state.state_page->flush();
- }
-}
-
-// Returns true if the page can be purged: page must use allocated
-// memory instead of an mmapped pointer; page must not be in use (= in
-// a changeset) and not have cursors attached
-struct PurgeProcessor
-{
- PurgeProcessor(Page *last_blob_page, FlushPageMessage *message)
- : last_blob_page(last_blob_page), message(message) {
- }
-
- bool operator()(Page *page) {
- // the lock in here will be unlocked by the worker thread
- if (page == last_blob_page || !page->mutex().try_lock())
- return (false);
- message->list.push_back(page);
- return (true);
- }
-
- Page *last_blob_page;
- FlushPageMessage *message;
-};
-
-void
-PageManager::purge_cache(Context *context)
-{
- // do NOT purge the cache iff
- // 1. this is an in-memory Environment
- // 2. there's still a "purge cache" operation pending
- // 3. the cache is not full
- if (m_state.config.flags & HAM_IN_MEMORY
- || m_state.purge_cache_pending
- || !m_state.cache.is_cache_full())
- return;
-
- // Purge as many pages as possible to get memory usage down to the
- // cache's limit.
- FlushPageMessage *message = new FlushPageMessage();
- PurgeProcessor processor(m_state.last_blob_page, message);
- m_state.cache.purge(processor, m_state.last_blob_page);
-
- if (message->list.size())
- m_worker->add_to_queue(message);
- else
- delete message;
-}
-
-void
-PageManager::reclaim_space(Context *context)
-{
- if (m_state.last_blob_page) {
- m_state.last_blob_page_id = m_state.last_blob_page->get_address();
- m_state.last_blob_page = 0;
- }
- ham_assert(!(m_state.config.flags & HAM_DISABLE_RECLAIM_INTERNAL));
-
- bool do_truncate = false;
- size_t file_size = m_state.device->file_size();
- uint32_t page_size = m_state.config.page_size_bytes;
-
- while (m_state.free_pages.size() > 1) {
- PageManagerState::FreeMap::iterator fit =
- m_state.free_pages.find(file_size - page_size);
- if (fit != m_state.free_pages.end()) {
- Page *page = m_state.cache.get(fit->first);
- if (page) {
- m_state.cache.del(page);
- delete page;
- }
- file_size -= page_size;
- do_truncate = true;
- m_state.free_pages.erase(fit);
- continue;
- }
- break;
- }
-
- if (do_truncate) {
- m_state.needs_flush = true;
- maybe_store_state(context, true);
- m_state.device->truncate(file_size);
- }
-}
-
-struct DbClosePurger
-{
- DbClosePurger(LocalDatabase *db)
- : m_db(db) {
- }
-
- bool operator()(Page *page) {
- if (page->get_db() == m_db && page->get_address() != 0) {
- ScopedSpinlock lock(page->mutex());
- ham_assert(page->cursor_list() == 0);
- page->flush();
- return (true);
- }
- return (false);
- }
-
- LocalDatabase *m_db;
-};
-
-void
-PageManager::close_database(Context *context, LocalDatabase *db)
-{
- if (m_state.last_blob_page) {
- m_state.last_blob_page_id = m_state.last_blob_page->get_address();
- m_state.last_blob_page = 0;
- }
-
- context->changeset.clear();
-
- DbClosePurger purger(db);
- m_state.cache.purge_if(purger);
-}
-
-void
-PageManager::del(Context *context, Page *page, size_t page_count)
-{
- ham_assert(page_count > 0);
-
- if (m_state.config.flags & HAM_IN_MEMORY)
- return;
-
- // remove all pages from the changeset, otherwise they won't be unlocked
- context->changeset.del(page);
- if (page_count > 1) {
- uint32_t page_size = m_state.config.page_size_bytes;
- for (size_t i = 1; i < page_count; i++) {
- Page *p = m_state.cache.get(page->get_address() + i * page_size);
- if (p && context->changeset.has(p))
- context->changeset.del(p);
- }
- }
-
- m_state.needs_flush = true;
- m_state.free_pages[page->get_address()] = page_count;
- ham_assert(page->get_address() % m_state.config.page_size_bytes == 0);
-
- if (page->get_node_proxy()) {
- delete page->get_node_proxy();
- page->set_node_proxy(0);
- }
-
- // do not call maybe_store_state() - this change in the m_state is not
- // relevant for logging.
-}
-
-void
-PageManager::reset(Context *context)
-{
- close(context);
-
- /* start the worker thread */
- m_worker.reset(new PageManagerWorker(&m_state.cache));
-}
-
-void
-PageManager::close(Context *context)
-{
- /* wait for the worker thread to stop */
- if (m_worker.get())
- m_worker->stop_and_join();
-
- // store the state of the PageManager
- if ((m_state.config.flags & HAM_IN_MEMORY) == 0
- && (m_state.config.flags & HAM_READ_ONLY) == 0) {
- maybe_store_state(context, true);
- }
-
- // reclaim unused disk space
- // if logging is enabled: also flush the changeset to write back the
- // modified freelist pages
- bool try_reclaim = m_state.config.flags & HAM_DISABLE_RECLAIM_INTERNAL
- ? false
- : true;
-
-#ifdef WIN32
- // Win32: it's not possible to truncate the file while there's an active
- // mapping, therefore only reclaim if memory mapped I/O is disabled
- if (!(m_state.config.flags & HAM_DISABLE_MMAP))
- try_reclaim = false;
-#endif
-
- if (try_reclaim) {
- reclaim_space(context);
- }
-
- // clear the Changeset because flush() will delete all Page pointers
- context->changeset.clear();
-
- // flush all dirty pages to disk, then delete them
- flush(true);
-
- delete m_state.state_page;
- m_state.state_page = 0;
- m_state.last_blob_page = 0;
-}
-
-Page *
-PageManager::get_last_blob_page(Context *context)
-{
- if (m_state.last_blob_page)
- return (safely_lock_page(context, m_state.last_blob_page, true));
- if (m_state.last_blob_page_id)
- return (fetch(context, m_state.last_blob_page_id, 0));
- return (0);
-}
-
-void
-PageManager::set_last_blob_page(Page *page)
-{
- m_state.last_blob_page_id = 0;
- m_state.last_blob_page = page;
-}
-
-uint64_t
-PageManager::store_state(Context *context)
-{
- // no modifications? then simply return the old blobid
- if (!m_state.needs_flush)
- return (m_state.state_page ? m_state.state_page->get_address() : 0);
-
- m_state.needs_flush = false;
-
- // no freelist pages, no freelist state? then don't store anything
- if (!m_state.state_page && m_state.free_pages.empty())
- return (0);
-
- // otherwise allocate a new page, if required
- if (!m_state.state_page) {
- m_state.state_page = new Page(m_state.device);
- m_state.state_page->alloc(Page::kTypePageManager,
- Page::kInitializeWithZeroes);
- }
-
- // don't bother locking the state page
- context->changeset.put(m_state.state_page);
-
- uint32_t page_size = m_state.config.page_size_bytes;
-
- // make sure that the page is logged
- Page *page = m_state.state_page;
- page->set_dirty(true);
-
- uint8_t *p = page->get_payload();
-
- // store page-ID of the last allocated blob
- *(uint64_t *)p = m_state.last_blob_page_id;
- p += sizeof(uint64_t);
-
- // reset the overflow pointer and the counter
- // TODO here we lose a whole chain of overflow pointers if there was such
- // a chain. We only save the first. That's not critical but also not nice.
- uint64_t next_pageid = *(uint64_t *)p;
- if (next_pageid) {
- m_state.free_pages[next_pageid] = 1;
- ham_assert(next_pageid % page_size == 0);
- }
-
- // No freelist entries? then we're done. Make sure that there's no
- // overflow pointer or other garbage in the page!
- if (m_state.free_pages.empty()) {
- *(uint64_t *)p = 0;
- p += sizeof(uint64_t);
- *(uint32_t *)p = 0;
- return (m_state.state_page->get_address());
- }
-
- PageManagerState::FreeMap::const_iterator it = m_state.free_pages.begin();
- while (it != m_state.free_pages.end()) {
- // this is where we will store the data
- p = page->get_payload();
- // skip m_state.last_blob_page_id?
- if (page == m_state.state_page)
- p += sizeof(uint64_t);
- p += 8; // leave room for the pointer to the next page
- p += 4; // leave room for the counter
-
- uint32_t counter = 0;
-
- while (it != m_state.free_pages.end()) {
- // 9 bytes is the maximum amount of storage that we will need for a
- // new entry; if it does not fit then break
- if ((p + 9) - page->get_payload()
- >= (ptrdiff_t)(m_state.config.page_size_bytes
- - Page::kSizeofPersistentHeader))
- break;
-
- // ... and check if the next entry (and the following) are directly
- // next to the current page
- uint32_t page_counter = 1;
- uint64_t base = it->first;
- ham_assert(base % page_size == 0);
- uint64_t current = it->first;
-
- // move to the next entry
- it++;
-
- for (; it != m_state.free_pages.end() && page_counter < 16 - 1; it++) {
- if (it->first != current + page_size)
- break;
- current += page_size;
- page_counter++;
- }
-
- // now |base| is the start of a sequence of free pages, and the
- // sequence has |page_counter| pages
- //
- // This is encoded as
- // - 1 byte header
- // - 4 bits for |page_counter|
- // - 4 bits for the number of bytes following ("n")
- // - n byte page-id (div page_size)
- ham_assert(page_counter < 16);
- int num_bytes = Pickle::encode_u64(p + 1, base / page_size);
- *p = (page_counter << 4) | num_bytes;
- p += 1 + num_bytes;
-
- counter++;
- }
-
- p = page->get_payload();
- if (page == m_state.state_page) // skip m_state.last_blob_page_id?
- p += sizeof(uint64_t);
- uint64_t next_pageid = *(uint64_t *)p;
- *(uint64_t *)p = 0;
- p += 8; // overflow page
-
- // now store the counter
- *(uint32_t *)p = counter;
-
- // are we done? if not then continue with the next page
- if (it != m_state.free_pages.end()) {
- // allocate (or fetch) an overflow page
- if (!next_pageid) {
- Page *new_page = alloc(context, Page::kTypePageManager,
- PageManager::kIgnoreFreelist);
- // patch the overflow pointer in the old (current) page
- p = page->get_payload();
- if (page == m_state.state_page) // skip m_state.last_blob_page_id?
- p += sizeof(uint64_t);
- *(uint64_t *)p = new_page->get_address();
-
- // reset the overflow pointer in the new page
- page = new_page;
- p = page->get_payload();
- *(uint64_t *)p = 0;
- }
- else
- page = fetch(context, next_pageid, 0);
-
- // make sure that the page is logged
- page->set_dirty(true);
- }
- }
-
- return (m_state.state_page->get_address());
-}
-
-void
-PageManager::maybe_store_state(Context *context, bool force)
-{
- if (force || (m_state.config.flags & HAM_ENABLE_RECOVERY)) {
- uint64_t new_blobid = store_state(context);
- if (new_blobid != m_state.header->get_page_manager_blobid()) {
- m_state.header->set_page_manager_blobid(new_blobid);
- // don't bother to lock the header page
- m_state.header->get_header_page()->set_dirty(true);
- context->changeset.put(m_state.header->get_header_page());
- }
- }
-}
-
-Page *
-PageManager::safely_lock_page(Context *context, Page *page,
- bool allow_recursive_lock)
-{
- context->changeset.put(page);
-
- ham_assert(page->mutex().try_lock() == false);
-
- // fetch contents again?
- if (!page->get_data()) {
- page->fetch(page->get_address());
- }
-
- return (page);
-}
-
-PageManagerTest
-PageManager::test()
-{
- return (PageManagerTest(this));
-}
-
-PageManagerTest::PageManagerTest(PageManager *page_manager)
- : m_sut(page_manager)
-{
-}
-
-uint64_t
-PageManagerTest::store_state()
-{
- Context context(0, 0, 0);
- return (m_sut->store_state(&context));
-}
-
-void
-PageManagerTest::remove_page(Page *page)
-{
- m_sut->m_state.cache.del(page);
-}
-
-bool
-PageManagerTest::is_page_free(uint64_t pageid)
-{
- return (m_sut->m_state.free_pages.find(pageid)
- != m_sut->m_state.free_pages.end());
-}
-
-Page *
-PageManagerTest::fetch_page(uint64_t id)
-{
- return (m_sut->m_state.cache.get(id));
-}
-
-void
-PageManagerTest::store_page(Page *page)
-{
- m_sut->m_state.cache.put(page);
-}
-
-bool
-PageManagerTest::is_cache_full()
-{
- return (m_sut->m_state.cache.is_cache_full());
-}
-
-PageManagerState *
-PageManagerTest::state()
-{
- return (&m_sut->m_state);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager.h b/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager.h
deleted file mode 100644
index a6593e39ae..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The PageManager allocates, fetches and frees pages. It manages the
- * list of all pages (free and not free), and maps their virtual ID to
- * their physical address in the file.
- *
- * @exception_safe: basic
- * @thread_safe: no
- */
-
-#ifndef HAM_PAGE_MANAGER_H
-#define HAM_PAGE_MANAGER_H
-
-#include "0root/root.h"
-
-#include <map>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/scoped_ptr.h"
-#include "3page_manager/page_manager_state.h"
-#include "3page_manager/page_manager_test.h"
-#include "3page_manager/page_manager_worker.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-class LocalDatabase;
-class LocalEnvironment;
-
-class PageManager
-{
- public:
- enum {
- // flag for alloc(): Clear the full page with zeroes
- kClearWithZero = 1,
-
- // flag for alloc(): Ignores the freelist
- kIgnoreFreelist = 2,
-
- // flag for alloc(): Do not persist the PageManager state to disk
- kDisableStoreState = 4,
-
- // Flag for fetch(): only fetches from cache, not from disk
- kOnlyFromCache = 1,
-
- // Flag for fetch(): does not add page to the Changeset
- kReadOnly = 2,
-
- // Flag for fetch(): page is part of a multi-page blob, has no header
- kNoHeader = 4
- };
-
- // Constructor
- PageManager(LocalEnvironment *env);
-
- // Loads the state from a blob
- void initialize(uint64_t blobid);
-
- // Fills in the current metrics for the PageManager, the Cache and the
- // Freelist
- void fill_metrics(ham_env_metrics_t *metrics) const;
-
- // Fetches a page from disk. |flags| are bitwise OR'd: kOnlyFromCache,
- // kReadOnly, kNoHeader...
- // The page is locked and stored in |context->changeset|.
- Page *fetch(Context *context, uint64_t address, uint32_t flags = 0);
-
- // Allocates a new page. |page_type| is one of Page::kType* in page.h.
- // |flags| are either 0 or kClearWithZero
- // The page is locked and stored in |context->changeset|.
- Page *alloc(Context *context, uint32_t page_type, uint32_t flags = 0);
-
- // Allocates multiple adjacent pages.
- // Used by the BlobManager to store blobs that span multiple pages
- // Returns the first page in the list of pages
- // The pages are locked and stored in |context->changeset|.
- Page *alloc_multiple_blob_pages(Context *context, size_t num_pages);
-
- // Flushes all pages to disk and deletes them if |delete_pages| is true
- void flush(bool delete_pages);
-
- // Asks the worker thread to purge the cache if the cache limits are
- // exceeded
- void purge_cache(Context *context);
-
- // Reclaim file space; truncates unused file space at the end of the file.
- void reclaim_space(Context *context);
-
- // Flushes and closes all pages of a database
- void close_database(Context *context, LocalDatabase *db);
-
- // Schedules one (or many sequential) pages for deletion and adds them
- // to the Freelist. Will not do anything if the Environment is in-memory.
- void del(Context *context, Page *page, size_t page_count = 1);
-
- // Resets the PageManager; calls clear(), then starts a new worker thread
- void reset(Context *context);
-
- // Closes the PageManager; flushes all dirty pages
- void close(Context *context);
-
- // Returns the Page pointer where we can add more blobs
- Page *get_last_blob_page(Context *context);
-
- // Sets the Page pointer where we can add more blobs
- void set_last_blob_page(Page *page);
-
- // Returns additional testing interfaces
- PageManagerTest test();
-
- private:
- friend struct Purger;
- friend class PageManagerTest;
- friend class PageManagerWorker;
-
- // Persists the PageManager's state in the file
- uint64_t store_state(Context *context);
-
- // Calls store_state() whenever it makes sense
- void maybe_store_state(Context *context, bool force);
-
- // Locks a page, fetches contents from disk if they were flushed in
- // the meantime
- Page *safely_lock_page(Context *context, Page *page,
- bool allow_recursive_lock);
-
- // The worker thread which flushes dirty pages
- ScopedPtr<PageManagerWorker> m_worker;
-
- // The state
- PageManagerState m_state;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_PAGE_MANAGER_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_state.h b/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_state.h
deleted file mode 100644
index dc02b02b79..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_state.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The PageManager allocates, fetches and frees pages. It manages the
- * list of all pages (free and not free), and maps their virtual ID to
- * their physical address in the file.
- *
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_PAGE_MANAGER_STATE_H
-#define HAM_PAGE_MANAGER_STATE_H
-
-#include "0root/root.h"
-
-#include <map>
-#include <boost/atomic.hpp>
-
-// Always verify that a file of level N does not include headers > N!
-#include "2config/env_config.h"
-#include "3cache/cache.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Device;
-class EnvironmentHeader;
-class LocalDatabase;
-class LocalEnvironment;
-class LsnManager;
-
-/*
- * The internal state of the PageManager
- */
-struct PageManagerState
-{
- // The freelist maps page-id to number of free pages (usually 1)
- typedef std::map<uint64_t, size_t> FreeMap;
-
- PageManagerState(LocalEnvironment *env);
-
- // Copy of the Environment's configuration
- const EnvironmentConfiguration config;
-
- // The Environment's header
- EnvironmentHeader *header;
-
- // The Device
- Device *device;
-
- // The lsn manager
- LsnManager *lsn_manager;
-
- // The cache
- Cache cache;
-
- // The map with free pages
- FreeMap free_pages;
-
- // Whether |m_free_pages| must be flushed or not
- bool needs_flush;
-
- // Whether a "purge cache" operation is pending
- boost::atomic<bool> purge_cache_pending;
-
- // Page with the persisted state data. If multiple pages are allocated
- // then these pages form a linked list, with |m_state_page| being the head
- Page *state_page;
-
- // Cached page where to add more blobs
- Page *last_blob_page;
-
- // Page where to add more blobs - if |m_last_blob_page| was flushed
- uint64_t last_blob_page_id;
-
- // tracks number of fetched pages
- uint64_t page_count_fetched;
-
- // tracks number of index pages
- uint64_t page_count_index;
-
- // tracks number of blob pages
- uint64_t page_count_blob;
-
- // tracks number of page manager pages
- uint64_t page_count_page_manager;
-
- // tracks number of cache hits
- uint64_t cache_hits;
-
- // tracks number of cache misses
- uint64_t cache_misses;
-
- // number of successful freelist hits
- uint64_t freelist_hits;
-
- // number of freelist misses
- uint64_t freelist_misses;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_PAGE_MANAGER_STATE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_test.h b/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_test.h
deleted file mode 100644
index 741cbc8390..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_test.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A test gateway for the PageManager
- *
- * @exception_safe: no
- * @thread_safe: no
- */
-
-#ifndef HAM_PAGE_MANAGER_TEST_H
-#define HAM_PAGE_MANAGER_TEST_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "3page_manager/page_manager_state.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Page;
-class PageManager;
-
-class PageManagerTest
-{
- public:
- // Constructor
- PageManagerTest(PageManager *page_manager);
-
- // Stores the local PageManager state to disk; returns the blob id
- uint64_t store_state();
-
- // Removes a page from the list; only for testing.
- void remove_page(Page *page);
-
- // Returns true if a page is free. Ignores multi-pages; only for
- // testing and integrity checks
- bool is_page_free(uint64_t pageid);
-
- // Fetches a page from the cache
- Page *fetch_page(uint64_t id);
-
- // Stores a page in the cache
- void store_page(Page *page);
-
- // Returns true if the cache is full
- bool is_cache_full();
-
- // Returns the state
- PageManagerState *state();
-
- private:
- // Reference of the PageManager instance
- PageManager *m_sut;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_PAGE_MANAGER_TEST_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_worker.h b/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_worker.h
deleted file mode 100644
index 2a66189765..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/3page_manager/page_manager_worker.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The worker thread for the PageManager
- */
-
-#ifndef HAM_PAGE_MANAGER_WORKER_H
-#define HAM_PAGE_MANAGER_WORKER_H
-
-#include "0root/root.h"
-
-#include <vector>
-#include <boost/thread.hpp>
-#include <boost/atomic.hpp>
-
-// Always verify that a file of level N does not include headers > N!
-#include "2device/device.h"
-#include "2queue/queue.h"
-#include "2worker/worker.h"
-#include "3cache/cache.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct FlushPageMessage : public MessageBase
-{
- // The available message types
- enum {
- kFlushPage = 1,
- };
-
- FlushPageMessage()
- : MessageBase(kFlushPage, 0) {
- }
-
- std::vector<Page *> list;
-};
-
-
-class PageManagerWorker : public Worker
-{
- public:
- PageManagerWorker(Cache *cache)
- : Worker(), m_cache(cache) {
- }
-
- private:
- virtual void handle_message(MessageBase *message) {
- switch (message->type) {
- case FlushPageMessage::kFlushPage: {
- FlushPageMessage *fpm = (FlushPageMessage *)message;
- for (std::vector<Page *>::iterator it = fpm->list.begin();
- it != fpm->list.end();
- ++it) {
- Page *page = *it;
- ham_assert(page != 0);
- ham_assert(page->mutex().try_lock() == false);
- try {
- page->flush();
- }
- catch (Exception &) {
- page->mutex().unlock();
- throw;
- }
- page->mutex().unlock();
- }
- break;
- }
- default:
- ham_assert(!"shouldn't be here");
- }
- }
-
- // The PageManager's cache
- Cache *m_cache;
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_PAGE_MANAGER_WORKER_H
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4context/context.h b/plugins/Dbx_kv/src/hamsterdb/src/4context/context.h
deleted file mode 100644
index 7a88aa211e..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4context/context.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_CONTEXT_H
-#define HAM_CONTEXT_H
-
-#include "0root/root.h"
-
-#include "3changeset/changeset.h"
-
-namespace hamsterdb {
-
-class Cursor;
-class LocalDatabase;
-class LocalEnvironment;
-class LocalTransaction;
-
-struct Context
-{
- Context(LocalEnvironment *env, LocalTransaction *txn = 0,
- LocalDatabase *db = 0)
- : env(env), txn(txn), db(db), changeset(env) {
- }
-
- ~Context() {
- changeset.clear();
- }
-
- LocalEnvironment *env;
- LocalTransaction *txn;
- LocalDatabase *db;
-
- // Each operation has its own changeset which stores all locked pages
- Changeset changeset;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_CONTEXT_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4cursor/cursor.cc b/plugins/Dbx_kv/src/hamsterdb/src/4cursor/cursor.cc
deleted file mode 100644
index 57cc80a6f6..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4cursor/cursor.cc
+++ /dev/null
@@ -1,1119 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "3btree/btree_cursor.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_node_proxy.h"
-#include "4cursor/cursor.h"
-#include "4env/env_local.h"
-#include "4txn/txn_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-Cursor::Cursor(LocalDatabase *db, Transaction *txn, uint32_t flags)
- : m_db(db), m_txn(txn), m_txn_cursor(this), m_btree_cursor(this),
- m_remote_handle(0), m_next(0), m_previous(0), m_dupecache_index(0),
- m_lastop(0), m_last_cmp(0), m_flags(flags), m_is_first_use(true)
-{
-}
-
-Cursor::Cursor(Cursor &other)
- : m_db(other.m_db), m_txn_cursor(this), m_btree_cursor(this)
-{
- m_txn = other.m_txn;
- m_remote_handle = other.m_remote_handle;
- m_next = other.m_next;
- m_previous = other.m_previous;
- m_dupecache_index = other.m_dupecache_index;
- m_lastop = other.m_lastop;
- m_last_cmp = other.m_last_cmp;
- m_flags = other.m_flags;
- m_is_first_use = other.m_is_first_use;
-
- m_btree_cursor.clone(&other.m_btree_cursor);
- m_txn_cursor.clone(&other.m_txn_cursor);
-
- if (m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS)
- other.m_dupecache.clone(&m_dupecache);
-}
-
-void
-Cursor::append_btree_duplicates(Context *context, BtreeCursor *btc,
- DupeCache *dc)
-{
- uint32_t count = btc->get_record_count(context, 0);
- for (uint32_t i = 0; i < count; i++)
- dc->append(DupeCacheLine(true, i));
-}
-
-void
-Cursor::update_dupecache(Context *context, uint32_t what)
-{
- if (!(m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS))
- return;
-
- /* if the cache already exists: no need to continue, it should be
- * up to date */
- if (m_dupecache.get_count() != 0)
- return;
-
- if ((what & kBtree) && (what & kTxn)) {
- if (is_nil(kBtree) && !is_nil(kTxn)) {
- bool equal_keys;
- sync(context, 0, &equal_keys);
- if (!equal_keys)
- set_to_nil(kBtree);
- }
- }
-
- /* first collect all duplicates from the btree. They're already sorted,
- * therefore we can just append them to our duplicate-cache. */
- if ((what & kBtree) && !is_nil(kBtree))
- append_btree_duplicates(context, &m_btree_cursor, &m_dupecache);
-
- /* read duplicates from the txn-cursor? */
- if ((what & kTxn) && !is_nil(kTxn)) {
- TransactionOperation *op = m_txn_cursor.get_coupled_op();
- TransactionNode *node = op->get_node();
-
- if (!node)
- return;
-
- /* now start integrating the items from the transactions */
- op = node->get_oldest_op();
- while (op) {
- Transaction *optxn = op->get_txn();
- /* collect all ops that are valid (even those that are
- * from conflicting transactions) */
- if (!optxn->is_aborted()) {
- /* a normal (overwriting) insert will overwrite ALL dupes,
- * but an overwrite of a duplicate will only overwrite
- * an entry in the dupecache */
- if (op->get_flags() & TransactionOperation::kInsert) {
- /* all existing dupes are overwritten */
- m_dupecache.clear();
- m_dupecache.append(DupeCacheLine(false, op));
- }
- else if (op->get_flags() & TransactionOperation::kInsertOverwrite) {
- uint32_t ref = op->get_referenced_dupe();
- if (ref) {
- ham_assert(ref <= m_dupecache.get_count());
- DupeCacheLine *e = m_dupecache.get_first_element();
- (&e[ref - 1])->set_txn_op(op);
- }
- else {
- /* all existing dupes are overwritten */
- m_dupecache.clear();
- m_dupecache.append(DupeCacheLine(false, op));
- }
- }
- /* insert a duplicate key */
- else if (op->get_flags() & TransactionOperation::kInsertDuplicate) {
- uint32_t of = op->get_orig_flags();
- uint32_t ref = op->get_referenced_dupe() - 1;
- DupeCacheLine dcl(false, op);
- if (of & HAM_DUPLICATE_INSERT_FIRST)
- m_dupecache.insert(0, dcl);
- else if (of & HAM_DUPLICATE_INSERT_BEFORE) {
- m_dupecache.insert(ref, dcl);
- }
- else if (of & HAM_DUPLICATE_INSERT_AFTER) {
- if (ref + 1 >= m_dupecache.get_count())
- m_dupecache.append(dcl);
- else
- m_dupecache.insert(ref + 1, dcl);
- }
- else /* default is HAM_DUPLICATE_INSERT_LAST */
- m_dupecache.append(dcl);
- }
- /* a normal erase will erase ALL duplicate keys */
- else if (op->get_flags() & TransactionOperation::kErase) {
- uint32_t ref = op->get_referenced_dupe();
- if (ref) {
- ham_assert(ref <= m_dupecache.get_count());
- m_dupecache.erase(ref - 1);
- }
- else {
- /* all existing dupes are erased */
- m_dupecache.clear();
- }
- }
- else {
- /* everything else is a bug! */
- ham_assert(op->get_flags() == TransactionOperation::kNop);
- }
- }
-
- /* continue with the previous/older operation */
- op = op->get_next_in_node();
- }
- }
-}
-
-void
-Cursor::couple_to_dupe(uint32_t dupe_id)
-{
- DupeCacheLine *e = 0;
-
- ham_assert(m_dupecache.get_count() >= dupe_id);
- ham_assert(dupe_id >= 1);
-
- /* dupe-id is a 1-based index! */
- e = m_dupecache.get_element(dupe_id - 1);
- if (e->use_btree()) {
- couple_to_btree();
- m_btree_cursor.set_duplicate_index((uint32_t)e->get_btree_dupe_idx());
- }
- else {
- ham_assert(e->get_txn_op() != 0);
- m_txn_cursor.couple_to_op(e->get_txn_op());
- couple_to_txnop();
- }
- set_dupecache_index(dupe_id);
-}
-
-ham_status_t
-Cursor::check_if_btree_key_is_erased_or_overwritten(Context *context)
-{
- ham_key_t key = {0};
- TransactionOperation *op;
- // TODO not threadsafe - will leak if an exception is thrown
- Cursor *clone = get_db()->cursor_clone_impl(this);
-
- ham_status_t st = m_btree_cursor.move(context, &key,
- &get_db()->key_arena(get_txn()), 0, 0, 0);
- if (st) {
- get_db()->cursor_close(clone);
- return (st);
- }
-
- st = clone->m_txn_cursor.find(&key, 0);
- if (st) {
- get_db()->cursor_close_impl(clone);
- delete clone;
- return (st);
- }
-
- op = clone->m_txn_cursor.get_coupled_op();
- if (op->get_flags() & TransactionOperation::kInsertDuplicate)
- st = HAM_KEY_NOT_FOUND;
- get_db()->cursor_close_impl(clone);
- delete clone;
- return (st);
-}
-
-void
-Cursor::sync(Context *context, uint32_t flags, bool *equal_keys)
-{
- if (equal_keys)
- *equal_keys = false;
-
- if (is_nil(kBtree)) {
- if (!m_txn_cursor.get_coupled_op())
- return;
- ham_key_t *key = m_txn_cursor.get_coupled_op()->get_node()->get_key();
-
- if (!(flags & kSyncOnlyEqualKeys))
- flags = flags | ((flags & HAM_CURSOR_NEXT)
- ? HAM_FIND_GEQ_MATCH
- : HAM_FIND_LEQ_MATCH);
- /* the flag |kSyncDontLoadKey| does not load the key if there's an
- * approx match - it only positions the cursor */
- ham_status_t st = m_btree_cursor.find(context, key, 0, 0, 0,
- kSyncDontLoadKey | flags);
- /* if we had a direct hit instead of an approx. match then
- * set |equal_keys| to false; otherwise Cursor::move()
- * will move the btree cursor again */
- if (st == 0 && equal_keys && !ham_key_get_approximate_match_type(key))
- *equal_keys = true;
- }
- else if (is_nil(kTxn)) {
- // TODO not threadsafe - will leak if an exception is thrown
- Cursor *clone = get_db()->cursor_clone_impl(this);
- clone->m_btree_cursor.uncouple_from_page(context);
- ham_key_t *key = clone->m_btree_cursor.get_uncoupled_key();
- if (!(flags & kSyncOnlyEqualKeys))
- flags = flags | ((flags & HAM_CURSOR_NEXT)
- ? HAM_FIND_GEQ_MATCH
- : HAM_FIND_LEQ_MATCH);
-
- ham_status_t st = m_txn_cursor.find(key, kSyncDontLoadKey | flags);
- /* if we had a direct hit instead of an approx. match then
- * set |equal_keys| to false; otherwise Cursor::move()
- * will move the btree cursor again */
- if (st == 0 && equal_keys && !ham_key_get_approximate_match_type(key))
- *equal_keys = true;
- get_db()->cursor_close_impl(clone);
- delete clone;
- }
-}
-
-ham_status_t
-Cursor::move_next_dupe(Context *context)
-{
- if (get_dupecache_index()) {
- if (get_dupecache_index() < m_dupecache.get_count()) {
- set_dupecache_index(get_dupecache_index() + 1);
- couple_to_dupe(get_dupecache_index());
- return (0);
- }
- }
- return (HAM_LIMITS_REACHED);
-}
-
-ham_status_t
-Cursor::move_previous_dupe(Context *context)
-{
- if (get_dupecache_index()) {
- if (get_dupecache_index() > 1) {
- set_dupecache_index(get_dupecache_index() - 1);
- couple_to_dupe(get_dupecache_index());
- return (0);
- }
- }
- return (HAM_LIMITS_REACHED);
-}
-
-ham_status_t
-Cursor::move_first_dupe(Context *context)
-{
- if (m_dupecache.get_count()) {
- set_dupecache_index(1);
- couple_to_dupe(get_dupecache_index());
- return (0);
- }
- return (HAM_LIMITS_REACHED);
-}
-
-ham_status_t
-Cursor::move_last_dupe(Context *context)
-{
- if (m_dupecache.get_count()) {
- set_dupecache_index(m_dupecache.get_count());
- couple_to_dupe(get_dupecache_index());
- return (0);
- }
- return (HAM_LIMITS_REACHED);
-}
-
-static bool
-__txn_cursor_is_erase(TransactionCursor *txnc)
-{
- TransactionOperation *op = txnc->get_coupled_op();
- return (op
- ? (op->get_flags() & TransactionOperation::kErase) != 0
- : false);
-}
-
-int
-Cursor::compare(Context *context)
-{
- BtreeCursor *btrc = get_btree_cursor();
- BtreeIndex *btree = get_db()->btree_index();
-
- TransactionNode *node = m_txn_cursor.get_coupled_op()->get_node();
- ham_key_t *txnk = node->get_key();
-
- ham_assert(!is_nil(0));
- ham_assert(!m_txn_cursor.is_nil());
-
- if (btrc->get_state() == BtreeCursor::kStateCoupled) {
- Page *page;
- int slot;
- btrc->get_coupled_key(&page, &slot, 0);
- m_last_cmp = btree->get_node_from_page(page)->compare(context, txnk, slot);
-
- // need to fix the sort order - we compare txnk vs page[slot], but the
- // caller expects m_last_cmp to be the comparison of page[slot] vs txnk
- if (m_last_cmp < 0)
- m_last_cmp = +1;
- else if (m_last_cmp > 0)
- m_last_cmp = -1;
-
- return (m_last_cmp);
- }
- else if (btrc->get_state() == BtreeCursor::kStateUncoupled) {
- m_last_cmp = btree->compare_keys(btrc->get_uncoupled_key(), txnk);
- return (m_last_cmp);
- }
-
- ham_assert(!"shouldn't be here");
- return (0);
-}
-
-ham_status_t
-Cursor::move_next_key_singlestep(Context *context)
-{
- ham_status_t st = 0;
- BtreeCursor *btrc = get_btree_cursor();
-
- /* if both cursors point to the same key: move next with both */
- if (m_last_cmp == 0) {
- if (!is_nil(kBtree)) {
- st = btrc->move(context, 0, 0, 0, 0,
- HAM_CURSOR_NEXT | HAM_SKIP_DUPLICATES);
- if (st == HAM_KEY_NOT_FOUND || st == HAM_CURSOR_IS_NIL) {
- set_to_nil(kBtree); // TODO muss raus
- if (m_txn_cursor.is_nil())
- return (HAM_KEY_NOT_FOUND);
- else {
- couple_to_txnop();
- m_last_cmp = 1;
- }
- }
- }
- if (!m_txn_cursor.is_nil()) {
- st = m_txn_cursor.move(HAM_CURSOR_NEXT);
- if (st == HAM_KEY_NOT_FOUND || st==HAM_CURSOR_IS_NIL) {
- set_to_nil(kTxn); // TODO muss raus
- if (is_nil(kBtree))
- return (HAM_KEY_NOT_FOUND);
- else {
- couple_to_btree();
- m_last_cmp = -1;
-
- ham_status_t st2 = check_if_btree_key_is_erased_or_overwritten(context);
- if (st2 == HAM_TXN_CONFLICT)
- st = st2;
- }
- }
- }
- }
- /* if the btree-key is smaller: move it next */
- else if (m_last_cmp < 0) {
- st = btrc->move(context, 0, 0, 0, 0, HAM_CURSOR_NEXT | HAM_SKIP_DUPLICATES);
- if (st == HAM_KEY_NOT_FOUND) {
- set_to_nil(kBtree); // TODO Das muss raus!
- if (m_txn_cursor.is_nil())
- return (st);
- couple_to_txnop();
- m_last_cmp = +1;
- }
- else {
- ham_status_t st2 = check_if_btree_key_is_erased_or_overwritten(context);
- if (st2 == HAM_TXN_CONFLICT)
- st = st2;
- }
- if (m_txn_cursor.is_nil())
- m_last_cmp = -1;
- }
- /* if the txn-key is smaller OR if both keys are equal: move next
- * with the txn-key (which is chronologically newer) */
- else {
- st = m_txn_cursor.move(HAM_CURSOR_NEXT);
- if (st == HAM_KEY_NOT_FOUND) {
- set_to_nil(kTxn); // TODO Das muss raus!
- if (is_nil(kBtree))
- return (st);
- couple_to_btree();
- m_last_cmp = -1;
- }
- if (is_nil(kBtree))
- m_last_cmp = 1;
- }
-
- /* compare keys again */
- if (!is_nil(kBtree) && !m_txn_cursor.is_nil())
- compare(context);
-
- /* if there's a txn conflict: move next */
- if (st == HAM_TXN_CONFLICT)
- return (move_next_key_singlestep(context));
-
- /* btree-key is smaller */
- if (m_last_cmp < 0 || m_txn_cursor.is_nil()) {
- couple_to_btree();
- update_dupecache(context, kBtree);
- return (0);
- }
- /* txn-key is smaller */
- else if (m_last_cmp > 0 || btrc->get_state() == BtreeCursor::kStateNil) {
- couple_to_txnop();
- update_dupecache(context, kTxn);
- return (0);
- }
- /* both keys are equal */
- else {
- couple_to_txnop();
- update_dupecache(context, kTxn | kBtree);
- return (0);
- }
-}
-
-ham_status_t
-Cursor::move_next_key(Context *context, uint32_t flags)
-{
- ham_status_t st;
-
- /* are we in the middle of a duplicate list? if yes then move to the
- * next duplicate */
- if (get_dupecache_index() > 0 && !(flags & HAM_SKIP_DUPLICATES)) {
- st = move_next_dupe(context);
- if (st != HAM_LIMITS_REACHED)
- return (st);
- else if (st == HAM_LIMITS_REACHED && (flags & HAM_ONLY_DUPLICATES))
- return (HAM_KEY_NOT_FOUND);
- }
-
- clear_dupecache();
-
- /* either there were no duplicates or we've reached the end of the
- * duplicate list. move next till we found a new candidate */
- while (1) {
- st = move_next_key_singlestep(context);
- if (st)
- return (st);
-
- /* check for duplicates. the dupecache was already updated in
- * move_next_key_singlestep() */
- if (m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS) {
- /* are there any duplicates? if not then they were all erased and
- * we move to the previous key */
- if (!has_duplicates())
- continue;
-
- /* otherwise move to the first duplicate */
- return (move_first_dupe(context));
- }
-
- /* no duplicates - make sure that we've not coupled to an erased
- * item */
- if (is_coupled_to_txnop()) {
- if (__txn_cursor_is_erase(&m_txn_cursor))
- continue;
- else
- return (0);
- }
- if (is_coupled_to_btree()) {
- st = check_if_btree_key_is_erased_or_overwritten(context);
- if (st == HAM_KEY_ERASED_IN_TXN)
- continue;
- else if (st == 0) {
- couple_to_txnop();
- return (0);
- }
- else if (st == HAM_KEY_NOT_FOUND)
- return (0);
- else
- return (st);
- }
- else
- return (HAM_KEY_NOT_FOUND);
- }
-
- ham_assert(!"should never reach this");
- return (HAM_INTERNAL_ERROR);
-}
-
-ham_status_t
-Cursor::move_previous_key_singlestep(Context *context)
-{
- ham_status_t st = 0;
- BtreeCursor *btrc = get_btree_cursor();
-
- /* if both cursors point to the same key: move previous with both */
- if (m_last_cmp == 0) {
- if (!is_nil(kBtree)) {
- st = btrc->move(context, 0, 0, 0, 0,
- HAM_CURSOR_PREVIOUS | HAM_SKIP_DUPLICATES);
- if (st == HAM_KEY_NOT_FOUND || st == HAM_CURSOR_IS_NIL) {
- set_to_nil(kBtree); // TODO muss raus
- if (m_txn_cursor.is_nil())
- return (HAM_KEY_NOT_FOUND);
- else {
- couple_to_txnop();
- m_last_cmp = -1;
- }
- }
- }
- if (!m_txn_cursor.is_nil()) {
- st = m_txn_cursor.move(HAM_CURSOR_PREVIOUS);
- if (st == HAM_KEY_NOT_FOUND || st==HAM_CURSOR_IS_NIL) {
- set_to_nil(kTxn); // TODO muss raus
- if (is_nil(kBtree))
- return (HAM_KEY_NOT_FOUND);
- else {
- couple_to_btree();
- m_last_cmp = 1;
- }
- }
- }
- }
- /* if the btree-key is greater: move previous */
- else if (m_last_cmp > 0) {
- st = btrc->move(context, 0, 0, 0, 0,
- HAM_CURSOR_PREVIOUS | HAM_SKIP_DUPLICATES);
- if (st == HAM_KEY_NOT_FOUND) {
- set_to_nil(kBtree); // TODO Das muss raus!
- if (m_txn_cursor.is_nil())
- return (st);
- couple_to_txnop();
- m_last_cmp = -1;
- }
- else {
- ham_status_t st2 = check_if_btree_key_is_erased_or_overwritten(context);
- if (st2 == HAM_TXN_CONFLICT)
- st = st2;
- }
- if (m_txn_cursor.is_nil())
- m_last_cmp = 1;
- }
- /* if the txn-key is greater OR if both keys are equal: move previous
- * with the txn-key (which is chronologically newer) */
- else {
- st = m_txn_cursor.move(HAM_CURSOR_PREVIOUS);
- if (st == HAM_KEY_NOT_FOUND) {
- set_to_nil(kTxn); // TODO Das muss raus!
- if (is_nil(kBtree))
- return (st);
- couple_to_btree();
- m_last_cmp = 1;
-
- ham_status_t st2 = check_if_btree_key_is_erased_or_overwritten(context);
- if (st2 == HAM_TXN_CONFLICT)
- st = st2;
- }
- if (is_nil(kBtree))
- m_last_cmp = -1;
- }
-
- /* compare keys again */
- if (!is_nil(kBtree) && !m_txn_cursor.is_nil())
- compare(context);
-
- /* if there's a txn conflict: move previous */
- if (st == HAM_TXN_CONFLICT)
- return (move_previous_key_singlestep(context));
-
- /* btree-key is greater */
- if (m_last_cmp > 0 || m_txn_cursor.is_nil()) {
- couple_to_btree();
- update_dupecache(context, kBtree);
- return (0);
- }
- /* txn-key is greater */
- else if (m_last_cmp < 0 || btrc->get_state() == BtreeCursor::kStateNil) {
- couple_to_txnop();
- update_dupecache(context, kTxn);
- return (0);
- }
- /* both keys are equal */
- else {
- couple_to_txnop();
- update_dupecache(context, kTxn | kBtree);
- return (0);
- }
-}
-
-ham_status_t
-Cursor::move_previous_key(Context *context, uint32_t flags)
-{
- ham_status_t st;
-
- /* are we in the middle of a duplicate list? if yes then move to the
- * previous duplicate */
- if (get_dupecache_index() > 0 && !(flags & HAM_SKIP_DUPLICATES)) {
- st = move_previous_dupe(context);
- if (st != HAM_LIMITS_REACHED)
- return (st);
- else if (st == HAM_LIMITS_REACHED && (flags & HAM_ONLY_DUPLICATES))
- return (HAM_KEY_NOT_FOUND);
- }
-
- clear_dupecache();
-
- /* either there were no duplicates or we've reached the end of the
- * duplicate list. move previous till we found a new candidate */
- while (!is_nil(kBtree) || !m_txn_cursor.is_nil()) {
- st = move_previous_key_singlestep(context);
- if (st)
- return (st);
-
- /* check for duplicates. the dupecache was already updated in
- * move_previous_key_singlestep() */
- if (m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS) {
- /* are there any duplicates? if not then they were all erased and
- * we move to the previous key */
- if (!has_duplicates())
- continue;
-
- /* otherwise move to the last duplicate */
- return (move_last_dupe(context));
- }
-
- /* no duplicates - make sure that we've not coupled to an erased
- * item */
- if (is_coupled_to_txnop()) {
- if (__txn_cursor_is_erase(&m_txn_cursor))
- continue;
- else
- return (0);
- }
- if (is_coupled_to_btree()) {
- st = check_if_btree_key_is_erased_or_overwritten(context);
- if (st == HAM_KEY_ERASED_IN_TXN)
- continue;
- else if (st == 0) {
- couple_to_txnop();
- return (0);
- }
- else if (st == HAM_KEY_NOT_FOUND)
- return (0);
- else
- return (st);
- }
- else
- return (HAM_KEY_NOT_FOUND);
- }
-
- return (HAM_KEY_NOT_FOUND);
-}
-
-ham_status_t
-Cursor::move_first_key_singlestep(Context *context)
-{
- ham_status_t btrs, txns;
- BtreeCursor *btrc = get_btree_cursor();
-
- /* fetch the smallest key from the transaction tree. */
- txns = m_txn_cursor.move(HAM_CURSOR_FIRST);
- /* fetch the smallest key from the btree tree. */
- btrs = btrc->move(context, 0, 0, 0, 0,
- HAM_CURSOR_FIRST | HAM_SKIP_DUPLICATES);
- /* now consolidate - if both trees are empty then return */
- if (btrs == HAM_KEY_NOT_FOUND && txns == HAM_KEY_NOT_FOUND) {
- return (HAM_KEY_NOT_FOUND);
- }
- /* if btree is empty but txn-tree is not: couple to txn */
- else if (btrs == HAM_KEY_NOT_FOUND && txns != HAM_KEY_NOT_FOUND) {
- if (txns == HAM_TXN_CONFLICT)
- return (txns);
- couple_to_txnop();
- update_dupecache(context, kTxn);
- return (0);
- }
- /* if txn-tree is empty but btree is not: couple to btree */
- else if (txns == HAM_KEY_NOT_FOUND && btrs != HAM_KEY_NOT_FOUND) {
- couple_to_btree();
- update_dupecache(context, kBtree);
- return (0);
- }
- /* if both trees are not empty then compare them and couple to the
- * smaller one */
- else {
- ham_assert(btrs == 0 && (txns == 0
- || txns == HAM_KEY_ERASED_IN_TXN
- || txns == HAM_TXN_CONFLICT));
- compare(context);
-
- /* both keys are equal - couple to txn; it's chronologically
- * newer */
- if (m_last_cmp == 0) {
- if (txns && txns != HAM_KEY_ERASED_IN_TXN)
- return (txns);
- couple_to_txnop();
- update_dupecache(context, kBtree | kTxn);
- }
- /* couple to txn */
- else if (m_last_cmp > 0) {
- if (txns && txns != HAM_KEY_ERASED_IN_TXN)
- return (txns);
- couple_to_txnop();
- update_dupecache(context, kTxn);
- }
- /* couple to btree */
- else {
- couple_to_btree();
- update_dupecache(context, kBtree);
- }
- return (0);
- }
-}
-
-ham_status_t
-Cursor::move_first_key(Context *context, uint32_t flags)
-{
- ham_status_t st = 0;
-
- /* move to the very very first key */
- st = move_first_key_singlestep(context);
- if (st)
- return (st);
-
- /* check for duplicates. the dupecache was already updated in
- * move_first_key_singlestep() */
- if (m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS) {
- /* are there any duplicates? if not then they were all erased and we
- * move to the previous key */
- if (!has_duplicates())
- return (move_next_key(context, flags));
-
- /* otherwise move to the first duplicate */
- return (move_first_dupe(context));
- }
-
- /* no duplicates - make sure that we've not coupled to an erased
- * item */
- if (is_coupled_to_txnop()) {
- if (__txn_cursor_is_erase(&m_txn_cursor))
- return (move_next_key(context, flags));
- else
- return (0);
- }
- if (is_coupled_to_btree()) {
- st = check_if_btree_key_is_erased_or_overwritten(context);
- if (st == HAM_KEY_ERASED_IN_TXN)
- return (move_next_key(context, flags));
- else if (st == 0) {
- couple_to_txnop();
- return (0);
- }
- else if (st == HAM_KEY_NOT_FOUND)
- return (0);
- else
- return (st);
- }
- else
- return (HAM_KEY_NOT_FOUND);
-}
-
-ham_status_t
-Cursor::move_last_key_singlestep(Context *context)
-{
- ham_status_t btrs, txns;
- BtreeCursor *btrc = get_btree_cursor();
-
- /* fetch the largest key from the transaction tree. */
- txns = m_txn_cursor.move(HAM_CURSOR_LAST);
- /* fetch the largest key from the btree tree. */
- btrs = btrc->move(context, 0, 0, 0, 0, HAM_CURSOR_LAST | HAM_SKIP_DUPLICATES);
- /* now consolidate - if both trees are empty then return */
- if (btrs == HAM_KEY_NOT_FOUND && txns == HAM_KEY_NOT_FOUND) {
- return (HAM_KEY_NOT_FOUND);
- }
- /* if btree is empty but txn-tree is not: couple to txn */
- else if (btrs == HAM_KEY_NOT_FOUND && txns != HAM_KEY_NOT_FOUND) {
- if (txns == HAM_TXN_CONFLICT)
- return (txns);
- couple_to_txnop();
- update_dupecache(context, kTxn);
- return (0);
- }
- /* if txn-tree is empty but btree is not: couple to btree */
- else if (txns == HAM_KEY_NOT_FOUND && btrs != HAM_KEY_NOT_FOUND) {
- couple_to_btree();
- update_dupecache(context, kBtree);
- return (0);
- }
- /* if both trees are not empty then compare them and couple to the
- * greater one */
- else {
- ham_assert(btrs == 0 && (txns == 0
- || txns == HAM_KEY_ERASED_IN_TXN
- || txns == HAM_TXN_CONFLICT));
- compare(context);
-
- /* both keys are equal - couple to txn; it's chronologically
- * newer */
- if (m_last_cmp == 0) {
- if (txns && txns != HAM_KEY_ERASED_IN_TXN)
- return (txns);
- couple_to_txnop();
- update_dupecache(context, kBtree | kTxn);
- }
- /* couple to txn */
- else if (m_last_cmp < 1) {
- if (txns && txns != HAM_KEY_ERASED_IN_TXN)
- return (txns);
- couple_to_txnop();
- update_dupecache(context, kTxn);
- }
- /* couple to btree */
- else {
- couple_to_btree();
- update_dupecache(context, kBtree);
- }
- return (0);
- }
-}
-
-ham_status_t
-Cursor::move_last_key(Context *context, uint32_t flags)
-{
- ham_status_t st = 0;
-
- /* move to the very very last key */
- st = move_last_key_singlestep(context);
- if (st)
- return (st);
-
- /* check for duplicates. the dupecache was already updated in
- * move_last_key_singlestep() */
- if (m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS) {
- /* are there any duplicates? if not then they were all erased and we
- * move to the previous key */
- if (!has_duplicates())
- return (move_previous_key(context, flags));
-
- /* otherwise move to the last duplicate */
- return (move_last_dupe(context));
- }
-
- /* no duplicates - make sure that we've not coupled to an erased
- * item */
- if (is_coupled_to_txnop()) {
- if (__txn_cursor_is_erase(&m_txn_cursor))
- return (move_previous_key(context, flags));
- else
- return (0);
- }
- if (is_coupled_to_btree()) {
- st = check_if_btree_key_is_erased_or_overwritten(context);
- if (st == HAM_KEY_ERASED_IN_TXN)
- return (move_previous_key(context, flags));
- else if (st == 0) {
- couple_to_txnop();
- return (0);
- }
- else if (st == HAM_KEY_NOT_FOUND)
- return (0);
- else
- return (st);
- }
- else
- return (HAM_KEY_NOT_FOUND);
-}
-
-ham_status_t
-Cursor::move(Context *context, ham_key_t *key, ham_record_t *record,
- uint32_t flags)
-{
- ham_status_t st = 0;
- bool changed_dir = false;
- BtreeCursor *btrc = get_btree_cursor();
-
- /* no movement requested? directly retrieve key/record */
- if (!flags)
- goto retrieve_key_and_record;
-
- /* synchronize the btree and transaction cursor if the last operation was
- * not a move next/previous OR if the direction changed */
- if ((m_lastop == HAM_CURSOR_PREVIOUS) && (flags & HAM_CURSOR_NEXT))
- changed_dir = true;
- else if ((m_lastop == HAM_CURSOR_NEXT) && (flags & HAM_CURSOR_PREVIOUS))
- changed_dir = true;
- if (((flags & HAM_CURSOR_NEXT) || (flags & HAM_CURSOR_PREVIOUS))
- && (m_lastop == Cursor::kLookupOrInsert
- || changed_dir)) {
- if (is_coupled_to_txnop())
- set_to_nil(kBtree);
- else
- set_to_nil(kTxn);
- (void)sync(context, flags, 0);
-
- if (!m_txn_cursor.is_nil() && !is_nil(kBtree))
- compare(context);
- }
-
- /* we have either skipped duplicates or reached the end of the duplicate
- * list. btree cursor and txn cursor are synced and as close to
- * each other as possible. Move the cursor in the requested direction. */
- if (flags & HAM_CURSOR_NEXT) {
- st = move_next_key(context, flags);
- }
- else if (flags & HAM_CURSOR_PREVIOUS) {
- st = move_previous_key(context, flags);
- }
- else if (flags & HAM_CURSOR_FIRST) {
- clear_dupecache();
- st = move_first_key(context, flags);
- }
- else {
- ham_assert(flags & HAM_CURSOR_LAST);
- clear_dupecache();
- st = move_last_key(context, flags);
- }
-
- if (st)
- return (st);
-
-retrieve_key_and_record:
- /* retrieve key/record, if requested */
- if (st == 0) {
- if (is_coupled_to_txnop()) {
-#ifdef HAM_DEBUG
- TransactionOperation *op = m_txn_cursor.get_coupled_op();
- ham_assert(!(op->get_flags() & TransactionOperation::kErase));
-#endif
- try {
- if (key)
- m_txn_cursor.copy_coupled_key(key);
- if (record)
- m_txn_cursor.copy_coupled_record(record);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
- }
- else {
- st = btrc->move(context, key, &get_db()->key_arena(get_txn()),
- record, &get_db()->record_arena(get_txn()), 0);
- }
- }
-
- return (st);
-}
-
-bool
-Cursor::is_nil(int what)
-{
- switch (what) {
- case kBtree:
- return (m_btree_cursor.get_state() == BtreeCursor::kStateNil);
- case kTxn:
- return (m_txn_cursor.is_nil());
- default:
- ham_assert(what == 0);
- return (m_btree_cursor.get_state() == BtreeCursor::kStateNil
- && m_txn_cursor.is_nil());
- }
-}
-
-void
-Cursor::set_to_nil(int what)
-{
- switch (what) {
- case kBtree:
- m_btree_cursor.set_to_nil();
- break;
- case kTxn:
- m_txn_cursor.set_to_nil();
- couple_to_btree(); /* reset flag */
- break;
- default:
- ham_assert(what == 0);
- m_btree_cursor.set_to_nil();
- m_txn_cursor.set_to_nil();
- couple_to_btree(); /* reset flag */
- m_is_first_use = true;
- break;
- }
-}
-
-uint32_t
-Cursor::get_record_count(Context *context, uint32_t flags)
-{
- if (is_nil())
- throw Exception(HAM_CURSOR_IS_NIL);
-
- if (m_txn || is_coupled_to_txnop()) {
- if (m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS) {
- bool dummy;
- sync(context, 0, &dummy);
- update_dupecache(context, kTxn | kBtree);
- return (m_dupecache.get_count());
- }
- else {
- /* obviously the key exists, since the cursor is coupled */
- return (1);
- }
- }
-
- return (m_btree_cursor.get_record_count(context, flags));
-}
-
-uint64_t
-Cursor::get_record_size(Context *context)
-{
- if (is_nil())
- return (HAM_CURSOR_IS_NIL);
-
- if (is_coupled_to_txnop())
- return (m_txn_cursor.get_record_size());
- else
- return (m_btree_cursor.get_record_size(context));
-}
-
-uint32_t
-Cursor::get_duplicate_position()
-{
- if (is_nil())
- throw Exception(HAM_CURSOR_IS_NIL);
-
- // use btree cursor?
- if (m_txn_cursor.is_nil())
- return (m_btree_cursor.get_duplicate_index());
-
- // otherwise return the index in the duplicate cache
- return (get_dupecache_index() - 1);
-}
-
-ham_status_t
-Cursor::overwrite(Context *context, Transaction *htxn,
- ham_record_t *record, uint32_t flags)
-{
- ham_status_t st = 0;
- LocalTransaction *txn = dynamic_cast<LocalTransaction *>(htxn);
- ham_assert(context->txn == txn);
-
- /*
- * if we're in transactional mode then just append an "insert/OW" operation
- * to the txn-tree.
- *
- * if the txn_cursor is already coupled to a txn-op, then we can use
- * txn_cursor_overwrite(). Otherwise we have to call db_insert_txn().
- *
- * If transactions are disabled then overwrite the item in the btree.
- */
- if (txn) {
- if (m_txn_cursor.is_nil() && !(is_nil(0))) {
- m_btree_cursor.uncouple_from_page(context);
- st = m_db->insert_txn(context,
- m_btree_cursor.get_uncoupled_key(),
- record, flags | HAM_OVERWRITE, get_txn_cursor());
- }
- else {
- // TODO also calls db->insert_txn()
- st = m_txn_cursor.overwrite(context, txn, record);
- }
-
- if (st == 0)
- couple_to_txnop();
- }
- else {
- m_btree_cursor.overwrite(context, record, flags);
- couple_to_btree();
- }
-
- return (st);
-}
-
-void
-Cursor::close()
-{
- m_btree_cursor.close();
- m_dupecache.clear();
-}
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4cursor/cursor.h b/plugins/Dbx_kv/src/hamsterdb/src/4cursor/cursor.h
deleted file mode 100644
index 0adf400ab3..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4cursor/cursor.h
+++ /dev/null
@@ -1,555 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A Cursor is an object which is used to traverse a Database.
- *
- * A Cursor structure is separated into 3 components:
- * 1. The btree cursor
- * This cursor can traverse btrees. It is described and implemented
- * in btree_cursor.h.
- * 2. The txn cursor
- * This cursor can traverse txn-trees. It is described and implemented
- * in txn_cursor.h.
- * 3. The upper layer
- * This layer acts as a kind of dispatcher for both cursors. If
- * Transactions are used, then it also uses a duplicate cache for
- * consolidating the duplicate keys from both cursors. This layer is
- * described and implemented in cursor.h (this file).
- *
- * A Cursor can have several states. It can be
- * 1. NIL (not in list) - this is the default state, meaning that the Cursor
- * does not point to any key. If the Cursor was initialized, then it's
- * "NIL". If the Cursor was erased (i.e. with ham_cursor_erase) then it's
- * also "NIL".
- *
- * relevant functions:
- * Cursor::is_nil
- * Cursor::set_to_nil
- *
- * 2. Coupled to the txn-cursor - meaning that the Cursor points to a key
- * that is modified in a Transaction. Technically, the txn-cursor points
- * to a TransactionOperation structure.
- *
- * relevant functions:
- * Cursor::is_coupled_to_txnop
- * Cursor::couple_to_txnop
- *
- * 3. Coupled to the btree-cursor - meaning that the Cursor points to a key
- * that is stored in a Btree. A Btree cursor itself can then be coupled
- * (it directly points to a page in the cache) or uncoupled, meaning that
- * the page was purged from the cache and has to be fetched from disk when
- * the Cursor is used again. This is described in btree_cursor.h.
- *
- * relevant functions:
- * Cursor::is_coupled_to_btree
- * Cursor::couple_to_btree
- *
- * The dupecache is used when information from the btree and the txn-tree
- * is merged. The btree cursor has its private dupecache. The dupecache
- * increases performance (and complexity).
- *
- * The cursor interface is used in db_local.cc. Many of the functions use
- * a high-level cursor interface (i.e. @ref cursor_create, @ref cursor_clone)
- * while some directly use the low-level interfaces of btree_cursor.h and
- * txn_cursor.h. Over time i will clean this up, trying to maintain a clear
- * separation of the 3 layers, and only accessing the top-level layer in
- * cursor.h. This is work in progress.
- *
- * In order to speed up Cursor::move() we keep track of the last compare
- * between the two cursors. i.e. if the btree cursor is currently pointing to
- * a larger key than the txn-cursor, the 'lastcmp' field is <0 etc.
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_CURSORS_H
-#define HAM_CURSORS_H
-
-#include "0root/root.h"
-
-#include <vector>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "4txn/txn_cursor.h"
-#include "3btree/btree_cursor.h"
-#include "3blob_manager/blob_manager.h"
-#include "4db/db_local.h"
-#include "4env/env.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-// A helper structure; ham_cursor_t is declared in ham/hamsterdb.h as an
-// opaque C structure, but internally we use a C++ class. The ham_cursor_t
-// struct satisfies the C compiler, and internally we just cast the pointers.
-struct ham_cursor_t
-{
- bool _dummy;
-};
-
-namespace hamsterdb {
-
-struct Context;
-
-// A single line in the dupecache structure - can reference a btree
-// record or a txn-op
-class DupeCacheLine
-{
- public:
- DupeCacheLine(bool use_btree = true, uint64_t btree_dupeidx = 0)
- : m_btree_dupeidx(btree_dupeidx), m_op(0), m_use_btree(use_btree) {
- ham_assert(use_btree == true);
- }
-
- DupeCacheLine(bool use_btree, TransactionOperation *op)
- : m_btree_dupeidx(0), m_op(op), m_use_btree(use_btree) {
- ham_assert(use_btree == false);
- }
-
- // Returns true if this cache entry is a duplicate in the btree index
- // (otherwise it's a duplicate in the transaction index)
- bool use_btree() const {
- return (m_use_btree);
- }
-
- // Returns the btree duplicate index
- uint64_t get_btree_dupe_idx() {
- ham_assert(m_use_btree == true);
- return (m_btree_dupeidx);
- }
-
- // Sets the btree duplicate index
- void set_btree_dupe_idx(uint64_t idx) {
- m_use_btree = true;
- m_btree_dupeidx = idx;
- m_op = 0;
- }
-
- // Returns the txn-op duplicate
- TransactionOperation *get_txn_op() {
- ham_assert(m_use_btree == false);
- return (m_op);
- }
-
- // Sets the txn-op duplicate
- void set_txn_op(TransactionOperation *op) {
- m_use_btree = false;
- m_op = op;
- m_btree_dupeidx = 0;
- }
-
- private:
- // The btree duplicate index (of the original btree dupe table)
- uint64_t m_btree_dupeidx;
-
- // The txn op structure that we refer to
- TransactionOperation *m_op;
-
- // using btree or txn duplicates?
- bool m_use_btree;
-};
-
-//
-// The dupecache is a cache for duplicate keys
-//
-class DupeCache {
- public:
- // default constructor - creates an empty dupecache with room for 8
- // duplicates
- DupeCache() {
- m_elements.reserve(8);
- }
-
- // Returns the number of elements in the cache
- uint32_t get_count() const {
- return ((uint32_t)m_elements.size());
- }
-
- // Returns an element from the cache
- DupeCacheLine *get_element(unsigned idx) {
- return (&m_elements[idx]);
- }
-
- // Returns a pointer to the first element from the cache
- DupeCacheLine *get_first_element() {
- return (&m_elements[0]);
- }
-
- // Clones this dupe-cache into 'other'
- void clone(DupeCache *other) {
- other->m_elements = m_elements;
- }
-
- // Inserts a new item somewhere in the cache; resizes the
- // cache if necessary
- void insert(unsigned position, const DupeCacheLine &dcl) {
- m_elements.insert(m_elements.begin() + position, dcl);
- }
-
- // Append an element to the dupecache
- void append(const DupeCacheLine &dcl) {
- m_elements.push_back(dcl);
- }
-
- // Erases an item
- void erase(uint32_t position) {
- m_elements.erase(m_elements.begin() + position);
- }
-
- // Clears the cache; frees all resources
- void clear() {
- m_elements.resize(0);
- }
-
- private:
- // The cached elements
- std::vector<DupeCacheLine> m_elements;
-};
-
-
-//
-// the Database Cursor
-//
-class Cursor
-{
- public:
- // The flags have ranges:
- // 0 - 0x1000000-1: btree_cursor
- // > 0x1000000: cursor
- enum {
- // Flags for set_to_nil, is_nil
- kBoth = 0,
- kBtree = 1,
- kTxn = 2,
-
- // Flag for sync(): do not use approx matching if the key
- // is not available
- kSyncOnlyEqualKeys = 0x200000,
-
- // Flag for sync(): do not load the key if there's an approx.
- // match. Only positions the cursor.
- kSyncDontLoadKey = 0x100000,
-
- // Cursor flag: cursor is coupled to the txn-cursor
- kCoupledToTxn = 0x1000000,
-
- // Flag for set_lastop()
- kLookupOrInsert = 0x10000
- };
-
- public:
- // Constructor; retrieves pointer to db and txn, initializes all members
- Cursor(LocalDatabase *db, Transaction *txn = 0, uint32_t flags = 0);
-
- // Copy constructor; used for cloning a Cursor
- Cursor(Cursor &other);
-
- // Destructor; sets cursor to nil
- ~Cursor() {
- set_to_nil();
- }
-
- // Returns the Database
- LocalDatabase *get_db() {
- return (m_db);
- }
-
- // Returns the Transaction handle
- Transaction *get_txn() {
- return (m_txn);
- }
-
- // Sets the Transaction handle; often used to assign a temporary
- // Transaction to this cursor
- void set_txn(Transaction *txn) {
- m_txn = txn;
- }
-
- // Sets the cursor to nil
- void set_to_nil(int what = kBoth);
-
- // Returns true if a cursor is nil (Not In List - does not point to any
- // key)
- // |what| is one of the flags kBoth, kTxn, kBtree
- bool is_nil(int what = kBoth);
-
- // Couples the cursor to the btree key
- void couple_to_btree() {
- m_flags &= ~kCoupledToTxn;
- }
-
- // Returns true if a cursor is coupled to the btree
- bool is_coupled_to_btree() const {
- return (!(m_flags & kCoupledToTxn));
- }
-
- // Couples the cursor to the txn-op
- void couple_to_txnop() {
- m_flags |= kCoupledToTxn;
- }
-
- // Returns true if a cursor is coupled to a txn-op
- bool is_coupled_to_txnop() const {
- return ((m_flags & kCoupledToTxn) ? true : false);
- }
-
- // Retrieves the number of duplicates of the current key
- uint32_t get_record_count(Context *context, uint32_t flags);
-
- // Retrieves the duplicate position of a cursor
- uint32_t get_duplicate_position();
-
- // Retrieves the size of the current record
- uint64_t get_record_size(Context *context);
-
- // Overwrites the record of the current key
- //
- // The Transaction is passed as a separate pointer since it might be a
- // local/temporary Transaction that was created only for this single
- // operation.
- ham_status_t overwrite(Context *context, Transaction *txn,
- ham_record_t *record, uint32_t flags);
-
- // Moves a Cursor (ham_cursor_move)
- ham_status_t move(Context *context, ham_key_t *key, ham_record_t *record,
- uint32_t flags);
-
- // Closes an existing cursor (ham_cursor_close)
- void close();
-
- // Updates (or builds) the dupecache for a cursor
- //
- // The |what| parameter specifies if the dupecache is initialized from
- // btree (kBtree), from txn (kTxn) or both.
- void update_dupecache(Context *context, uint32_t what);
-
- // Appends the duplicates of the BtreeCursor to the duplicate cache.
- void append_btree_duplicates(Context *context, BtreeCursor *btc,
- DupeCache *dc);
-
- // Clears the dupecache and disconnect the Cursor from any duplicate key
- void clear_dupecache() {
- m_dupecache.clear();
- set_dupecache_index(0);
- }
-
- // Couples the cursor to a duplicate in the dupe table
- // dupe_id is a 1 based index!!
- void couple_to_dupe(uint32_t dupe_id);
-
- // Synchronizes txn- and btree-cursor
- //
- // If txn-cursor is nil then try to move the txn-cursor to the same key
- // as the btree cursor.
- // If btree-cursor is nil then try to move the btree-cursor to the same key
- // as the txn cursor.
- // If both are nil, or both are valid, then nothing happens
- //
- // |equal_key| is set to true if the keys in both cursors are equal.
- void sync(Context *context, uint32_t flags, bool *equal_keys);
-
- // Returns the number of duplicates in the duplicate cache
- // The duplicate cache is updated if necessary
- uint32_t get_dupecache_count(Context *context) {
- if (!(m_db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS))
- return (0);
-
- TransactionCursor *txnc = get_txn_cursor();
- if (txnc->get_coupled_op())
- update_dupecache(context, kBtree | kTxn);
- else
- update_dupecache(context, kBtree);
- return (m_dupecache.get_count());
- }
-
- // Get the 'next' Cursor in this Database
- Cursor *get_next() {
- return (m_next);
- }
-
- // Set the 'next' Cursor in this Database
- void set_next(Cursor *next) {
- m_next = next;
- }
-
- // Get the 'previous' Cursor in this Database
- Cursor *get_previous() {
- return (m_previous);
- }
-
- // Set the 'previous' Cursor in this Database
- void set_previous(Cursor *previous) {
- m_previous = previous;
- }
-
- // Returns the Transaction cursor
- // TODO required?
- TransactionCursor *get_txn_cursor() {
- return (&m_txn_cursor);
- }
-
- // Returns the Btree cursor
- // TODO required?
- BtreeCursor *get_btree_cursor() {
- return (&m_btree_cursor);
- }
-
- // Returns the remote Cursor handle
- uint64_t get_remote_handle() {
- return (m_remote_handle);
- }
-
- // Returns the remote Cursor handle
- void set_remote_handle(uint64_t handle) {
- m_remote_handle = handle;
- }
-
- // Returns a pointer to the duplicate cache
- // TODO really required?
- DupeCache *get_dupecache() {
- return (&m_dupecache);
- }
-
- // Returns a pointer to the duplicate cache
- // TODO really required?
- const DupeCache *get_dupecache() const {
- return (&m_dupecache);
- }
-
- // Returns the current index in the dupe cache
- uint32_t get_dupecache_index() const {
- return (m_dupecache_index);
- }
-
- // Sets the current index in the dupe cache
- void set_dupecache_index(uint32_t index) {
- m_dupecache_index = index;
- }
-
- // Returns true if this cursor was never used before
- // TODO this is identical to is_nil()??
- bool is_first_use() const {
- return (m_is_first_use);
- }
-
- // Stores the current operation; needed for ham_cursor_move
- // TODO should be private
- void set_lastop(uint32_t lastop) {
- m_lastop = lastop;
- m_is_first_use = false;
- }
-
- private:
- // Checks if a btree cursor points to a key that was overwritten or erased
- // in the txn-cursor
- //
- // This is needed when moving the cursor backwards/forwards
- // and consolidating the btree and the txn-tree
- ham_status_t check_if_btree_key_is_erased_or_overwritten(Context *context);
-
- // Compares btree and txn-cursor; stores result in lastcmp
- int compare(Context *context);
-
- // Returns true if this key has duplicates
- bool has_duplicates() const {
- return (m_dupecache.get_count() > 0);
- }
-
- // Moves cursor to the first duplicate
- ham_status_t move_first_dupe(Context *context);
-
- // Moves cursor to the last duplicate
- ham_status_t move_last_dupe(Context *context);
-
- // Moves cursor to the next duplicate
- ham_status_t move_next_dupe(Context *context);
-
- // Moves cursor to the previous duplicate
- ham_status_t move_previous_dupe(Context *context);
-
- // Moves cursor to the first key
- ham_status_t move_first_key(Context *context, uint32_t flags);
-
- // Moves cursor to the last key
- ham_status_t move_last_key(Context *context, uint32_t flags);
-
- // Moves cursor to the next key
- ham_status_t move_next_key(Context *context, uint32_t flags);
-
- // Moves cursor to the previous key
- ham_status_t move_previous_key(Context *context, uint32_t flags);
-
- // Moves cursor to the first key - helper function
- ham_status_t move_first_key_singlestep(Context *context);
-
- // Moves cursor to the last key - helper function
- ham_status_t move_last_key_singlestep(Context *context);
-
- // Moves cursor to the next key - helper function
- ham_status_t move_next_key_singlestep(Context *context);
-
- // Moves cursor to the previous key - helper function
- ham_status_t move_previous_key_singlestep(Context *context);
-
- // Pointer to the Database object
- LocalDatabase *m_db;
-
- // Pointer to the Transaction
- Transaction *m_txn;
-
- // A Cursor which can walk over Transaction trees
- TransactionCursor m_txn_cursor;
-
- // A Cursor which can walk over B+trees
- BtreeCursor m_btree_cursor;
-
- // The remote database handle
- uint64_t m_remote_handle;
-
- // Linked list of all Cursors in this Database
- Cursor *m_next, *m_previous;
-
- // A cache for all duplicates of the current key. needed for
- // ham_cursor_move, ham_find and other functions. The cache is
- // used to consolidate all duplicates of btree and txn.
- DupeCache m_dupecache;
-
- /** The current position of the cursor in the cache. This is a
- * 1-based index. 0 means that the cache is not in use. */
- uint32_t m_dupecache_index;
-
- // The last operation (insert/find or move); needed for
- // ham_cursor_move. Values can be HAM_CURSOR_NEXT,
- // HAM_CURSOR_PREVIOUS or CURSOR_LOOKUP_INSERT
- uint32_t m_lastop;
-
- // The result of the last compare operation
- int m_last_cmp;
-
- // Cursor flags
- uint32_t m_flags;
-
- // true if this cursor was never used
- bool m_is_first_use;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_CURSORS_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4db/db.cc b/plugins/Dbx_kv/src/hamsterdb/src/4db/db.cc
deleted file mode 100644
index 7d6cd82929..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4db/db.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "4db/db.h"
-#include "4cursor/cursor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-Database::Database(Environment *env, DatabaseConfiguration &config)
- : m_env(env), m_config(config), m_error(0), m_context(0), m_cursor_list(0)
-{
-}
-
-ham_status_t
-Database::cursor_create(Cursor **pcursor, Transaction *txn, uint32_t flags)
-{
- try {
- Cursor *cursor = cursor_create_impl(txn, flags);
-
- /* fix the linked list of cursors */
- cursor->set_next(m_cursor_list);
- if (m_cursor_list)
- m_cursor_list->set_previous(cursor);
- m_cursor_list = cursor;
-
- if (txn)
- txn->increase_cursor_refcount();
-
- *pcursor = cursor;
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Database::cursor_clone(Cursor **pdest, Cursor *src)
-{
- try {
- Cursor *dest = cursor_clone_impl(src);
-
- // fix the linked list of cursors
- dest->set_previous(0);
- dest->set_next(m_cursor_list);
- ham_assert(m_cursor_list != 0);
- m_cursor_list->set_previous(dest);
- m_cursor_list = dest;
-
- // initialize the remaining fields
- if (src->get_txn())
- src->get_txn()->increase_cursor_refcount();
-
- *pdest = dest;
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Database::cursor_close(Cursor *cursor)
-{
- try {
- Cursor *p, *n;
-
- // first close the cursor
- cursor_close_impl(cursor);
-
- // decrease the transaction refcount; the refcount specifies how many
- // cursors are attached to the transaction
- if (cursor->get_txn())
- cursor->get_txn()->decrease_cursor_refcount();
-
- // fix the linked list of cursors
- p = cursor->get_previous();
- n = cursor->get_next();
-
- if (p)
- p->set_next(n);
- else
- m_cursor_list = n;
-
- if (n)
- n->set_previous(p);
-
- cursor->set_next(0);
- cursor->set_previous(0);
-
- delete cursor;
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-// No need to catch Exceptions - they're caught in Environment::close_db
-ham_status_t
-Database::close(uint32_t flags)
-{
- // auto-cleanup cursors?
- if (flags & HAM_AUTO_CLEANUP) {
- Cursor *cursor;
- while ((cursor = m_cursor_list))
- cursor_close(cursor);
- }
- else if (m_cursor_list) {
- ham_trace(("cannot close Database if Cursors are still open"));
- return (set_error(HAM_CURSOR_STILL_OPEN));
- }
-
- // the derived classes can now do the bulk of the work
- ham_status_t st = close_impl(flags);
- if (st)
- return (set_error(st));
-
- m_env = 0;
- return (0);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4db/db.h b/plugins/Dbx_kv/src/hamsterdb/src/4db/db.h
deleted file mode 100644
index 0290cc86b0..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4db/db.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: nothrow
- * @thread_safe: no
- */
-
-#ifndef HAM_DB_H
-#define HAM_DB_H
-
-#include "0root/root.h"
-
-#include "ham/hamsterdb_int.h"
-#include "ham/hamsterdb_ola.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/dynamic_array.h"
-#include "2config/db_config.h"
-#include "4env/env.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-// A helper structure; ham_db_t is declared in ham/hamsterdb.h as an
-// opaque C structure, but internally we use a C++ class. The ham_db_t
-// struct satisfies the C compiler, and internally we just cast the pointers.
-struct ham_db_t {
- int dummy;
-};
-
-namespace hamsterdb {
-
-class Cursor;
-struct ScanVisitor;
-
-/*
- * An abstract base class for a Database; is overwritten for local and
- * remote implementations
- */
-class Database
-{
- public:
- // Constructor
- Database(Environment *env, DatabaseConfiguration &config);
-
- virtual ~Database() {
- }
-
- // Returns the Environment pointer
- Environment *get_env() {
- return (m_env);
- }
-
- // Returns the Database's configuration
- const DatabaseConfiguration &config() const {
- return (m_config);
- }
-
- // Returns the runtime-flags - the flags are "mixed" with the flags from
- // the Environment
- uint32_t get_flags() {
- return (m_env->get_flags() | m_config.flags);
- }
-
- // Returns the database name
- uint16_t name() const {
- return (m_config.db_name);
- }
-
- // Sets the database name
- void set_name(uint16_t name) {
- m_config.db_name = name;
- }
-
- // Fills in the current metrics
- virtual void fill_metrics(ham_env_metrics_t *metrics) = 0;
-
- // Returns Database parameters (ham_db_get_parameters)
- virtual ham_status_t get_parameters(ham_parameter_t *param) = 0;
-
- // Checks Database integrity (ham_db_check_integrity)
- virtual ham_status_t check_integrity(uint32_t flags) = 0;
-
- // Returns the number of keys (ham_db_get_key_count)
- virtual ham_status_t count(Transaction *txn, bool distinct,
- uint64_t *pcount) = 0;
-
- // Scans the whole database, applies a processor function
- virtual ham_status_t scan(Transaction *txn, ScanVisitor *visitor,
- bool distinct) = 0;
-
- // Inserts a key/value pair (ham_db_insert, ham_cursor_insert)
- virtual ham_status_t insert(Cursor *cursor, Transaction *txn,
- ham_key_t *key, ham_record_t *record, uint32_t flags) = 0;
-
- // Erase a key/value pair (ham_db_erase, ham_cursor_erase)
- virtual ham_status_t erase(Cursor *cursor, Transaction *txn, ham_key_t *key,
- uint32_t flags) = 0;
-
- // Lookup of a key/value pair (ham_db_find, ham_cursor_find)
- virtual ham_status_t find(Cursor *cursor, Transaction *txn, ham_key_t *key,
- ham_record_t *record, uint32_t flags) = 0;
-
- // Creates a cursor (ham_cursor_create)
- virtual ham_status_t cursor_create(Cursor **pcursor, Transaction *txn,
- uint32_t flags);
-
- // Clones a cursor (ham_cursor_clone)
- virtual ham_status_t cursor_clone(Cursor **pdest, Cursor *src);
-
- // Returns number of duplicates (ham_cursor_get_record_count)
- virtual ham_status_t cursor_get_record_count(Cursor *cursor,
- uint32_t flags, uint32_t *pcount) = 0;
-
- // Returns position in duplicate list (ham_cursor_get_duplicate_position)
- virtual ham_status_t cursor_get_duplicate_position(Cursor *cursor,
- uint32_t *pposition) = 0;
-
- // Get current record size (ham_cursor_get_record_size)
- virtual ham_status_t cursor_get_record_size(Cursor *cursor,
- uint64_t *psize) = 0;
-
- // Overwrites the record of a cursor (ham_cursor_overwrite)
- virtual ham_status_t cursor_overwrite(Cursor *cursor,
- ham_record_t *record, uint32_t flags) = 0;
-
- // Moves a cursor, returns key and/or record (ham_cursor_move)
- virtual ham_status_t cursor_move(Cursor *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags) = 0;
-
- // Closes a cursor (ham_cursor_close)
- ham_status_t cursor_close(Cursor *cursor);
-
- // Closes the Database (ham_db_close)
- ham_status_t close(uint32_t flags);
-
- // Returns the last error code
- ham_status_t get_error() const {
- return (m_error);
- }
-
- // Sets the last error code
- ham_status_t set_error(ham_status_t e) {
- return ((m_error = e));
- }
-
- // Returns the user-provided context pointer (ham_get_context_data)
- void *get_context_data() {
- return (m_context);
- }
-
- // Sets the user-provided context pointer (ham_set_context_data)
- void set_context_data(void *ctxt) {
- m_context = ctxt;
- }
-
- // Returns the head of the linked list with all cursors
- Cursor *cursor_list() {
- return (m_cursor_list);
- }
-
- // Returns the memory buffer for the key data: the per-database buffer
- // if |txn| is null or temporary, otherwise the buffer from the |txn|
- ByteArray &key_arena(Transaction *txn) {
- return ((txn == 0 || (txn->get_flags() & HAM_TXN_TEMPORARY))
- ? m_key_arena
- : txn->key_arena());
- }
-
- // Returns the memory buffer for the record data: the per-database buffer
- // if |txn| is null or temporary, otherwise the buffer from the |txn|
- ByteArray &record_arena(Transaction *txn) {
- return ((txn == 0 || (txn->get_flags() & HAM_TXN_TEMPORARY))
- ? m_record_arena
- : txn->record_arena());
- }
-
- protected:
- // Creates a cursor; this is the actual implementation
- virtual Cursor *cursor_create_impl(Transaction *txn, uint32_t flags) = 0;
-
- // Clones a cursor; this is the actual implementation
- virtual Cursor *cursor_clone_impl(Cursor *src) = 0;
-
- // Closes a cursor; this is the actual implementation
- virtual void cursor_close_impl(Cursor *c) = 0;
-
- // Closes a database; this is the actual implementation
- virtual ham_status_t close_impl(uint32_t flags) = 0;
-
- // the current Environment
- Environment *m_env;
-
- // the configuration settings
- DatabaseConfiguration m_config;
-
- // the last error code
- ham_status_t m_error;
-
- // the user-provided context data
- void *m_context;
-
- // linked list of all cursors
- Cursor *m_cursor_list;
-
- // This is where key->data points to when returning a
- // key to the user; used if Transactions are disabled
- ByteArray m_key_arena;
-
- // This is where record->data points to when returning a
- // record to the user; used if Transactions are disabled
- ByteArray m_record_arena;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_DB_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4db/db_local.cc b/plugins/Dbx_kv/src/hamsterdb/src/4db/db_local.cc
deleted file mode 100644
index 849eb4e7aa..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4db/db_local.cc
+++ /dev/null
@@ -1,1776 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <boost/scope_exit.hpp>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1mem/mem.h"
-#include "1os/os.h"
-#include "2page/page.h"
-#include "2device/device.h"
-#include "3page_manager/page_manager.h"
-#include "3journal/journal.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_index_factory.h"
-#include "3btree/btree_cursor.h"
-#include "3btree/btree_stats.h"
-#include "4db/db_local.h"
-#include "4context/context.h"
-#include "4cursor/cursor.h"
-#include "4txn/txn_local.h"
-#include "4txn/txn_cursor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-ham_status_t
-LocalDatabase::check_insert_conflicts(Context *context, TransactionNode *node,
- ham_key_t *key, uint32_t flags)
-{
- TransactionOperation *op = 0;
-
- /*
- * pick the tree_node of this key, and walk through each operation
- * in reverse chronological order (from newest to oldest):
- * - is this op part of an aborted txn? then skip it
- * - is this op part of a committed txn? then look at the
- * operation in detail
- * - is this op part of an txn which is still active? return an error
- * because we've found a conflict
- * - if a committed txn has erased the item then there's no need
- * to continue checking older, committed txns
- */
- op = node->get_newest_op();
- while (op) {
- LocalTransaction *optxn = op->get_txn();
- if (optxn->is_aborted())
- ; /* nop */
- else if (optxn->is_committed() || context->txn == optxn) {
- /* if key was erased then it doesn't exist and can be
- * inserted without problems */
- if (op->get_flags() & TransactionOperation::kIsFlushed)
- ; /* nop */
- else if (op->get_flags() & TransactionOperation::kErase)
- return (0);
- /* if the key already exists then we can only continue if
- * we're allowed to overwrite it or to insert a duplicate */
- else if ((op->get_flags() & TransactionOperation::kInsert)
- || (op->get_flags() & TransactionOperation::kInsertOverwrite)
- || (op->get_flags() & TransactionOperation::kInsertDuplicate)) {
- if ((flags & HAM_OVERWRITE) || (flags & HAM_DUPLICATE))
- return (0);
- else
- return (HAM_DUPLICATE_KEY);
- }
- else if (!(op->get_flags() & TransactionOperation::kNop)) {
- ham_assert(!"shouldn't be here");
- return (HAM_DUPLICATE_KEY);
- }
- }
- else { /* txn is still active */
- return (HAM_TXN_CONFLICT);
- }
-
- op = op->get_previous_in_node();
- }
-
- /*
- * we've successfully checked all un-flushed transactions and there
- * were no conflicts. Now check all transactions which are already
- * flushed - basically that's identical to a btree lookup.
- *
- * however we can skip this check if we do not care about duplicates.
- */
- if ((flags & HAM_OVERWRITE)
- || (flags & HAM_DUPLICATE)
- || (get_flags() & (HAM_RECORD_NUMBER32 | HAM_RECORD_NUMBER64)))
- return (0);
-
- ham_status_t st = m_btree_index->find(context, 0, key, 0, 0, 0, flags);
- switch (st) {
- case HAM_KEY_NOT_FOUND:
- return (0);
- case HAM_SUCCESS:
- return (HAM_DUPLICATE_KEY);
- default:
- return (st);
- }
-}
-
-ham_status_t
-LocalDatabase::check_erase_conflicts(Context *context, TransactionNode *node,
- ham_key_t *key, uint32_t flags)
-{
- TransactionOperation *op = 0;
-
- /*
- * pick the tree_node of this key, and walk through each operation
- * in reverse chronological order (from newest to oldest):
- * - is this op part of an aborted txn? then skip it
- * - is this op part of a committed txn? then look at the
- * operation in detail
- * - is this op part of an txn which is still active? return an error
- * because we've found a conflict
- * - if a committed txn has erased the item then there's no need
- * to continue checking older, committed txns
- */
- op = node->get_newest_op();
- while (op) {
- Transaction *optxn = op->get_txn();
- if (optxn->is_aborted())
- ; /* nop */
- else if (optxn->is_committed() || context->txn == optxn) {
- if (op->get_flags() & TransactionOperation::kIsFlushed)
- ; /* nop */
- /* if key was erased then it doesn't exist and we fail with
- * an error */
- else if (op->get_flags() & TransactionOperation::kErase)
- return (HAM_KEY_NOT_FOUND);
- /* if the key exists then we're successful */
- else if ((op->get_flags() & TransactionOperation::kInsert)
- || (op->get_flags() & TransactionOperation::kInsertOverwrite)
- || (op->get_flags() & TransactionOperation::kInsertDuplicate)) {
- return (0);
- }
- else if (!(op->get_flags() & TransactionOperation::kNop)) {
- ham_assert(!"shouldn't be here");
- return (HAM_KEY_NOT_FOUND);
- }
- }
- else { /* txn is still active */
- return (HAM_TXN_CONFLICT);
- }
-
- op = op->get_previous_in_node();
- }
-
- /*
- * we've successfully checked all un-flushed transactions and there
- * were no conflicts. Now check all transactions which are already
- * flushed - basically that's identical to a btree lookup.
- */
- return (m_btree_index->find(context, 0, key, 0, 0, 0, flags));
-}
-
-ham_status_t
-LocalDatabase::insert_txn(Context *context, ham_key_t *key,
- ham_record_t *record, uint32_t flags, TransactionCursor *cursor)
-{
- ham_status_t st = 0;
- TransactionOperation *op;
- bool node_created = false;
-
- /* get (or create) the node for this key */
- TransactionNode *node = m_txn_index->get(key, 0);
- if (!node) {
- node = new TransactionNode(this, key);
- node_created = true;
- // TODO only store when the operation is successful?
- m_txn_index->store(node);
- }
-
- // check for conflicts of this key
- //
- // !!
- // afterwards, clear the changeset; check_insert_conflicts()
- // checks if a key already exists, and this fills the changeset
- st = check_insert_conflicts(context, node, key, flags);
- if (st) {
- if (node_created) {
- m_txn_index->remove(node);
- delete node;
- }
- return (st);
- }
-
- // append a new operation to this node
- op = node->append(context->txn, flags,
- (flags & HAM_PARTIAL) |
- ((flags & HAM_DUPLICATE)
- ? TransactionOperation::kInsertDuplicate
- : (flags & HAM_OVERWRITE)
- ? TransactionOperation::kInsertOverwrite
- : TransactionOperation::kInsert),
- lenv()->next_lsn(), key, record);
-
- // if there's a cursor then couple it to the op; also store the
- // dupecache-index in the op (it's needed for DUPLICATE_INSERT_BEFORE/NEXT) */
- if (cursor) {
- Cursor *c = cursor->get_parent();
- if (c->get_dupecache_index())
- op->set_referenced_dupe(c->get_dupecache_index());
-
- cursor->couple_to_op(op);
-
- // all other cursors need to increment their dupe index, if their
- // index is > this cursor's index
- increment_dupe_index(context, node, c, c->get_dupecache_index());
- }
-
- // append journal entry
- if (m_env->get_flags() & HAM_ENABLE_RECOVERY
- && m_env->get_flags() & HAM_ENABLE_TRANSACTIONS) {
- Journal *j = lenv()->journal();
- j->append_insert(this, context->txn, key, record,
- flags & HAM_DUPLICATE ? flags : flags | HAM_OVERWRITE,
- op->get_lsn());
- }
-
- ham_assert(st == 0);
- return (0);
-}
-
-ham_status_t
-LocalDatabase::find_txn(Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags)
-{
- ham_status_t st = 0;
- TransactionOperation *op = 0;
- bool first_loop = true;
- bool exact_is_erased = false;
-
- ByteArray *pkey_arena = &key_arena(context->txn);
- ByteArray *precord_arena = &record_arena(context->txn);
-
- ham_key_set_intflags(key,
- (ham_key_get_intflags(key) & (~BtreeKey::kApproximate)));
-
- /* get the node for this key (but don't create a new one if it does
- * not yet exist) */
- TransactionNode *node = m_txn_index->get(key, flags);
-
- /*
- * pick the node of this key, and walk through each operation
- * in reverse chronological order (from newest to oldest):
- * - is this op part of an aborted txn? then skip it
- * - is this op part of a committed txn? then look at the
- * operation in detail
- * - is this op part of an txn which is still active? return an error
- * because we've found a conflict
- * - if a committed txn has erased the item then there's no need
- * to continue checking older, committed txns
- */
-retry:
- if (node)
- op = node->get_newest_op();
- while (op) {
- Transaction *optxn = op->get_txn();
- if (optxn->is_aborted())
- ; /* nop */
- else if (optxn->is_committed() || context->txn == optxn) {
- if (op->get_flags() & TransactionOperation::kIsFlushed)
- ; /* nop */
- /* if key was erased then it doesn't exist and we can return
- * immediately
- *
- * if an approximate match is requested then move to the next
- * or previous node
- */
- else if (op->get_flags() & TransactionOperation::kErase) {
- if (first_loop
- && !(ham_key_get_intflags(key) & BtreeKey::kApproximate))
- exact_is_erased = true;
- first_loop = false;
- if (flags & HAM_FIND_LT_MATCH) {
- node = node->get_previous_sibling();
- if (!node)
- break;
- ham_key_set_intflags(key,
- (ham_key_get_intflags(key) | BtreeKey::kApproximate));
- goto retry;
- }
- else if (flags & HAM_FIND_GT_MATCH) {
- node = node->get_next_sibling();
- if (!node)
- break;
- ham_key_set_intflags(key,
- (ham_key_get_intflags(key) | BtreeKey::kApproximate));
- goto retry;
- }
- /* if a duplicate was deleted then check if there are other duplicates
- * left */
- st = HAM_KEY_NOT_FOUND;
- // TODO merge both calls
- if (cursor) {
- cursor->get_txn_cursor()->couple_to_op(op);
- cursor->couple_to_txnop();
- }
- if (op->get_referenced_dupe() > 1) {
- // not the first dupe - there are other dupes
- st = 0;
- }
- else if (op->get_referenced_dupe() == 1) {
- // check if there are other dupes
- bool is_equal;
- (void)cursor->sync(context, Cursor::kSyncOnlyEqualKeys, &is_equal);
- if (!is_equal) // TODO merge w/ line above?
- cursor->set_to_nil(Cursor::kBtree);
- st = cursor->get_dupecache_count(context) ? 0 : HAM_KEY_NOT_FOUND;
- }
- return (st);
- }
- /* if the key already exists then return its record; do not
- * return pointers to TransactionOperation::get_record, because it may be
- * flushed and the user's pointers would be invalid */
- else if ((op->get_flags() & TransactionOperation::kInsert)
- || (op->get_flags() & TransactionOperation::kInsertOverwrite)
- || (op->get_flags() & TransactionOperation::kInsertDuplicate)) {
- if (cursor) { // TODO merge those calls
- cursor->get_txn_cursor()->couple_to_op(op);
- cursor->couple_to_txnop();
- }
- // approx match? leave the loop and continue
- // with the btree
- if (ham_key_get_intflags(key) & BtreeKey::kApproximate)
- break;
- // otherwise copy the record and return
- if (record)
- return (LocalDatabase::copy_record(this, context->txn, op, record));
- return (0);
- }
- else if (!(op->get_flags() & TransactionOperation::kNop)) {
- ham_assert(!"shouldn't be here");
- return (HAM_KEY_NOT_FOUND);
- }
- }
- else { /* txn is still active */
- return (HAM_TXN_CONFLICT);
- }
-
- op = op->get_previous_in_node();
- }
-
- /*
- * if there was an approximate match: check if the btree provides
- * a better match
- *
- * TODO use alloca or ByteArray instead of Memory::allocate()
- */
- if (op && ham_key_get_intflags(key) & BtreeKey::kApproximate) {
- ham_key_t txnkey = {0};
- ham_key_t *k = op->get_node()->get_key();
- txnkey.size = k->size;
- txnkey._flags = BtreeKey::kApproximate;
- txnkey.data = Memory::allocate<uint8_t>(txnkey.size);
- memcpy(txnkey.data, k->data, txnkey.size);
-
- ham_key_set_intflags(key, 0);
-
- // the "exact match" key was erased? then don't fetch it again
- if (exact_is_erased)
- flags = flags & (~HAM_FIND_EXACT_MATCH);
-
- // now lookup in the btree
- if (cursor)
- cursor->set_to_nil(Cursor::kBtree);
- st = m_btree_index->find(context, cursor, key, pkey_arena, record,
- precord_arena, flags);
- if (st == HAM_KEY_NOT_FOUND) {
- if (!(key->flags & HAM_KEY_USER_ALLOC) && txnkey.data) {
- pkey_arena->resize(txnkey.size);
- key->data = pkey_arena->get_ptr();
- }
- if (txnkey.data) {
- ::memcpy(key->data, txnkey.data, txnkey.size);
- Memory::release(txnkey.data);
- }
- key->size = txnkey.size;
- key->_flags = txnkey._flags;
-
- if (cursor) { // TODO merge those calls
- cursor->get_txn_cursor()->couple_to_op(op);
- cursor->couple_to_txnop();
- }
- if (record)
- return (LocalDatabase::copy_record(this, context->txn, op, record));
- return (0);
- }
- else if (st)
- return (st);
- // the btree key is a direct match? then return it
- if ((!(ham_key_get_intflags(key) & BtreeKey::kApproximate))
- && (flags & HAM_FIND_EXACT_MATCH)) {
- Memory::release(txnkey.data);
- if (cursor)
- cursor->couple_to_btree();
- return (0);
- }
- // if there's an approx match in the btree: compare both keys and
- // use the one that is closer. if the btree is closer: make sure
- // that it was not erased or overwritten in a transaction
- int cmp = m_btree_index->compare_keys(key, &txnkey);
- bool use_btree = false;
- if (flags & HAM_FIND_GT_MATCH) {
- if (cmp < 0)
- use_btree = true;
- }
- else if (flags & HAM_FIND_LT_MATCH) {
- if (cmp > 0)
- use_btree = true;
- }
- else
- ham_assert(!"shouldn't be here");
-
- if (use_btree) {
- Memory::release(txnkey.data);
- // lookup again, with the same flags and the btree key.
- // this will check if the key was erased or overwritten
- // in a transaction
- st = find_txn(context, cursor, key, record, flags | HAM_FIND_EXACT_MATCH);
- if (st == 0)
- ham_key_set_intflags(key,
- (ham_key_get_intflags(key) | BtreeKey::kApproximate));
- return (st);
- }
- else { // use txn
- if (!(key->flags & HAM_KEY_USER_ALLOC) && txnkey.data) {
- pkey_arena->resize(txnkey.size);
- key->data = pkey_arena->get_ptr();
- }
- if (txnkey.data) {
- ::memcpy(key->data, txnkey.data, txnkey.size);
- Memory::release(txnkey.data);
- }
- key->size = txnkey.size;
- key->_flags = txnkey._flags;
-
- if (cursor) { // TODO merge those calls
- cursor->get_txn_cursor()->couple_to_op(op);
- cursor->couple_to_txnop();
- }
- if (record)
- return (LocalDatabase::copy_record(this, context->txn, op, record));
- return (0);
- }
- }
-
- /*
- * no approximate match:
- *
- * we've successfully checked all un-flushed transactions and there
- * were no conflicts, and we have not found the key: now try to
- * lookup the key in the btree.
- */
- return (m_btree_index->find(context, cursor, key, pkey_arena, record,
- precord_arena, flags));
-}
-
-ham_status_t
-LocalDatabase::erase_txn(Context *context, ham_key_t *key, uint32_t flags,
- TransactionCursor *cursor)
-{
- ham_status_t st = 0;
- TransactionOperation *op;
- bool node_created = false;
- Cursor *pc = 0;
- if (cursor)
- pc = cursor->get_parent();
-
- /* get (or create) the node for this key */
- TransactionNode *node = m_txn_index->get(key, 0);
- if (!node) {
- node = new TransactionNode(this, key);
- node_created = true;
- // TODO only store when the operation is successful?
- m_txn_index->store(node);
- }
-
- /* check for conflicts of this key - but only if we're not erasing a
- * duplicate key. dupes are checked for conflicts in _local_cursor_move TODO that function no longer exists */
- if (!pc || (!pc->get_dupecache_index())) {
- st = check_erase_conflicts(context, node, key, flags);
- if (st) {
- if (node_created) {
- m_txn_index->remove(node);
- delete node;
- }
- return (st);
- }
- }
-
- /* append a new operation to this node */
- op = node->append(context->txn, flags, TransactionOperation::kErase,
- lenv()->next_lsn(), key, 0);
-
- /* is this function called through ham_cursor_erase? then add the
- * duplicate ID */
- if (cursor) {
- if (pc->get_dupecache_index())
- op->set_referenced_dupe(pc->get_dupecache_index());
- }
-
- /* the current op has no cursors attached; but if there are any
- * other ops in this node and in this transaction, then they have to
- * be set to nil. This only nil's txn-cursors! */
- nil_all_cursors_in_node(context->txn, pc, node);
-
- /* in addition we nil all btree cursors which are coupled to this key */
- nil_all_cursors_in_btree(context, pc, node->get_key());
-
- /* append journal entry */
- if (m_env->get_flags() & HAM_ENABLE_RECOVERY
- && m_env->get_flags() & HAM_ENABLE_TRANSACTIONS) {
- Journal *j = lenv()->journal();
- j->append_erase(this, context->txn, key, 0,
- flags | HAM_ERASE_ALL_DUPLICATES, op->get_lsn());
- }
-
- ham_assert(st == 0);
- return (0);
-}
-
-ham_status_t
-LocalDatabase::create(Context *context, PBtreeHeader *btree_header)
-{
- /* set the flags; strip off run-time (per session) flags for the btree */
- uint32_t persistent_flags = get_flags();
- persistent_flags &= ~(HAM_CACHE_UNLIMITED
- | HAM_DISABLE_MMAP
- | HAM_ENABLE_FSYNC
- | HAM_READ_ONLY
- | HAM_ENABLE_RECOVERY
- | HAM_AUTO_RECOVERY
- | HAM_ENABLE_TRANSACTIONS);
-
- switch (m_config.key_type) {
- case HAM_TYPE_UINT8:
- m_config.key_size = 1;
- break;
- case HAM_TYPE_UINT16:
- m_config.key_size = 2;
- break;
- case HAM_TYPE_REAL32:
- case HAM_TYPE_UINT32:
- m_config.key_size = 4;
- break;
- case HAM_TYPE_REAL64:
- case HAM_TYPE_UINT64:
- m_config.key_size = 8;
- break;
- }
-
- // if we cannot fit at least 10 keys in a page then refuse to continue
- if (m_config.key_size != HAM_KEY_SIZE_UNLIMITED) {
- if (lenv()->config().page_size_bytes / (m_config.key_size + 8) < 10) {
- ham_trace(("key size too large; either increase page_size or decrease "
- "key size"));
- return (HAM_INV_KEY_SIZE);
- }
- }
-
- // fixed length records:
- //
- // if records are <= 8 bytes OR if we can fit at least 500 keys AND
- // records into the leaf then store the records in the leaf;
- // otherwise they're allocated as a blob
- if (m_config.record_size != HAM_RECORD_SIZE_UNLIMITED) {
- if (m_config.record_size <= 8
- || (m_config.record_size <= kInlineRecordThreshold
- && lenv()->config().page_size_bytes
- / (m_config.key_size + m_config.record_size) > 500)) {
- persistent_flags |= HAM_FORCE_RECORDS_INLINE;
- m_config.flags |= HAM_FORCE_RECORDS_INLINE;
- }
- }
-
- // create the btree
- m_btree_index.reset(new BtreeIndex(this, btree_header, persistent_flags,
- m_config.key_type, m_config.key_size));
-
- /* initialize the btree */
- m_btree_index->create(context, m_config.key_type, m_config.key_size,
- m_config.record_size);
-
- /* the header page is now dirty */
- Page *header = lenv()->page_manager()->fetch(context, 0);
- header->set_dirty(true);
-
- /* and the TransactionIndex */
- m_txn_index.reset(new TransactionIndex(this));
-
- return (0);
-}
-
-ham_status_t
-LocalDatabase::open(Context *context, PBtreeHeader *btree_header)
-{
- /*
- * set the database flags; strip off the persistent flags that may have been
- * set by the caller, before mixing in the persistent flags as obtained
- * from the btree.
- */
- uint32_t flags = get_flags();
- flags &= ~(HAM_CACHE_UNLIMITED
- | HAM_DISABLE_MMAP
- | HAM_ENABLE_FSYNC
- | HAM_READ_ONLY
- | HAM_ENABLE_RECOVERY
- | HAM_AUTO_RECOVERY
- | HAM_ENABLE_TRANSACTIONS);
-
- m_config.key_type = btree_header->get_key_type();
- m_config.key_size = btree_header->get_key_size();
-
- /* create the BtreeIndex */
- m_btree_index.reset(new BtreeIndex(this, btree_header,
- flags | btree_header->get_flags(),
- btree_header->get_key_type(),
- btree_header->get_key_size()));
-
- ham_assert(!(m_btree_index->get_flags() & HAM_CACHE_UNLIMITED));
- ham_assert(!(m_btree_index->get_flags() & HAM_DISABLE_MMAP));
- ham_assert(!(m_btree_index->get_flags() & HAM_ENABLE_FSYNC));
- ham_assert(!(m_btree_index->get_flags() & HAM_READ_ONLY));
- ham_assert(!(m_btree_index->get_flags() & HAM_ENABLE_RECOVERY));
- ham_assert(!(m_btree_index->get_flags() & HAM_AUTO_RECOVERY));
- ham_assert(!(m_btree_index->get_flags() & HAM_ENABLE_TRANSACTIONS));
-
- /* initialize the btree */
- m_btree_index->open();
-
- /* create the TransactionIndex - TODO only if txn's are enabled? */
- m_txn_index.reset(new TransactionIndex(this));
-
- /* merge the non-persistent database flag with the persistent flags from
- * the btree index */
- m_config.flags = config().flags | m_btree_index->get_flags();
- m_config.key_size = m_btree_index->get_key_size();
- m_config.key_type = m_btree_index->get_key_type();
- m_config.record_size = m_btree_index->get_record_size();
-
- // fetch the current record number
- if ((get_flags() & (HAM_RECORD_NUMBER32 | HAM_RECORD_NUMBER64))) {
- ham_key_t key = {};
- Cursor *c = new Cursor(this, 0, 0);
- ham_status_t st = cursor_move_impl(context, c, &key, 0, HAM_CURSOR_LAST);
- cursor_close(c);
- if (st)
- return (st == HAM_KEY_NOT_FOUND ? 0 : st);
-
- if (get_flags() & HAM_RECORD_NUMBER32)
- m_recno = *(uint32_t *)key.data;
- else
- m_recno = *(uint64_t *)key.data;
- }
-
- return (0);
-}
-
-struct MetricsVisitor : public BtreeVisitor {
- MetricsVisitor(ham_env_metrics_t *metrics)
- : m_metrics(metrics) {
- }
-
- // Specifies if the visitor modifies the node
- virtual bool is_read_only() const {
- return (true);
- }
-
- // called for each node
- virtual void operator()(Context *context, BtreeNodeProxy *node) {
- if (node->is_leaf())
- node->fill_metrics(&m_metrics->btree_leaf_metrics);
- else
- node->fill_metrics(&m_metrics->btree_internal_metrics);
- }
-
- ham_env_metrics_t *m_metrics;
-};
-
-void
-LocalDatabase::fill_metrics(ham_env_metrics_t *metrics)
-{
- metrics->btree_leaf_metrics.database_name = name();
- metrics->btree_internal_metrics.database_name = name();
-
- try {
- MetricsVisitor visitor(metrics);
- Context context(lenv(), 0, this);
- m_btree_index->visit_nodes(&context, visitor, true);
-
- // calculate the "avg" values
- BtreeStatistics::finalize_metrics(&metrics->btree_leaf_metrics);
- BtreeStatistics::finalize_metrics(&metrics->btree_internal_metrics);
- }
- catch (Exception &) {
- }
-}
-
-ham_status_t
-LocalDatabase::get_parameters(ham_parameter_t *param)
-{
- try {
- Context context(lenv(), 0, this);
-
- Page *page = 0;
- ham_parameter_t *p = param;
-
- if (p) {
- for (; p->name; p++) {
- switch (p->name) {
- case HAM_PARAM_KEY_SIZE:
- p->value = m_config.key_size;
- break;
- case HAM_PARAM_KEY_TYPE:
- p->value = m_config.key_type;
- break;
- case HAM_PARAM_RECORD_SIZE:
- p->value = m_config.record_size;
- break;
- case HAM_PARAM_FLAGS:
- p->value = (uint64_t)get_flags();
- break;
- case HAM_PARAM_DATABASE_NAME:
- p->value = (uint64_t)name();
- break;
- case HAM_PARAM_MAX_KEYS_PER_PAGE:
- p->value = 0;
- page = lenv()->page_manager()->fetch(&context,
- m_btree_index->get_root_address(),
- PageManager::kReadOnly);
- if (page) {
- BtreeNodeProxy *node = m_btree_index->get_node_from_page(page);
- p->value = node->estimate_capacity();
- }
- break;
- case HAM_PARAM_RECORD_COMPRESSION:
- p->value = 0;
- break;
- case HAM_PARAM_KEY_COMPRESSION:
- p->value = 0;
- break;
- default:
- ham_trace(("unknown parameter %d", (int)p->name));
- throw Exception(HAM_INV_PARAMETER);
- }
- }
- }
- }
- catch (Exception &ex) {
- return (ex.code);
- }
- return (0);
-}
-
-ham_status_t
-LocalDatabase::check_integrity(uint32_t flags)
-{
- try {
- Context context(lenv(), 0, this);
-
- /* purge cache if necessary */
- lenv()->page_manager()->purge_cache(&context);
-
- /* call the btree function */
- m_btree_index->check_integrity(&context, flags);
-
- /* call the txn function */
- //m_txn_index->check_integrity(flags);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
- return (0);
-}
-
-ham_status_t
-LocalDatabase::count(Transaction *htxn, bool distinct, uint64_t *pcount)
-{
- LocalTransaction *txn = dynamic_cast<LocalTransaction *>(htxn);
-
- try {
- Context context(lenv(), txn, this);
-
- /* purge cache if necessary */
- lenv()->page_manager()->purge_cache(&context);
-
- /*
- * call the btree function - this will retrieve the number of keys
- * in the btree
- */
- uint64_t keycount = m_btree_index->count(&context, distinct);
-
- /*
- * if transactions are enabled, then also sum up the number of keys
- * from the transaction tree
- */
- if (get_flags() & HAM_ENABLE_TRANSACTIONS)
- keycount += m_txn_index->count(&context, txn, distinct);
-
- *pcount = keycount;
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::scan(Transaction *txn, ScanVisitor *visitor, bool distinct)
-{
- ham_status_t st = 0;
-
- try {
- Context context(lenv(), (LocalTransaction *)txn, this);
-
- Page *page;
- ham_key_t key = {0};
-
- /* purge cache if necessary */
- lenv()->page_manager()->purge_cache(&context);
-
- /* create a cursor, move it to the first key */
- Cursor *cursor = cursor_create_impl(txn, 0);
-
- st = cursor_move_impl(&context, cursor, &key, 0, HAM_CURSOR_FIRST);
- if (st)
- goto bail;
-
- /* only transaction keys? then use a regular cursor */
- if (!cursor->is_coupled_to_btree()) {
- do {
- /* process the key */
- (*visitor)(key.data, key.size, distinct
- ? cursor->get_record_count(&context, 0)
- : 1);
- } while ((st = cursor_move_impl(&context, cursor, &key,
- 0, HAM_CURSOR_NEXT)) == 0);
- goto bail;
- }
-
- /* only btree keys? then traverse page by page */
- if (!(get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_assert(cursor->is_coupled_to_btree());
-
- do {
- // get the coupled page
- cursor->get_btree_cursor()->get_coupled_key(&page);
- BtreeNodeProxy *node = m_btree_index->get_node_from_page(page);
- // and let the btree node perform the remaining work
- node->scan(&context, visitor, 0, distinct);
- } while (cursor->get_btree_cursor()->move_to_next_page(&context) == 0);
-
- goto bail;
- }
-
- /* mixed txn/btree load? if there are btree nodes which are NOT modified
- * in transactions then move the scan to the btree node. Otherwise use
- * a regular cursor */
- while (true) {
- if (!cursor->is_coupled_to_btree())
- break;
-
- int slot;
- cursor->get_btree_cursor()->get_coupled_key(&page, &slot);
- BtreeNodeProxy *node = m_btree_index->get_node_from_page(page);
-
- /* are transactions present? then check if the next txn key is >= btree[0]
- * and <= btree[n] */
- ham_key_t *txnkey = 0;
- if (cursor->get_txn_cursor()->get_coupled_op())
- txnkey = cursor->get_txn_cursor()->get_coupled_op()->get_node()->get_key();
- // no (more) transactional keys left - process the current key, then
- // scan the remaining keys directly in the btree
- if (!txnkey) {
- /* process the key */
- (*visitor)(key.data, key.size, distinct
- ? cursor->get_record_count(&context, 0)
- : 1);
- break;
- }
-
- /* if yes: use the cursor to traverse the page */
- if (node->compare(&context, txnkey, 0) >= 0
- && node->compare(&context, txnkey, node->get_count() - 1) <= 0) {
- do {
- Page *new_page = 0;
- if (cursor->is_coupled_to_btree())
- cursor->get_btree_cursor()->get_coupled_key(&new_page);
- /* break the loop if we've reached the next page */
- if (new_page && new_page != page) {
- page = new_page;
- break;
- }
- /* process the key */
- (*visitor)(key.data, key.size, distinct
- ? cursor->get_record_count(&context, 0)
- : 1);
- } while ((st = cursor_move_impl(&context, cursor, &key,
- 0, HAM_CURSOR_NEXT)) == 0);
-
- if (st != HAM_SUCCESS)
- goto bail;
- }
- else {
- /* Otherwise traverse directly in the btree page. This is the fastest
- * code path. */
- node->scan(&context, visitor, slot, distinct);
- /* and then move to the next page */
- if (cursor->get_btree_cursor()->move_to_next_page(&context) != 0)
- break;
- }
- }
-
- /* pick up the remaining transactional keys */
- while ((st = cursor_move_impl(&context, cursor, &key,
- 0, HAM_CURSOR_NEXT)) == 0) {
- (*visitor)(key.data, key.size, distinct
- ? cursor->get_record_count(&context, 0)
- : 1);
- }
-
-bail:
- if (cursor)
- cursor_close_impl(cursor);
- return (st == HAM_KEY_NOT_FOUND ? 0 : st);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::insert(Cursor *cursor, Transaction *txn, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- Context context(lenv(), (LocalTransaction *)txn, this);
-
- try {
- if (m_config.flags & (HAM_RECORD_NUMBER32 | HAM_RECORD_NUMBER64)) {
- if (key->size == 0 && key->data == 0) {
- // ok!
- }
- else if (key->size == 0 && key->data != 0) {
- ham_trace(("for record number keys set key size to 0, "
- "key->data to null"));
- return (HAM_INV_PARAMETER);
- }
- else if (key->size != m_config.key_size) {
- ham_trace(("invalid key size (%u instead of %u)",
- key->size, m_config.key_size));
- return (HAM_INV_KEY_SIZE);
- }
- }
- else if (m_config.key_size != HAM_KEY_SIZE_UNLIMITED
- && key->size != m_config.key_size) {
- ham_trace(("invalid key size (%u instead of %u)",
- key->size, m_config.key_size));
- return (HAM_INV_KEY_SIZE);
- }
- if (m_config.record_size != HAM_RECORD_SIZE_UNLIMITED
- && record->size != m_config.record_size) {
- ham_trace(("invalid record size (%u instead of %u)",
- record->size, m_config.record_size));
- return (HAM_INV_RECORD_SIZE);
- }
-
- ByteArray *arena = &key_arena(txn);
-
- /*
- * record number: make sure that we have a valid key structure,
- * and lazy load the last used record number
- *
- * TODO TODO
- * too much duplicated code
- */
- uint64_t recno = 0;
- if (get_flags() & HAM_RECORD_NUMBER64) {
- if (flags & HAM_OVERWRITE) {
- ham_assert(key->size == sizeof(uint64_t));
- ham_assert(key->data != 0);
- recno = *(uint64_t *)key->data;
- }
- else {
- /* get the record number and increment it */
- recno = next_record_number();
- }
-
- /* allocate memory for the key */
- if (!key->data) {
- arena->resize(sizeof(uint64_t));
- key->data = arena->get_ptr();
- }
- key->size = sizeof(uint64_t);
- *(uint64_t *)key->data = recno;
-
- /* A recno key is always appended sequentially */
- flags |= HAM_HINT_APPEND;
- }
- else if (get_flags() & HAM_RECORD_NUMBER32) {
- if (flags & HAM_OVERWRITE) {
- ham_assert(key->size == sizeof(uint32_t));
- ham_assert(key->data != 0);
- recno = *(uint32_t *)key->data;
- }
- else {
- /* get the record number and increment it */
- recno = next_record_number();
- }
-
- /* allocate memory for the key */
- if (!key->data) {
- arena->resize(sizeof(uint32_t));
- key->data = arena->get_ptr();
- }
- key->size = sizeof(uint32_t);
- *(uint32_t *)key->data = (uint32_t)recno;
-
- /* A recno key is always appended sequentially */
- flags |= HAM_HINT_APPEND;
- }
-
- ham_status_t st = 0;
- LocalTransaction *local_txn = 0;
-
- /* purge cache if necessary */
- if (!txn && (get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- local_txn = begin_temp_txn();
- context.txn = local_txn;
- }
-
- st = insert_impl(&context, cursor, key, record, flags);
- return (finalize(&context, st, local_txn));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::erase(Cursor *cursor, Transaction *txn, ham_key_t *key,
- uint32_t flags)
-{
- Context context(lenv(), (LocalTransaction *)txn, this);
-
- try {
- ham_status_t st = 0;
- LocalTransaction *local_txn = 0;
-
- if (cursor) {
- if (cursor->is_nil())
- throw Exception(HAM_CURSOR_IS_NIL);
- if (cursor->is_coupled_to_txnop()) // TODO rewrite the next line, it's ugly
- key = cursor->get_txn_cursor()->get_coupled_op()->get_node()->get_key();
- else // cursor->is_coupled_to_btree()
- key = 0;
- }
-
- if (key) {
- if (m_config.key_size != HAM_KEY_SIZE_UNLIMITED
- && key->size != m_config.key_size) {
- ham_trace(("invalid key size (%u instead of %u)",
- key->size, m_config.key_size));
- return (HAM_INV_KEY_SIZE);
- }
- }
-
- if (!txn && (get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- local_txn = begin_temp_txn();
- context.txn = local_txn;
- }
-
- st = erase_impl(&context, cursor, key, flags);
- return (finalize(&context, st, local_txn));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::find(Cursor *cursor, Transaction *txn, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- Context context(lenv(), (LocalTransaction *)txn, this);
-
- try {
- ham_status_t st = 0;
-
- /* Duplicates AND Transactions require a Cursor because only
- * Cursors can build lists of duplicates.
- * TODO not exception safe - if find() throws then the cursor is not closed
- */
- if (!cursor
- && (get_flags() & (HAM_ENABLE_DUPLICATE_KEYS|HAM_ENABLE_TRANSACTIONS))) {
- Cursor *c = cursor_create_impl(txn, 0);
- st = find(c, txn, key, record, flags);
- cursor_close_impl(c);
- delete c;
- return (st);
- }
-
- if (m_config.key_size != HAM_KEY_SIZE_UNLIMITED
- && key->size != m_config.key_size) {
- ham_trace(("invalid key size (%u instead of %u)",
- key->size, m_config.key_size));
- return (HAM_INV_KEY_SIZE);
- }
-
- // cursor: reset the dupecache, set to nil
- // TODO merge both calls, only set to nil if find() was successful
- if (cursor) {
- cursor->clear_dupecache();
- cursor->set_to_nil(Cursor::kBoth);
- }
-
- st = find_impl(&context, cursor, key, record, flags);
- if (st)
- return (finalize(&context, st, 0));
-
- if (cursor) {
- // make sure that txn-cursor and btree-cursor point to the same keys
- if (get_flags() & HAM_ENABLE_TRANSACTIONS) {
- bool is_equal;
- (void)cursor->sync(&context, Cursor::kSyncOnlyEqualKeys, &is_equal);
- if (!is_equal && cursor->is_coupled_to_txnop())
- cursor->set_to_nil(Cursor::kBtree);
- }
-
- /* if the key has duplicates: build a duplicate table, then couple to the
- * first/oldest duplicate */
- if (get_flags() & HAM_ENABLE_DUPLICATES)
- cursor->clear_dupecache();
-
- if (cursor->get_dupecache_count(&context)) {
- DupeCacheLine *e = cursor->get_dupecache()->get_first_element();
- if (e->use_btree())
- cursor->couple_to_btree();
- else
- cursor->couple_to_txnop();
- cursor->couple_to_dupe(1); // 1-based index!
- if (record) { // TODO don't copy record if it was already
- // copied in find_impl
- if (cursor->is_coupled_to_txnop())
- cursor->get_txn_cursor()->copy_coupled_record(record);
- else {
- Transaction *txn = cursor->get_txn();
- st = cursor->get_btree_cursor()->move(&context, 0, 0, record,
- &record_arena(txn), 0);
- }
- }
- }
-
- /* set a flag that the cursor just completed an Insert-or-find
- * operation; this information is needed in ham_cursor_move */
- cursor->set_lastop(Cursor::kLookupOrInsert);
- }
-
- return (finalize(&context, st, 0));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-Cursor *
-LocalDatabase::cursor_create_impl(Transaction *txn, uint32_t flags)
-{
- return (new Cursor(this, txn, flags));
-}
-
-Cursor *
-LocalDatabase::cursor_clone_impl(Cursor *src)
-{
- return (new Cursor(*src));
-}
-
-ham_status_t
-LocalDatabase::cursor_get_record_count(Cursor *cursor, uint32_t flags,
- uint32_t *pcount)
-{
- try {
- Context context(lenv(), (LocalTransaction *)cursor->get_txn(), this);
- *pcount = cursor->get_record_count(&context, flags);
- return (0);
- }
- catch (Exception &ex) {
- *pcount = 0;
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::cursor_get_duplicate_position(Cursor *cursor,
- uint32_t *pposition)
-{
- try {
- *pposition = cursor->get_duplicate_position();
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::cursor_get_record_size(Cursor *cursor, uint64_t *psize)
-{
- try {
- Context context(lenv(), (LocalTransaction *)cursor->get_txn(), this);
- *psize = cursor->get_record_size(&context);
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::cursor_overwrite(Cursor *cursor,
- ham_record_t *record, uint32_t flags)
-{
- Context context(lenv(), (LocalTransaction *)cursor->get_txn(), this);
-
- try {
- ham_status_t st = 0;
- Transaction *local_txn = 0;
-
- /* purge cache if necessary */
- lenv()->page_manager()->purge_cache(&context);
-
- /* if user did not specify a transaction, but transactions are enabled:
- * create a temporary one */
- if (!cursor->get_txn() && (get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- local_txn = begin_temp_txn();
- context.txn = (LocalTransaction *)local_txn;
- }
-
- /* this function will do all the work */
- st = cursor->overwrite(&context, cursor->get_txn()
- ? cursor->get_txn()
- : local_txn,
- record, flags);
- return (finalize(&context, st, local_txn));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::cursor_move(Cursor *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- try {
- Context context(lenv(), (LocalTransaction *)cursor->get_txn(),
- this);
-
- return (cursor_move_impl(&context, cursor, key, record, flags));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-LocalDatabase::cursor_move_impl(Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags)
-{
- /* purge cache if necessary */
- lenv()->page_manager()->purge_cache(context);
-
- /*
- * if the cursor was never used before and the user requests a NEXT then
- * move the cursor to FIRST; if the user requests a PREVIOUS we set it
- * to LAST, resp.
- *
- * if the cursor was already used but is nil then we've reached EOF,
- * and a NEXT actually tries to move to the LAST key (and PREVIOUS
- * moves to FIRST)
- *
- * TODO the btree-cursor has identical code which can be removed
- */
- if (cursor->is_nil(0)) {
- if (flags & HAM_CURSOR_NEXT) {
- flags &= ~HAM_CURSOR_NEXT;
- if (cursor->is_first_use())
- flags |= HAM_CURSOR_FIRST;
- else
- flags |= HAM_CURSOR_LAST;
- }
- else if (flags & HAM_CURSOR_PREVIOUS) {
- flags &= ~HAM_CURSOR_PREVIOUS;
- if (cursor->is_first_use())
- flags |= HAM_CURSOR_LAST;
- else
- flags |= HAM_CURSOR_FIRST;
- }
- }
-
- ham_status_t st = 0;
-
- /* in non-transactional mode - just call the btree function and return */
- if (!(get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- return (cursor->get_btree_cursor()->move(context,
- key, &key_arena(context->txn),
- record, &record_arena(context->txn), flags));
- }
-
- /* everything else is handled by the cursor function */
- st = cursor->move(context, key, record, flags);
-
- /* store the direction */
- if (flags & HAM_CURSOR_NEXT)
- cursor->set_lastop(HAM_CURSOR_NEXT);
- else if (flags & HAM_CURSOR_PREVIOUS)
- cursor->set_lastop(HAM_CURSOR_PREVIOUS);
- else
- cursor->set_lastop(0);
-
- if (st) {
- if (st == HAM_KEY_ERASED_IN_TXN)
- st = HAM_KEY_NOT_FOUND;
- /* trigger a sync when the function is called again */
- cursor->set_lastop(0);
- return (st);
- }
-
- return (0);
-}
-
-void
-LocalDatabase::cursor_close_impl(Cursor *cursor)
-{
- cursor->close();
-}
-
-ham_status_t
-LocalDatabase::close_impl(uint32_t flags)
-{
- Context context(lenv(), 0, this);
-
- /* check if this database is modified by an active transaction */
- if (m_txn_index) {
- TransactionNode *node = m_txn_index->get_first();
- while (node) {
- TransactionOperation *op = node->get_newest_op();
- while (op) {
- Transaction *optxn = op->get_txn();
- if (!optxn->is_committed() && !optxn->is_aborted()) {
- ham_trace(("cannot close a Database that is modified by "
- "a currently active Transaction"));
- return (set_error(HAM_TXN_STILL_OPEN));
- }
- op = op->get_previous_in_node();
- }
- node = node->get_next_sibling();
- }
- }
-
- /* in-memory-database: free all allocated blobs */
- if (m_btree_index && m_env->get_flags() & HAM_IN_MEMORY)
- m_btree_index->release(&context);
-
- /*
- * flush all pages of this database (but not the header page,
- * it's still required and will be flushed below)
- */
- lenv()->page_manager()->close_database(&context, this);
-
- return (0);
-}
-
-void
-LocalDatabase::increment_dupe_index(Context *context, TransactionNode *node,
- Cursor *skip, uint32_t start)
-{
- Cursor *c = m_cursor_list;
-
- while (c) {
- bool hit = false;
-
- if (c == skip || c->is_nil(0))
- goto next;
-
- /* if cursor is coupled to an op in the same node: increment
- * duplicate index (if required) */
- if (c->is_coupled_to_txnop()) {
- TransactionCursor *txnc = c->get_txn_cursor();
- TransactionNode *n = txnc->get_coupled_op()->get_node();
- if (n == node)
- hit = true;
- }
- /* if cursor is coupled to the same key in the btree: increment
- * duplicate index (if required) */
- else if (c->get_btree_cursor()->points_to(context, node->get_key())) {
- hit = true;
- }
-
- if (hit) {
- if (c->get_dupecache_index() > start)
- c->set_dupecache_index(c->get_dupecache_index() + 1);
- }
-
-next:
- c = c->get_next();
- }
-}
-
-void
-LocalDatabase::nil_all_cursors_in_node(LocalTransaction *txn, Cursor *current,
- TransactionNode *node)
-{
- TransactionOperation *op = node->get_newest_op();
- while (op) {
- TransactionCursor *cursor = op->cursor_list();
- while (cursor) {
- Cursor *parent = cursor->get_parent();
- // is the current cursor to a duplicate? then adjust the
- // coupled duplicate index of all cursors which point to a duplicate
- if (current) {
- if (current->get_dupecache_index()) {
- if (current->get_dupecache_index() < parent->get_dupecache_index()) {
- parent->set_dupecache_index(parent->get_dupecache_index() - 1);
- cursor = cursor->get_coupled_next();
- continue;
- }
- else if (current->get_dupecache_index() > parent->get_dupecache_index()) {
- cursor = cursor->get_coupled_next();
- continue;
- }
- // else fall through
- }
- }
- parent->couple_to_btree(); // TODO merge these two lines
- parent->set_to_nil(Cursor::kTxn);
- // set a flag that the cursor just completed an Insert-or-find
- // operation; this information is needed in ham_cursor_move
- // (in this aspect, an erase is the same as insert/find)
- parent->set_lastop(Cursor::kLookupOrInsert);
-
- cursor = op->cursor_list();
- }
-
- op = op->get_previous_in_node();
- }
-}
-
-ham_status_t
-LocalDatabase::copy_record(LocalDatabase *db, Transaction *txn,
- TransactionOperation *op, ham_record_t *record)
-{
- ByteArray *arena = &db->record_arena(txn);
-
- if (!(record->flags & HAM_RECORD_USER_ALLOC)) {
- arena->resize(op->get_record()->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, op->get_record()->data, op->get_record()->size);
- record->size = op->get_record()->size;
- return (0);
-}
-
-void
-LocalDatabase::nil_all_cursors_in_btree(Context *context, Cursor *current,
- ham_key_t *key)
-{
- Cursor *c = m_cursor_list;
-
- /* foreach cursor in this database:
- * if it's nil or coupled to the txn: skip it
- * if it's coupled to btree AND uncoupled: compare keys; set to nil
- * if keys are identical
- * if it's uncoupled to btree AND coupled: compare keys; set to nil
- * if keys are identical; (TODO - improve performance by nil'ling
- * all other cursors from the same btree page)
- *
- * do NOT nil the current cursor - it's coupled to the key, and the
- * coupled key is still needed by the caller
- */
- while (c) {
- if (c->is_nil(0) || c == current)
- goto next;
- if (c->is_coupled_to_txnop())
- goto next;
-
- if (c->get_btree_cursor()->points_to(context, key)) {
- /* is the current cursor to a duplicate? then adjust the
- * coupled duplicate index of all cursors which point to a
- * duplicate */
- if (current) {
- if (current->get_dupecache_index()) {
- if (current->get_dupecache_index() < c->get_dupecache_index()) {
- c->set_dupecache_index(c->get_dupecache_index() - 1);
- goto next;
- }
- else if (current->get_dupecache_index() > c->get_dupecache_index()) {
- goto next;
- }
- /* else fall through */
- }
- }
- c->set_to_nil(0);
- }
-next:
- c = c->get_next();
- }
-}
-
-ham_status_t
-LocalDatabase::flush_txn_operation(Context *context, LocalTransaction *txn,
- TransactionOperation *op)
-{
- ham_status_t st = 0;
- TransactionNode *node = op->get_node();
-
- /*
- * depending on the type of the operation: actually perform the
- * operation on the btree
- *
- * if the txn-op has a cursor attached, then all (txn)cursors
- * which are coupled to this op have to be uncoupled, and their
- * parent (btree) cursor must be coupled to the btree item instead.
- */
- if ((op->get_flags() & TransactionOperation::kInsert)
- || (op->get_flags() & TransactionOperation::kInsertOverwrite)
- || (op->get_flags() & TransactionOperation::kInsertDuplicate)) {
- uint32_t additional_flag =
- (op->get_flags() & TransactionOperation::kInsertDuplicate)
- ? HAM_DUPLICATE
- : HAM_OVERWRITE;
- if (!op->cursor_list()) {
- st = m_btree_index->insert(context, 0, node->get_key(), op->get_record(),
- op->get_orig_flags() | additional_flag);
- }
- else {
- TransactionCursor *tc1 = op->cursor_list();
- Cursor *c1 = tc1->get_parent();
- /* pick the first cursor, get the parent/btree cursor and
- * insert the key/record pair in the btree. The btree cursor
- * then will be coupled to this item. */
- st = m_btree_index->insert(context, c1, node->get_key(), op->get_record(),
- op->get_orig_flags() | additional_flag);
- if (!st) {
- /* uncouple the cursor from the txn-op, and remove it */
- c1->couple_to_btree(); // TODO merge these two calls
- c1->set_to_nil(Cursor::kTxn);
-
- /* all other (btree) cursors need to be coupled to the same
- * item as the first one. */
- TransactionCursor *tc2;
- while ((tc2 = op->cursor_list())) {
- Cursor *c2 = tc2->get_parent();
- c2->get_btree_cursor()->clone(c1->get_btree_cursor());
- c2->couple_to_btree(); // TODO merge these two calls
- c2->set_to_nil(Cursor::kTxn);
- }
- }
- }
- }
- else if (op->get_flags() & TransactionOperation::kErase) {
- st = m_btree_index->erase(context, 0, node->get_key(),
- op->get_referenced_dupe(), op->get_flags());
- if (st == HAM_KEY_NOT_FOUND)
- st = 0;
- }
-
- return (st);
-}
-
-ham_status_t
-LocalDatabase::drop(Context *context)
-{
- m_btree_index->release(context);
- return (0);
-}
-
-ham_status_t
-LocalDatabase::insert_impl(Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags)
-{
- ham_status_t st = 0;
-
- lenv()->page_manager()->purge_cache(context);
-
- /*
- * if transactions are enabled: only insert the key/record pair into
- * the Transaction structure. Otherwise immediately write to the btree.
- */
- if (context->txn || m_env->get_flags() & HAM_ENABLE_TRANSACTIONS)
- st = insert_txn(context, key, record, flags, cursor
- ? cursor->get_txn_cursor()
- : 0);
- else
- st = m_btree_index->insert(context, cursor, key, record, flags);
-
- // couple the cursor to the inserted key
- if (st == 0 && cursor) {
- if (m_env->get_flags() & HAM_ENABLE_TRANSACTIONS) {
- DupeCache *dc = cursor->get_dupecache();
- // TODO required? should have happened in insert_txn
- cursor->couple_to_txnop();
- /* the cursor is coupled to the txn-op; nil the btree-cursor to
- * trigger a sync() call when fetching the duplicates */
- // TODO merge with the line above
- cursor->set_to_nil(Cursor::kBtree);
-
- /* reset the dupecache, otherwise cursor->get_dupecache_count()
- * does not update the dupecache correctly */
- dc->clear();
-
- /* if duplicate keys are enabled: set the duplicate index of
- * the new key */
- if (st == 0 && cursor->get_dupecache_count(context)) {
- TransactionOperation *op = cursor->get_txn_cursor()->get_coupled_op();
- ham_assert(op != 0);
-
- for (uint32_t i = 0; i < dc->get_count(); i++) {
- DupeCacheLine *l = dc->get_element(i);
- if (!l->use_btree() && l->get_txn_op() == op) {
- cursor->set_dupecache_index(i + 1);
- break;
- }
- }
- }
- }
- else {
- // TODO required? should have happened in BtreeInsertAction
- cursor->couple_to_btree();
- }
-
- /* set a flag that the cursor just completed an Insert-or-find
- * operation; this information is needed in ham_cursor_move */
- cursor->set_lastop(Cursor::kLookupOrInsert);
- }
-
- return (st);
-}
-
-ham_status_t
-LocalDatabase::find_impl(Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags)
-{
- /* purge cache if necessary */
- lenv()->page_manager()->purge_cache(context);
-
- /*
- * if transactions are enabled: read keys from transaction trees,
- * otherwise read immediately from disk
- */
- if (context->txn || m_env->get_flags() & HAM_ENABLE_TRANSACTIONS)
- return (find_txn(context, cursor, key, record, flags));
-
- return (m_btree_index->find(context, cursor, key, &key_arena(context->txn),
- record, &record_arena(context->txn), flags));
-}
-
-ham_status_t
-LocalDatabase::erase_impl(Context *context, Cursor *cursor, ham_key_t *key,
- uint32_t flags)
-{
- ham_status_t st = 0;
-
- /*
- * if transactions are enabled: append a 'erase key' operation into
- * the txn tree; otherwise immediately erase the key from disk
- */
- if (context->txn || m_env->get_flags() & HAM_ENABLE_TRANSACTIONS) {
- if (cursor) {
- /*
- * !!
- * we have two cases:
- *
- * 1. the cursor is coupled to a btree item (or uncoupled, but not nil)
- * and the txn_cursor is nil; in that case, we have to
- * - uncouple the btree cursor
- * - insert the erase-op for the key which is used by the btree cursor
- *
- * 2. the cursor is coupled to a txn-op; in this case, we have to
- * - insert the erase-op for the key which is used by the txn-op
- *
- * TODO clean up this whole mess. code should be like
- *
- * if (txn)
- * erase_txn(txn, cursor->get_key(), 0, cursor->get_txn_cursor());
- */
- /* case 1 described above */
- if (cursor->is_coupled_to_btree()) {
- cursor->set_to_nil(Cursor::kTxn);
- cursor->get_btree_cursor()->uncouple_from_page(context);
- st = erase_txn(context, cursor->get_btree_cursor()->get_uncoupled_key(),
- 0, cursor->get_txn_cursor());
- }
- /* case 2 described above */
- else {
- // TODO this line is ugly
- st = erase_txn(context,
- cursor->get_txn_cursor()->get_coupled_op()->get_key(),
- 0, cursor->get_txn_cursor());
- }
- }
- else {
- st = erase_txn(context, key, flags, 0);
- }
- }
- else {
- st = m_btree_index->erase(context, cursor, key, 0, flags);
- }
-
- /* on success: verify that cursor is now nil */
- if (cursor && st == 0) {
- cursor->set_to_nil(0);
- cursor->couple_to_btree(); // TODO why?
- ham_assert(cursor->get_txn_cursor()->is_nil());
- ham_assert(cursor->is_nil(0));
- cursor->clear_dupecache(); // TODO merge with set_to_nil()
- }
-
- return (st);
-}
-
-ham_status_t
-LocalDatabase::finalize(Context *context, ham_status_t status,
- Transaction *local_txn)
-{
- LocalEnvironment *env = lenv();
-
- if (status) {
- if (local_txn) {
- context->changeset.clear();
- env->txn_manager()->abort(local_txn);
- }
- return (status);
- }
-
- if (local_txn) {
- context->changeset.clear();
- env->txn_manager()->commit(local_txn);
- }
- else if (env->get_flags() & HAM_ENABLE_RECOVERY
- && !(env->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- context->changeset.flush(env->next_lsn());
- }
- return (0);
-}
-
-LocalTransaction *
-LocalDatabase::begin_temp_txn()
-{
- LocalTransaction *txn;
- ham_status_t st = lenv()->txn_begin((Transaction **)&txn, 0,
- HAM_TXN_TEMPORARY | HAM_DONT_LOCK);
- if (st)
- throw Exception(st);
- return (txn);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4db/db_local.h b/plugins/Dbx_kv/src/hamsterdb/src/4db/db_local.h
deleted file mode 100644
index 0d08bd79ed..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4db/db_local.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: no
- */
-
-#ifndef HAM_DB_LOCAL_H
-#define HAM_DB_LOCAL_H
-
-#include "0root/root.h"
-
-#include <limits>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/scoped_ptr.h"
-#include "3btree/btree_index.h"
-#include "4txn/txn_local.h"
-#include "4db/db.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class TransactionNode;
-class TransactionIndex;
-class TransactionCursor;
-class TransactionOperation;
-class LocalEnvironment;
-class LocalTransaction;
-
-template<typename T>
-class RecordNumberFixture;
-
-//
-// The database implementation for local file access
-//
-class LocalDatabase : public Database {
- public:
- enum {
- // The default threshold for inline records
- kInlineRecordThreshold = 32
- };
-
- // Constructor
- LocalDatabase(Environment *env, DatabaseConfiguration &config)
- : Database(env, config), m_recno(0), m_cmp_func(0) {
- }
-
- // Returns the btree index
- BtreeIndex *btree_index() {
- return (m_btree_index.get());
- }
-
- // Returns the transactional index
- TransactionIndex *txn_index() {
- return (m_txn_index.get());
- }
-
- // Returns the LocalEnvironment instance
- LocalEnvironment *lenv() {
- return ((LocalEnvironment *)m_env);
- }
-
- // Creates a new Database
- ham_status_t create(Context *context, PBtreeHeader *btree_header);
-
- // Opens an existing Database
- ham_status_t open(Context *context, PBtreeHeader *btree_header);
-
- // Erases this Database
- ham_status_t drop(Context *context);
-
- // Fills in the current metrics
- virtual void fill_metrics(ham_env_metrics_t *metrics);
-
- // Returns Database parameters (ham_db_get_parameters)
- virtual ham_status_t get_parameters(ham_parameter_t *param);
-
- // Checks Database integrity (ham_db_check_integrity)
- virtual ham_status_t check_integrity(uint32_t flags);
-
- // Returns the number of keys
- virtual ham_status_t count(Transaction *txn, bool distinct,
- uint64_t *pcount);
-
- // Scans the whole database, applies a processor function
- virtual ham_status_t scan(Transaction *txn, ScanVisitor *visitor,
- bool distinct);
-
- // Inserts a key/value pair (ham_db_insert, ham_cursor_insert)
- virtual ham_status_t insert(Cursor *cursor, Transaction *txn,
- ham_key_t *key, ham_record_t *record, uint32_t flags);
-
- // Erase a key/value pair (ham_db_erase, ham_cursor_erase)
- virtual ham_status_t erase(Cursor *cursor, Transaction *txn, ham_key_t *key,
- uint32_t flags);
-
- // Lookup of a key/value pair (ham_db_find, ham_cursor_find)
- virtual ham_status_t find(Cursor *cursor, Transaction *txn, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
- // Returns number of duplicates (ham_cursor_get_record_count)
- virtual ham_status_t cursor_get_record_count(Cursor *cursor, uint32_t flags,
- uint32_t *pcount);
-
- // Returns position in duplicate list (ham_cursor_get_duplicate_position)
- virtual ham_status_t cursor_get_duplicate_position(Cursor *cursor,
- uint32_t *pposition);
-
- // Get current record size (ham_cursor_get_record_size)
- virtual ham_status_t cursor_get_record_size(Cursor *cursor,
- uint64_t *psize);
-
- // Overwrites the record of a cursor (ham_cursor_overwrite)
- virtual ham_status_t cursor_overwrite(Cursor *cursor,
- ham_record_t *record, uint32_t flags);
-
- // Moves a cursor, returns key and/or record (ham_cursor_move)
- virtual ham_status_t cursor_move(Cursor *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
- // Inserts a key/record pair in a txn node; if cursor is not NULL it will
- // be attached to the new txn_op structure
- // TODO this should be private
- ham_status_t insert_txn(Context *context, ham_key_t *key,
- ham_record_t *record, uint32_t flags,
- TransactionCursor *cursor);
-
- // Returns the default comparison function
- ham_compare_func_t compare_func() {
- return (m_cmp_func);
- }
-
- // Sets the default comparison function (ham_db_set_compare_func)
- ham_status_t set_compare_func(ham_compare_func_t f) {
- if (m_config.key_type != HAM_TYPE_CUSTOM) {
- ham_trace(("ham_set_compare_func only allowed for HAM_TYPE_CUSTOM "
- "databases!"));
- return (HAM_INV_PARAMETER);
- }
- m_cmp_func = f;
- return (0);
- }
-
- // Flushes a TransactionOperation to the btree
- // TODO should be private
- ham_status_t flush_txn_operation(Context *context, LocalTransaction *txn,
- TransactionOperation *op);
-
- protected:
- friend class Cursor;
-
- // Copies the ham_record_t structure from |op| into |record|
- static ham_status_t copy_record(LocalDatabase *db, Transaction *txn,
- TransactionOperation *op, ham_record_t *record);
-
- // Creates a cursor; this is the actual implementation
- virtual Cursor *cursor_create_impl(Transaction *txn, uint32_t flags);
-
- // Clones a cursor; this is the actual implementation
- virtual Cursor *cursor_clone_impl(Cursor *src);
-
- // Closes a cursor; this is the actual implementation
- virtual void cursor_close_impl(Cursor *c);
-
- // Closes a database; this is the actual implementation
- virtual ham_status_t close_impl(uint32_t flags);
-
- private:
- friend struct DbFixture;
- friend struct HamsterdbFixture;
- friend struct ExtendedKeyFixture;
- friend class RecordNumberFixture<uint32_t>;
- friend class RecordNumberFixture<uint64_t>;
-
- // Erases a key/record pair from a txn; on success, cursor will be set to
- // nil
- ham_status_t erase_txn(Context *context, ham_key_t *key, uint32_t flags,
- TransactionCursor *cursor);
-
- // Lookup of a key/record pair in the Transaction index and in the btree,
- // if transactions are disabled/not successful; copies the
- // record into |record|. Also performs approx. matching.
- ham_status_t find_txn(Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags);
-
- // Moves a cursor, returns key and/or record (ham_cursor_move)
- ham_status_t cursor_move_impl(Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags);
-
- // The actual implementation of insert()
- ham_status_t insert_impl(Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags);
-
- // The actual implementation of find()
- ham_status_t find_impl(Context *context, Cursor *cursor,
- ham_key_t *key, ham_record_t *record, uint32_t flags);
-
- // The actual implementation of erase()
- ham_status_t erase_impl(Context *context, Cursor *cursor,
- ham_key_t *key, uint32_t flags);
-
- // Finalizes an operation by committing or aborting the |local_txn|
- // and clearing or flushing the Changeset.
- // Returns |status|.
- ham_status_t finalize(Context *context, ham_status_t status,
- Transaction *local_txn);
-
- // Begins a new temporary Transaction
- LocalTransaction *begin_temp_txn();
-
- // returns the next record number
- uint64_t next_record_number() {
- m_recno++;
- if (m_config.flags & HAM_RECORD_NUMBER32
- && m_recno > std::numeric_limits<uint32_t>::max())
- throw Exception(HAM_LIMITS_REACHED);
- else if (m_recno == 0)
- throw Exception(HAM_LIMITS_REACHED);
- return (m_recno);
- }
-
- // Checks if an insert operation conflicts with another txn; this is the
- // case if the same key is modified by another active txn.
- ham_status_t check_insert_conflicts(Context *context, TransactionNode *node,
- ham_key_t *key, uint32_t flags);
-
- // Checks if an erase operation conflicts with another txn; this is the
- // case if the same key is modified by another active txn.
- ham_status_t check_erase_conflicts(Context *context, TransactionNode *node,
- ham_key_t *key, uint32_t flags);
-
- // Increments dupe index of all cursors with a dupe index > |start|;
- // only cursor |skip| is ignored
- void increment_dupe_index(Context *context, TransactionNode *node,
- Cursor *skip, uint32_t start);
-
- // Sets all cursors attached to a TransactionNode to nil
- void nil_all_cursors_in_node(LocalTransaction *txn, Cursor *current,
- TransactionNode *node);
-
- // Sets all cursors to nil if they point to |key| in the btree index
- void nil_all_cursors_in_btree(Context *context, Cursor *current,
- ham_key_t *key);
-
- // the current record number
- uint64_t m_recno;
-
- // the btree index
- ScopedPtr<BtreeIndex> m_btree_index;
-
- // the transaction index
- ScopedPtr<TransactionIndex> m_txn_index;
-
- // the comparison function
- ham_compare_func_t m_cmp_func;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_DB_LOCAL_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4db/db_remote.cc b/plugins/Dbx_kv/src/hamsterdb/src/4db/db_remote.cc
deleted file mode 100644
index 58bd49f4db..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4db/db_remote.cc
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifdef HAM_ENABLE_REMOTE
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/scoped_ptr.h"
-#include "2protobuf/protocol.h"
-#include "4db/db_remote.h"
-#include "4env/env_remote.h"
-#include "4txn/txn_remote.h"
-#include "4cursor/cursor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-ham_status_t
-RemoteDatabase::get_parameters(ham_parameter_t *param)
-{
- try {
- RemoteEnvironment *env = renv();
-
- Protocol request(Protocol::DB_GET_PARAMETERS_REQUEST);
- request.mutable_db_get_parameters_request()->set_db_handle(m_remote_handle);
-
- ham_parameter_t *p = param;
- if (p) {
- for (; p->name; p++)
- request.mutable_db_get_parameters_request()->add_names(p->name);
- }
-
- ScopedPtr<Protocol> reply(env->perform_request(&request));
-
- ham_assert(reply->has_db_get_parameters_reply());
-
- ham_status_t st = reply->db_get_parameters_reply().status();
- if (st)
- throw Exception(st);
-
- p = param;
- while (p && p->name) {
- switch (p->name) {
- case HAM_PARAM_FLAGS:
- ham_assert(reply->db_get_parameters_reply().has_flags());
- p->value = reply->db_get_parameters_reply().flags();
- break;
- case HAM_PARAM_KEY_SIZE:
- ham_assert(reply->db_get_parameters_reply().has_key_size());
- p->value = reply->db_get_parameters_reply().key_size();
- break;
- case HAM_PARAM_RECORD_SIZE:
- ham_assert(reply->db_get_parameters_reply().has_record_size());
- p->value = reply->db_get_parameters_reply().record_size();
- break;
- case HAM_PARAM_KEY_TYPE:
- ham_assert(reply->db_get_parameters_reply().has_key_type());
- p->value = reply->db_get_parameters_reply().key_type();
- break;
- case HAM_PARAM_DATABASE_NAME:
- ham_assert(reply->db_get_parameters_reply().has_dbname());
- p->value = reply->db_get_parameters_reply().dbname();
- break;
- case HAM_PARAM_MAX_KEYS_PER_PAGE:
- ham_assert(reply->db_get_parameters_reply().has_keys_per_page());
- p->value = reply->db_get_parameters_reply().keys_per_page();
- break;
- default:
- ham_trace(("unknown parameter %d", (int)p->name));
- break;
- }
- p++;
- }
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::check_integrity(uint32_t flags)
-{
- try {
- RemoteEnvironment *env = renv();
-
- Protocol request(Protocol::DB_CHECK_INTEGRITY_REQUEST);
- request.mutable_db_check_integrity_request()->set_db_handle(m_remote_handle);
- request.mutable_db_check_integrity_request()->set_flags(flags);
-
- std::auto_ptr<Protocol> reply(env->perform_request(&request));
-
- ham_assert(reply->has_db_check_integrity_reply());
-
- return (reply->db_check_integrity_reply().status());
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::count(Transaction *htxn, bool distinct, uint64_t *pcount)
-{
- try {
- RemoteEnvironment *env = renv();
- RemoteTransaction *txn = dynamic_cast<RemoteTransaction *>(htxn);
-
- SerializedWrapper request;
- request.id = kDbGetKeyCountRequest;
- request.db_count_request.db_handle = m_remote_handle;
- request.db_count_request.txn_handle = txn
- ? txn->get_remote_handle()
- : 0;
- request.db_count_request.distinct = distinct;
-
- SerializedWrapper reply;
- env->perform_request(&request, &reply);
-
- ham_assert(reply.id == kDbGetKeyCountReply);
-
- ham_status_t st = reply.db_count_reply.status;
- if (st)
- return (st);
-
- *pcount = reply.db_count_reply.keycount;
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::insert(Cursor *cursor, Transaction *htxn, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- try {
- bool send_key = true;
- RemoteEnvironment *env = renv();
- RemoteTransaction *txn = dynamic_cast<RemoteTransaction *>(htxn);
-
- ByteArray *arena = &key_arena(txn);
-
- /* recno: do not send the key */
- if (get_flags() & HAM_RECORD_NUMBER32) {
- send_key = false;
- if (!key->data) {
- arena->resize(sizeof(uint32_t));
- key->data = arena->get_ptr();
- key->size = sizeof(uint32_t);
- }
- }
- else if (get_flags() & HAM_RECORD_NUMBER64) {
- send_key = false;
- if (!key->data) {
- arena->resize(sizeof(uint64_t));
- key->data = arena->get_ptr();
- key->size = sizeof(uint64_t);
- }
- }
-
- SerializedWrapper request;
- SerializedWrapper reply;
-
- if (cursor) {
- SerializedWrapper request;
- request.id = kCursorInsertRequest;
- request.cursor_insert_request.cursor_handle = cursor->get_remote_handle();
- request.cursor_insert_request.flags = flags;
- if (send_key) {
- request.cursor_insert_request.has_key = true;
- request.cursor_insert_request.key.has_data = true;
- request.cursor_insert_request.key.data.size = key->size;
- request.cursor_insert_request.key.data.value = (uint8_t *)key->data;
- request.cursor_insert_request.key.flags = key->flags;
- request.cursor_insert_request.key.intflags = key->_flags;
- }
- if (record) {
- request.cursor_insert_request.has_record = true;
- request.cursor_insert_request.record.has_data = true;
- request.cursor_insert_request.record.data.size = record->size;
- request.cursor_insert_request.record.data.value = (uint8_t *)record->data;
- request.cursor_insert_request.record.flags = record->flags;
- request.cursor_insert_request.record.partial_size = record->partial_size;
- request.cursor_insert_request.record.partial_offset = record->partial_offset;
- }
-
- env->perform_request(&request, &reply);
-
- ham_assert(reply.id == kCursorInsertReply);
-
- ham_status_t st = reply.cursor_insert_reply.status;
- if (st)
- return (st);
-
- if (reply.cursor_insert_reply.has_key) {
- ham_assert(key->size == reply.cursor_insert_reply.key.data.size);
- ham_assert(key->data != 0);
- ::memcpy(key->data, reply.cursor_insert_reply.key.data.value, key->size);
- }
- }
- else {
- request.id = kDbInsertRequest;
- request.db_insert_request.db_handle = m_remote_handle;
- request.db_insert_request.txn_handle = txn ? txn->get_remote_handle() : 0;
- request.db_insert_request.flags = flags;
- if (key && !(get_flags() & (HAM_RECORD_NUMBER32 | HAM_RECORD_NUMBER64))) {
- request.db_insert_request.has_key = true;
- request.db_insert_request.key.has_data = true;
- request.db_insert_request.key.data.size = key->size;
- request.db_insert_request.key.data.value = (uint8_t *)key->data;
- request.db_insert_request.key.flags = key->flags;
- request.db_insert_request.key.intflags = key->_flags;
- }
- if (record) {
- request.db_insert_request.has_record = true;
- request.db_insert_request.record.has_data = true;
- request.db_insert_request.record.data.size = record->size;
- request.db_insert_request.record.data.value = (uint8_t *)record->data;
- request.db_insert_request.record.flags = record->flags;
- request.db_insert_request.record.partial_size = record->partial_size;
- request.db_insert_request.record.partial_offset = record->partial_offset;
- }
-
- env->perform_request(&request, &reply);
-
- ham_assert(reply.id == kDbInsertReply);
-
- ham_status_t st = reply.db_insert_reply.status;
- if (st)
- return (st);
-
- if (reply.db_insert_reply.has_key) {
- ham_assert(key->data != 0);
- ham_assert(key->size == reply.db_insert_reply.key.data.size);
- ::memcpy(key->data, reply.db_insert_reply.key.data.value, key->size);
- }
- }
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::erase(Cursor *cursor, Transaction *htxn, ham_key_t *key,
- uint32_t flags)
-{
- try {
- if (cursor) {
- SerializedWrapper request;
- request.id = kCursorEraseRequest;
- request.cursor_erase_request.cursor_handle = cursor->get_remote_handle();
- request.cursor_erase_request.flags = flags;
-
- SerializedWrapper reply;
- renv()->perform_request(&request, &reply);
- ham_assert(reply.id == kCursorEraseReply);
- return (reply.cursor_erase_reply.status);
- }
-
- RemoteEnvironment *env = renv();
- RemoteTransaction *txn = dynamic_cast<RemoteTransaction *>(htxn);
-
- SerializedWrapper request;
- request.id = kDbEraseRequest;
- request.db_erase_request.db_handle = m_remote_handle;
- request.db_erase_request.txn_handle = txn ? txn->get_remote_handle() : 0;
- request.db_erase_request.flags = flags;
- request.db_erase_request.key.has_data = true;
- request.db_erase_request.key.data.size = key->size;
- request.db_erase_request.key.data.value = (uint8_t *)key->data;
- request.db_erase_request.key.flags = key->flags;
- request.db_erase_request.key.intflags = key->_flags;
-
- SerializedWrapper reply;
- env->perform_request(&request, &reply);
-
- ham_assert(reply.id == kDbEraseReply);
-
- return (reply.db_erase_reply.status);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::find(Cursor *cursor, Transaction *htxn, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- try {
- if (cursor && !htxn)
- htxn = cursor->get_txn();
-
- RemoteEnvironment *env = renv();
- RemoteTransaction *txn = dynamic_cast<RemoteTransaction *>(htxn);
-
- SerializedWrapper request;
- request.id = kDbFindRequest;
- request.db_find_request.db_handle = m_remote_handle;
- request.db_find_request.cursor_handle = cursor ? cursor->get_remote_handle() : 0;
- request.db_find_request.txn_handle = txn ? txn->get_remote_handle() : 0;
- request.db_find_request.flags = flags;
- request.db_find_request.key.has_data = true;
- request.db_find_request.key.data.size = key->size;
- request.db_find_request.key.data.value = (uint8_t *)key->data;
- request.db_find_request.key.flags = key->flags;
- request.db_find_request.key.intflags = key->_flags;
- if (record) {
- request.db_find_request.has_record = true;
- request.db_find_request.record.has_data = true;
- request.db_find_request.record.data.size = record->size;
- request.db_find_request.record.data.value = (uint8_t *)record->data;
- request.db_find_request.record.flags = record->flags;
- request.db_find_request.record.partial_size = record->partial_size;
- request.db_find_request.record.partial_offset = record->partial_offset;
- }
-
- SerializedWrapper reply;
- env->perform_request(&request, &reply);
- ham_assert(reply.id == kDbFindReply);
-
- ByteArray *pkey_arena = &key_arena(txn);
- ByteArray *rec_arena = &record_arena(txn);
-
- ham_status_t st = reply.db_find_reply.status;
- if (st == 0) {
- /* approx. matching: need to copy the _flags and the key data! */
- if (reply.db_find_reply.has_key) {
- ham_assert(key);
- key->_flags = reply.db_find_reply.key.intflags;
- key->size = (uint16_t)reply.db_find_reply.key.data.size;
- if (!(key->flags & HAM_KEY_USER_ALLOC)) {
- pkey_arena->resize(key->size);
- key->data = pkey_arena->get_ptr();
- }
- ::memcpy(key->data, (void *)reply.db_find_reply.key.data.value,
- key->size);
- }
- if (record && reply.db_find_reply.has_record) {
- record->size = reply.db_find_reply.record.data.size;
- if (!(record->flags & HAM_RECORD_USER_ALLOC)) {
- rec_arena->resize(record->size);
- record->data = rec_arena->get_ptr();
- }
- ::memcpy(record->data, (void *)reply.db_find_reply.record.data.value,
- record->size);
- }
- }
- return (st);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-Cursor *
-RemoteDatabase::cursor_create_impl(Transaction *htxn, uint32_t flags)
-{
- RemoteTransaction *txn = dynamic_cast<RemoteTransaction *>(htxn);
-
- SerializedWrapper request;
- request.id = kCursorCreateRequest;
- request.cursor_create_request.db_handle = m_remote_handle;
- request.cursor_create_request.txn_handle = txn
- ? txn->get_remote_handle()
- : 0;
- request.cursor_create_request.flags = flags;
-
- SerializedWrapper reply;
- renv()->perform_request(&request, &reply);
- ham_assert(reply.id == kCursorCreateReply);
- ham_status_t st = reply.cursor_create_reply.status;
- if (st)
- return (0);
-
- Cursor *c = new Cursor((LocalDatabase *)this); // TODO this cast is evil!!
- c->set_remote_handle(reply.cursor_create_reply.cursor_handle);
- return (c);
-}
-
-Cursor *
-RemoteDatabase::cursor_clone_impl(Cursor *src)
-{
- SerializedWrapper request;
- request.id = kCursorCloneRequest;
- request.cursor_clone_request.cursor_handle = src->get_remote_handle();
-
- SerializedWrapper reply;
- renv()->perform_request(&request, &reply);
- ham_assert(reply.id == kCursorCloneReply);
- ham_status_t st = reply.cursor_clone_reply.status;
- if (st)
- return (0);
-
- Cursor *c = new Cursor(src->get_db());
- c->set_remote_handle(reply.cursor_clone_reply.cursor_handle);
- return (c);
-}
-
-ham_status_t
-RemoteDatabase::cursor_get_record_count(Cursor *cursor, uint32_t flags,
- uint32_t *pcount)
-{
- try {
- RemoteEnvironment *env = renv();
-
- SerializedWrapper request;
- request.id = kCursorGetRecordCountRequest;
- request.cursor_get_record_count_request.cursor_handle =
- cursor->get_remote_handle();
- request.cursor_get_record_count_request.flags = flags;
-
- SerializedWrapper reply;
- env->perform_request(&request, &reply);
- ham_assert(reply.id == kCursorGetRecordCountReply);
-
- ham_status_t st = reply.cursor_get_record_count_reply.status;
- if (st == 0)
- *pcount = reply.cursor_get_record_count_reply.count;
- else
- *pcount = 0;
- return (st);
- }
- catch (Exception &ex) {
- *pcount = 0;
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::cursor_get_duplicate_position(Cursor *cursor,
- uint32_t *pposition)
-{
- try {
- RemoteEnvironment *env = renv();
-
- SerializedWrapper request;
- request.id = kCursorGetDuplicatePositionRequest;
- request.cursor_get_duplicate_position_request.cursor_handle =
- cursor->get_remote_handle();
-
- SerializedWrapper reply;
- env->perform_request(&request, &reply);
- ham_assert(reply.id == kCursorGetDuplicatePositionReply);
-
- ham_status_t st = reply.cursor_get_duplicate_position_reply.status;
- if (st == 0)
- *pposition = reply.cursor_get_duplicate_position_reply.position;
- return (st);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::cursor_get_record_size(Cursor *cursor, uint64_t *psize)
-{
- try {
- RemoteEnvironment *env = renv();
-
- SerializedWrapper request;
- request.id = kCursorGetRecordSizeRequest;
- request.cursor_get_record_size_request.cursor_handle =
- cursor->get_remote_handle();
-
- SerializedWrapper reply;
- env->perform_request(&request, &reply);
- ham_assert(reply.id == kCursorGetRecordSizeReply);
-
- ham_status_t st = reply.cursor_get_record_size_reply.status;
- if (st == 0)
- *psize = reply.cursor_get_record_size_reply.size;
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::cursor_overwrite(Cursor *cursor,
- ham_record_t *record, uint32_t flags)
-{
- try {
- RemoteEnvironment *env = renv();
-
- SerializedWrapper request;
- request.id = kCursorOverwriteRequest;
- request.cursor_overwrite_request.cursor_handle = cursor->get_remote_handle();
- request.cursor_overwrite_request.flags = flags;
-
- if (record->size > 0) {
- request.cursor_overwrite_request.record.has_data = true;
- request.cursor_overwrite_request.record.data.size = record->size;
- request.cursor_overwrite_request.record.data.value = (uint8_t *)record->data;
- }
- request.cursor_overwrite_request.record.flags = record->flags;
- request.cursor_overwrite_request.record.partial_size = record->partial_size;
- request.cursor_overwrite_request.record.partial_offset = record->partial_offset;
-
- SerializedWrapper reply;
- env->perform_request(&request, &reply);
- ham_assert(reply.id == kCursorOverwriteReply);
-
- return (reply.cursor_overwrite_reply.status);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-RemoteDatabase::cursor_move(Cursor *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- try {
- RemoteEnvironment *env = renv();
-
- RemoteTransaction *txn = dynamic_cast<RemoteTransaction *>(cursor->get_txn());
- ByteArray *pkey_arena = &key_arena(txn);
- ByteArray *prec_arena = &record_arena(txn);
-
- Protocol request(Protocol::CURSOR_MOVE_REQUEST);
- request.mutable_cursor_move_request()->set_cursor_handle(cursor->get_remote_handle());
- request.mutable_cursor_move_request()->set_flags(flags);
- if (key)
- Protocol::assign_key(request.mutable_cursor_move_request()->mutable_key(),
- key, false);
- if (record)
- Protocol::assign_record(request.mutable_cursor_move_request()->mutable_record(),
- record, false);
-
- ScopedPtr<Protocol> reply(env->perform_request(&request));
-
- ham_assert(reply->has_cursor_move_reply() != 0);
-
- ham_status_t st = reply->cursor_move_reply().status();
- if (st)
- return (st);
-
- /* modify key/record, but make sure that USER_ALLOC is respected! */
- if (reply->cursor_move_reply().has_key()) {
- ham_assert(key);
- key->_flags = reply->cursor_move_reply().key().intflags();
- key->size = (uint16_t)reply->cursor_move_reply().key().data().size();
- if (!(key->flags & HAM_KEY_USER_ALLOC)) {
- pkey_arena->resize(key->size);
- key->data = pkey_arena->get_ptr();
- }
- memcpy(key->data, (void *)&reply->cursor_move_reply().key().data()[0],
- key->size);
- }
-
- /* same for the record */
- if (reply->cursor_move_reply().has_record()) {
- ham_assert(record);
- record->size = reply->cursor_move_reply().record().data().size();
- if (!(record->flags & HAM_RECORD_USER_ALLOC)) {
- prec_arena->resize(record->size);
- record->data = prec_arena->get_ptr();
- }
- memcpy(record->data, (void *)&reply->cursor_move_reply().record().data()[0],
- record->size);
- }
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-void
-RemoteDatabase::cursor_close_impl(Cursor *cursor)
-{
- SerializedWrapper request;
- request.id = kCursorCloseRequest;
- request.cursor_close_request.cursor_handle = cursor->get_remote_handle();
-
- SerializedWrapper reply;
- renv()->perform_request(&request, &reply);
- ham_assert(reply.id == kCursorCloseReply);
-}
-
-ham_status_t
-RemoteDatabase::close_impl(uint32_t flags)
-{
- RemoteEnvironment *env = renv();
-
- // do not set HAM_DONT_LOCK over the network
- flags &= ~HAM_DONT_LOCK;
-
- Protocol request(Protocol::DB_CLOSE_REQUEST);
- request.mutable_db_close_request()->set_db_handle(m_remote_handle);
- request.mutable_db_close_request()->set_flags(flags);
-
- ScopedPtr<Protocol> reply(env->perform_request(&request));
-
- ham_assert(reply->has_db_close_reply());
-
- ham_status_t st = reply->db_close_reply().status();
- if (st == 0)
- m_remote_handle = 0;
-
- return (st);
-}
-
-
-} // namespace hamsterdb
-
-#endif // HAM_ENABLE_REMOTE
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4db/db_remote.h b/plugins/Dbx_kv/src/hamsterdb/src/4db/db_remote.h
deleted file mode 100644
index 1a492418bc..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4db/db_remote.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_DB_REMOTE_H
-#define HAM_DB_REMOTE_H
-
-#ifdef HAM_ENABLE_REMOTE
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "4db/db.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-class Environment;
-class RemoteEnvironment;
-
-/*
- * The database implementation for remote file access
- */
-class RemoteDatabase : public Database
-{
- public:
- RemoteDatabase(Environment *env, DatabaseConfiguration config,
- uint64_t remote_handle)
- : Database(env, config), m_remote_handle(remote_handle) {
- }
-
- // Fills in the current metrics
- virtual void fill_metrics(ham_env_metrics_t *metrics) { }
-
- // Returns Database parameters (ham_db_get_parameters)
- virtual ham_status_t get_parameters(ham_parameter_t *param);
-
- // Checks Database integrity (ham_db_check_integrity)
- virtual ham_status_t check_integrity(uint32_t flags);
-
- // Returns the number of keys
- virtual ham_status_t count(Transaction *txn, bool distinct,
- uint64_t *pcount);
-
- // Scans the whole database, applies a processor function
- virtual ham_status_t scan(Transaction *txn, ScanVisitor *visitor,
- bool distinct) {
- return (HAM_NOT_IMPLEMENTED);
- }
-
- // Inserts a key/value pair (ham_db_insert, ham_cursor_insert)
- virtual ham_status_t insert(Cursor *cursor, Transaction *txn,
- ham_key_t *key, ham_record_t *record, uint32_t flags);
-
- // Erase a key/value pair (ham_db_erase, ham_cursor_erase)
- virtual ham_status_t erase(Cursor *cursor, Transaction *txn, ham_key_t *key,
- uint32_t flags);
-
- // Lookup of a key/value pair (ham_db_find, ham_cursor_find)
- virtual ham_status_t find(Cursor *cursor, Transaction *txn, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
- // Returns number of duplicates (ham_cursor_get_record_count)
- virtual ham_status_t cursor_get_record_count(Cursor *cursor, uint32_t flags,
- uint32_t *pcount);
-
- // Returns position in duplicate list (ham_cursor_get_duplicate_position)
- virtual ham_status_t cursor_get_duplicate_position(Cursor *cursor,
- uint32_t *pposition);
-
- // Get current record size (ham_cursor_get_record_size)
- virtual ham_status_t cursor_get_record_size(Cursor *cursor,
- uint64_t *psize);
-
- // Overwrites the record of a cursor (ham_cursor_overwrite)
- virtual ham_status_t cursor_overwrite(Cursor *cursor,
- ham_record_t *record, uint32_t flags);
-
- // Moves a cursor, returns key and/or record (ham_cursor_move)
- virtual ham_status_t cursor_move(Cursor *cursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags);
-
- protected:
- // Creates a cursor; this is the actual implementation
- virtual Cursor *cursor_create_impl(Transaction *txn, uint32_t flags);
-
- // Clones a cursor; this is the actual implementation
- virtual Cursor *cursor_clone_impl(Cursor *src);
-
- // Closes a cursor; this is the actual implementation
- virtual void cursor_close_impl(Cursor *c);
-
- // Closes a database; this is the actual implementation
- virtual ham_status_t close_impl(uint32_t flags);
-
- private:
- // Returns the RemoteEnvironment instance
- RemoteEnvironment *renv() {
- return ((RemoteEnvironment *)m_env);
- }
-
- // the remote database handle
- uint64_t m_remote_handle;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_ENABLE_REMOTE */
-
-#endif /* HAM_DB_REMOTE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env.cc b/plugins/Dbx_kv/src/hamsterdb/src/4env/env.cc
deleted file mode 100644
index 6e3a494f6d..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env.cc
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "4db/db.h"
-#include "4env/env.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-namespace hamsterdb {
-
-ham_status_t
-Environment::create()
-{
- try {
- return (do_create());
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::open()
-{
- try {
- return (do_open());
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::get_database_names(uint16_t *names, uint32_t *count)
-{
- try {
- ScopedLock lock(m_mutex);
- return (do_get_database_names(names, count));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::get_parameters(ham_parameter_t *param)
-{
- try {
- ScopedLock lock(m_mutex);
- return (do_get_parameters(param));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::flush(uint32_t flags)
-{
- try {
- ScopedLock lock(m_mutex);
- return (do_flush(flags));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::create_db(Database **pdb, DatabaseConfiguration &config,
- const ham_parameter_t *param)
-{
- try {
- ScopedLock lock(m_mutex);
-
- ham_status_t st = do_create_db(pdb, config, param);
-
- // on success: store the open database in the environment's list of
- // opened databases
- if (st == 0) {
- m_database_map[config.db_name] = *pdb;
- /* flush the environment to make sure that the header page is written
- * to disk */
- if (st == 0)
- st = do_flush(0);
- }
- else {
- if (*pdb)
- (void)ham_db_close((ham_db_t *)*pdb, HAM_DONT_LOCK);
- }
- return (st);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::open_db(Database **pdb, DatabaseConfiguration &config,
- const ham_parameter_t *param)
-{
- try {
- ScopedLock lock(m_mutex);
-
- /* make sure that this database is not yet open */
- if (m_database_map.find(config.db_name) != m_database_map.end())
- return (HAM_DATABASE_ALREADY_OPEN);
-
- ham_status_t st = do_open_db(pdb, config, param);
-
- // on success: store the open database in the environment's list of
- // opened databases
- if (st == 0)
- m_database_map[config.db_name] = *pdb;
- else {
- if (*pdb)
- (void)ham_db_close((ham_db_t *)*pdb, HAM_DONT_LOCK);
- }
- return (st);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::rename_db(uint16_t oldname, uint16_t newname, uint32_t flags)
-{
- try {
- ScopedLock lock(m_mutex);
- return (do_rename_db(oldname, newname, flags));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::erase_db(uint16_t dbname, uint32_t flags)
-{
- try {
- ScopedLock lock(m_mutex);
- return (do_erase_db(dbname, flags));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::close_db(Database *db, uint32_t flags)
-{
- ham_status_t st = 0;
-
- try {
- ScopedLock lock;
- if (!(flags & HAM_DONT_LOCK))
- lock = ScopedLock(m_mutex);
-
- uint16_t dbname = db->name();
-
- // flush committed Transactions
- st = do_flush(HAM_FLUSH_COMMITTED_TRANSACTIONS);
- if (st)
- return (st);
-
- st = db->close(flags);
- if (st)
- return (st);
-
- m_database_map.erase(dbname);
- delete db;
-
- /* in-memory database: make sure that a database with the same name
- * can be re-created */
- if (m_config.flags & HAM_IN_MEMORY)
- do_erase_db(dbname, 0);
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::txn_begin(Transaction **ptxn, const char *name, uint32_t flags)
-{
- try {
- ScopedLock lock;
- if (!(flags & HAM_DONT_LOCK))
- lock = ScopedLock(m_mutex);
-
- if (!(m_config.flags & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("transactions are disabled (see HAM_ENABLE_TRANSACTIONS)"));
- return (HAM_INV_PARAMETER);
- }
-
- *ptxn = do_txn_begin(name, flags);
- return (0);
- }
- catch (Exception &ex) {
- *ptxn = 0;
- return (ex.code);
- }
-}
-
-std::string
-Environment::txn_get_name(Transaction *txn)
-{
- try {
- ScopedLock lock(m_mutex);
- return (txn->get_name());
- }
- catch (Exception &) {
- return ("");
- }
-}
-
-ham_status_t
-Environment::txn_commit(Transaction *txn, uint32_t flags)
-{
- try {
- ScopedLock lock(m_mutex);
- return (do_txn_commit(txn, flags));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::txn_abort(Transaction *txn, uint32_t flags)
-{
- try {
- ScopedLock lock(m_mutex);
- return (do_txn_abort(txn, flags));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::close(uint32_t flags)
-{
- ham_status_t st = 0;
-
- try {
- ScopedLock lock(m_mutex);
-
- /* auto-abort (or commit) all pending transactions */
- if (m_txn_manager.get()) {
- Transaction *t;
-
- while ((t = m_txn_manager->get_oldest_txn())) {
- if (!t->is_aborted() && !t->is_committed()) {
- if (flags & HAM_TXN_AUTO_COMMIT)
- st = m_txn_manager->commit(t, 0);
- else /* if (flags & HAM_TXN_AUTO_ABORT) */
- st = m_txn_manager->abort(t, 0);
- if (st)
- return (st);
- }
-
- m_txn_manager->flush_committed_txns();
- }
- }
-
- /* flush all remaining transactions */
- if (m_txn_manager)
- m_txn_manager->flush_committed_txns();
-
- /* close all databases */
- Environment::DatabaseMap::iterator it = m_database_map.begin();
- while (it != m_database_map.end()) {
- Environment::DatabaseMap::iterator it2 = it; it++;
- Database *db = it2->second;
- if (flags & HAM_AUTO_CLEANUP)
- st = close_db(db, flags | HAM_DONT_LOCK);
- else
- st = db->close(flags);
- if (st)
- return (st);
- }
- m_database_map.clear();
-
- return (do_close(flags));
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-ham_status_t
-Environment::fill_metrics(ham_env_metrics_t *metrics)
-{
- try {
- ScopedLock lock(m_mutex);
- do_fill_metrics(metrics);
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-EnvironmentTest
-Environment::test()
-{
- return (EnvironmentTest(m_config));
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env.h b/plugins/Dbx_kv/src/hamsterdb/src/4env/env.h
deleted file mode 100644
index c0841151df..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: nothrow
- * @thread_safe: yes
- */
-
-#ifndef HAM_ENV_H
-#define HAM_ENV_H
-
-#include "0root/root.h"
-
-#include <map>
-#include <string>
-
-#include "ham/hamsterdb_int.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1base/mutex.h"
-#include "1base/scoped_ptr.h"
-#include "2config/db_config.h"
-#include "2config/env_config.h"
-#include "4txn/txn.h"
-#include "4env/env_test.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-// A helper structure; ham_env_t is declared in ham/hamsterdb.h as an
-// opaque C structure, but internally we use a C++ class. The ham_env_t
-// struct satisfies the C compiler, and internally we just cast the pointers.
-struct ham_env_t {
- int dummy;
-};
-
-namespace hamsterdb {
-
-class Database;
-class Transaction;
-
-//
-// The Environment is the "root" of all hamsterdb objects. It's a container
-// for multiple databases and transactions.
-//
-// This class provides exception handling and locking mechanisms, then
-// dispatches all calls to LocalEnvironment or RemoteEnvironment.
-//
-class Environment
-{
- public:
- // Constructor
- Environment(EnvironmentConfiguration &config)
- : m_config(config) {
- }
-
- virtual ~Environment() {
- }
-
- // Returns the flags which were set when creating/opening the Environment
- uint32_t get_flags() const {
- return (m_config.flags);
- }
-
- // Returns the Environment's configuration
- const EnvironmentConfiguration &config() const {
- return (m_config);
- }
-
- // Returns this Environment's mutex
- Mutex &mutex() {
- return (m_mutex);
- }
-
- // Creates a new Environment (ham_env_create)
- ham_status_t create();
-
- // Opens a new Environment (ham_env_open)
- ham_status_t open();
-
- // Returns all database names (ham_env_get_database_names)
- ham_status_t get_database_names(uint16_t *names, uint32_t *count);
-
- // Returns environment parameters and flags (ham_env_get_parameters)
- ham_status_t get_parameters(ham_parameter_t *param);
-
- // Flushes the environment and its databases to disk (ham_env_flush)
- ham_status_t flush(uint32_t flags);
-
- // Creates a new database in the environment (ham_env_create_db)
- ham_status_t create_db(Database **db, DatabaseConfiguration &config,
- const ham_parameter_t *param);
-
- // Opens an existing database in the environment (ham_env_open_db)
- ham_status_t open_db(Database **db, DatabaseConfiguration &config,
- const ham_parameter_t *param);
-
- // Renames a database in the Environment (ham_env_rename_db)
- ham_status_t rename_db(uint16_t oldname, uint16_t newname, uint32_t flags);
-
- // Erases (deletes) a database from the Environment (ham_env_erase_db)
- ham_status_t erase_db(uint16_t name, uint32_t flags);
-
- // Closes an existing database in the environment (ham_db_close)
- ham_status_t close_db(Database *db, uint32_t flags);
-
- // Begins a new transaction (ham_txn_begin)
- ham_status_t txn_begin(Transaction **ptxn, const char *name,
- uint32_t flags);
-
- // Returns the name of a Transaction
- std::string txn_get_name(Transaction *txn);
-
- // Commits a transaction (ham_txn_commit)
- ham_status_t txn_commit(Transaction *txn, uint32_t flags);
-
- // Commits a transaction (ham_txn_abort)
- ham_status_t txn_abort(Transaction *txn, uint32_t flags);
-
- // Closes the Environment (ham_env_close)
- ham_status_t close(uint32_t flags);
-
- // Fills in the current metrics
- ham_status_t fill_metrics(ham_env_metrics_t *metrics);
-
- // Returns a test object
- EnvironmentTest test();
-
- protected:
- // Creates a new Environment (ham_env_create)
- virtual ham_status_t do_create() = 0;
-
- // Opens a new Environment (ham_env_open)
- virtual ham_status_t do_open() = 0;
-
- // Returns all database names (ham_env_get_database_names)
- virtual ham_status_t do_get_database_names(uint16_t *names,
- uint32_t *count) = 0;
-
- // Returns environment parameters and flags (ham_env_get_parameters)
- virtual ham_status_t do_get_parameters(ham_parameter_t *param) = 0;
-
- // Flushes the environment and its databases to disk (ham_env_flush)
- virtual ham_status_t do_flush(uint32_t flags) = 0;
-
- // Creates a new database in the environment (ham_env_create_db)
- virtual ham_status_t do_create_db(Database **db,
- DatabaseConfiguration &config,
- const ham_parameter_t *param) = 0;
-
- // Opens an existing database in the environment (ham_env_open_db)
- virtual ham_status_t do_open_db(Database **db,
- DatabaseConfiguration &config,
- const ham_parameter_t *param) = 0;
-
- // Renames a database in the Environment (ham_env_rename_db)
- virtual ham_status_t do_rename_db(uint16_t oldname, uint16_t newname,
- uint32_t flags) = 0;
-
- // Erases (deletes) a database from the Environment (ham_env_erase_db)
- virtual ham_status_t do_erase_db(uint16_t name, uint32_t flags) = 0;
-
- // Begins a new transaction (ham_txn_begin)
- virtual Transaction *do_txn_begin(const char *name, uint32_t flags) = 0;
-
- // Commits a transaction (ham_txn_commit)
- virtual ham_status_t do_txn_commit(Transaction *txn, uint32_t flags) = 0;
-
- // Commits a transaction (ham_txn_abort)
- virtual ham_status_t do_txn_abort(Transaction *txn, uint32_t flags) = 0;
-
- // Closes the Environment (ham_env_close)
- virtual ham_status_t do_close(uint32_t flags) = 0;
-
- // Fills in the current metrics
- virtual void do_fill_metrics(ham_env_metrics_t *metrics) const = 0;
-
- protected:
- // A mutex to serialize access to this Environment
- Mutex m_mutex;
-
- // The Environment's configuration
- EnvironmentConfiguration m_config;
-
- // The Transaction manager; can be 0
- ScopedPtr<TransactionManager> m_txn_manager;
-
- // A map of all opened Databases
- typedef std::map<uint16_t, Database *> DatabaseMap;
- DatabaseMap m_database_map;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_ENV_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_header.h b/plugins/Dbx_kv/src/hamsterdb/src/4env/env_header.h
deleted file mode 100644
index 56c5a5fcb8..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_header.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_ENV_HEADER_H
-#define HAM_ENV_HEADER_H
-
-#include "0root/root.h"
-
-#include <map>
-#include <string>
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "2page/page.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-#include "1base/packstart.h"
-
-/**
- * the persistent file header
- */
-typedef HAM_PACK_0 struct HAM_PACK_1
-{
- /** magic cookie - always "ham\0" */
- uint8_t _magic[4];
-
- /** version information - major, minor, rev, file */
- uint8_t _version[4];
-
- /** reserved */
- uint64_t _reserved1;
-
- /** size of the page */
- uint32_t _page_size;
-
- /** maximum number of databases for this environment */
- uint16_t _max_databases;
-
- /** PRO: for storing journal compression algorithm */
- uint8_t _journal_compression;
-
- /** reserved */
- uint8_t _reserved3;
-
- /** blob id of the PageManager's state */
- uint64_t _page_manager_blobid;
-
- /*
- * following here:
- *
- * 1. the private data of the index btree(s)
- * -> see get_btree_header()
- */
-} HAM_PACK_2 PEnvironmentHeader;
-
-#include "1base/packstop.h"
-
-class EnvironmentHeader
-{
- public:
- // Constructor
- EnvironmentHeader(Page *page)
- : m_header_page(page) {
- }
-
- // Sets the 'magic' field of a file header
- void set_magic(uint8_t m1, uint8_t m2, uint8_t m3, uint8_t m4) {
- get_header()->_magic[0] = m1;
- get_header()->_magic[1] = m2;
- get_header()->_magic[2] = m3;
- get_header()->_magic[3] = m4;
- }
-
- // Returns true if the magic matches
- bool verify_magic(uint8_t m1, uint8_t m2, uint8_t m3, uint8_t m4) {
- if (get_header()->_magic[0] != m1)
- return (false);
- if (get_header()->_magic[1] != m2)
- return (false);
- if (get_header()->_magic[2] != m3)
- return (false);
- if (get_header()->_magic[3] != m4)
- return (false);
- return (true);
- }
-
- // Returns byte |i| of the 'version'-header
- uint8_t get_version(int i) {
- return (get_header()->_version[i]);
- }
-
- // Sets the version of a file header
- void set_version(uint8_t major, uint8_t minor, uint8_t revision,
- uint8_t file) {
- get_header()->_version[0] = major;
- get_header()->_version[1] = minor;
- get_header()->_version[2] = revision;
- get_header()->_version[3] = file;
- }
-
- // Returns get the maximum number of databases for this file
- uint16_t get_max_databases() {
- return (get_header()->_max_databases);
- }
-
- // Sets the maximum number of databases for this file
- void set_max_databases(uint16_t max_databases) {
- get_header()->_max_databases = max_databases;
- }
-
- // Returns the page size from the header page
- uint32_t page_size() {
- return (get_header()->_page_size);
- }
-
- // Sets the page size in the header page
- void set_page_size(uint32_t page_size) {
- get_header()->_page_size = page_size;
- }
-
- // Returns the PageManager's blob id
- uint64_t get_page_manager_blobid() {
- return (get_header()->_page_manager_blobid);
- }
-
- // Sets the page size in the header page
- void set_page_manager_blobid(uint64_t blobid) {
- get_header()->_page_manager_blobid = blobid;
- }
-
- // Returns the Journal compression configuration
- int get_journal_compression(int *level) {
- *level = get_header()->_journal_compression & 0x0f;
- return (get_header()->_journal_compression >> 4);
- }
-
- // Sets the Journal compression configuration
- void set_journal_compression(int algorithm, int level) {
- get_header()->_journal_compression = (algorithm << 4) | level;
- }
-
- // Returns the header page with persistent configuration settings
- Page *get_header_page() {
- return (m_header_page);
- }
-
- private:
- // Returns a pointer to the header data
- PEnvironmentHeader *get_header() {
- return ((PEnvironmentHeader *)(m_header_page->get_payload()));
- }
-
- // The header page of the Environment
- Page *m_header_page;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_ENV_HEADER_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local.cc b/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local.cc
deleted file mode 100644
index 7ba0280d7a..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local.cc
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1os/os.h"
-#include "2device/device_factory.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_stats.h"
-#include "3blob_manager/blob_manager_factory.h"
-#include "3journal/journal.h"
-#include "3page_manager/page_manager.h"
-#include "4db/db.h"
-#include "4txn/txn.h"
-#include "4txn/txn_local.h"
-#include "4env/env_local.h"
-#include "4cursor/cursor.h"
-#include "4context/context.h"
-#include "4txn/txn_cursor.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-namespace hamsterdb {
-
-LocalEnvironment::LocalEnvironment(EnvironmentConfiguration &config)
- : Environment(config)
-{
-}
-
-void
-LocalEnvironment::recover(uint32_t flags)
-{
- Context context(this);
-
- ham_status_t st = 0;
- m_journal.reset(new Journal(this));
-
- ham_assert(get_flags() & HAM_ENABLE_RECOVERY);
-
- try {
- m_journal->open();
- }
- catch (Exception &ex) {
- if (ex.code == HAM_FILE_NOT_FOUND) {
- m_journal->create();
- return;
- }
- }
-
- /* success - check if we need recovery */
- if (!m_journal->is_empty()) {
- if (flags & HAM_AUTO_RECOVERY) {
- m_journal->recover((LocalTransactionManager *)m_txn_manager.get());
- }
- else {
- st = HAM_NEED_RECOVERY;
- goto bail;
- }
- }
-
-bail:
- /* in case of errors: close log and journal, but do not delete the files */
- if (st) {
- m_journal->close(true);
- throw Exception(st);
- }
-
- /* reset the page manager */
- m_page_manager->reset(&context);
-}
-
-PBtreeHeader *
-LocalEnvironment::btree_header(int i)
-{
- PBtreeHeader *d = (PBtreeHeader *)
- (m_header->get_header_page()->get_payload()
- + sizeof(PEnvironmentHeader));
- return (d + i);
-}
-
-LocalEnvironmentTest
-LocalEnvironment::test()
-{
- return (LocalEnvironmentTest(this));
-}
-
-ham_status_t
-LocalEnvironment::do_create()
-{
- if (m_config.flags & HAM_IN_MEMORY)
- m_config.flags |= HAM_DISABLE_RECLAIM_INTERNAL;
-
- /* initialize the device if it does not yet exist */
- m_blob_manager.reset(BlobManagerFactory::create(this, m_config.flags));
- m_device.reset(DeviceFactory::create(m_config));
- if (m_config.flags & HAM_ENABLE_TRANSACTIONS)
- m_txn_manager.reset(new LocalTransactionManager(this));
-
- /* create the file */
- m_device->create();
-
- /* allocate the header page */
- Page *page = new Page(m_device.get());
- page->alloc(Page::kTypeHeader, m_config.page_size_bytes);
- ::memset(page->get_data(), 0, m_config.page_size_bytes);
- page->set_type(Page::kTypeHeader);
- page->set_dirty(true);
-
- m_header.reset(new EnvironmentHeader(page));
-
- /* initialize the header */
- m_header->set_magic('H', 'A', 'M', '\0');
- m_header->set_version(HAM_VERSION_MAJ, HAM_VERSION_MIN, HAM_VERSION_REV,
- HAM_FILE_VERSION);
- m_header->set_page_size(m_config.page_size_bytes);
- m_header->set_max_databases(m_config.max_databases);
-
- /* load page manager after setting up the blobmanager and the device! */
- m_page_manager.reset(new PageManager(this));
-
- /* create a logfile and a journal (if requested) */
- if (get_flags() & HAM_ENABLE_RECOVERY) {
- m_journal.reset(new Journal(this));
- m_journal->create();
- }
-
- /* flush the header page - this will write through disk if logging is
- * enabled */
- if (get_flags() & HAM_ENABLE_RECOVERY)
- m_header->get_header_page()->flush();
-
- return (0);
-}
-
-ham_status_t
-LocalEnvironment::do_open()
-{
- ham_status_t st = 0;
-
- Context context(this);
-
- /* Initialize the device if it does not yet exist. The page size will
- * be filled in later (at this point in time, it's still unknown) */
- m_blob_manager.reset(BlobManagerFactory::create(this, m_config.flags));
- m_device.reset(DeviceFactory::create(m_config));
-
- /* open the file */
- m_device->open();
-
- if (m_config.flags & HAM_ENABLE_TRANSACTIONS)
- m_txn_manager.reset(new LocalTransactionManager(this));
-
- /*
- * read the database header
- *
- * !!!
- * now this is an ugly problem - the database header spans one page, but
- * what's the size of this page? chances are good that it's the default
- * page-size, but we really can't be sure.
- *
- * read 512 byte and extract the "real" page size, then read
- * the real page.
- */
- {
- Page *page = 0;
- uint8_t hdrbuf[512];
-
- /*
- * in here, we're going to set up a faked headerpage for the
- * duration of this call; BE VERY CAREFUL: we MUST clean up
- * at the end of this section or we'll be in BIG trouble!
- */
- Page fakepage(m_device.get());
- fakepage.set_data((PPageData *)hdrbuf);
-
- /* create the configuration object */
- m_header.reset(new EnvironmentHeader(&fakepage));
-
- /*
- * now fetch the header data we need to get an estimate of what
- * the database is made of really.
- */
- m_device->read(0, hdrbuf, sizeof(hdrbuf));
-
- m_config.page_size_bytes = m_header->page_size();
-
- /** check the file magic */
- if (!m_header->verify_magic('H', 'A', 'M', '\0')) {
- ham_log(("invalid file type"));
- st = HAM_INV_FILE_HEADER;
- goto fail_with_fake_cleansing;
- }
-
- /* check the database version; everything with a different file version
- * is incompatible */
- if (m_header->get_version(3) != HAM_FILE_VERSION) {
- ham_log(("invalid file version"));
- st = HAM_INV_FILE_VERSION;
- goto fail_with_fake_cleansing;
- }
- else if (m_header->get_version(0) == 1 &&
- m_header->get_version(1) == 0 &&
- m_header->get_version(2) <= 9) {
- ham_log(("invalid file version; < 1.0.9 is not supported"));
- st = HAM_INV_FILE_VERSION;
- goto fail_with_fake_cleansing;
- }
-
- st = 0;
-
-fail_with_fake_cleansing:
-
- /* undo the headerpage fake first! */
- fakepage.set_data(0);
- m_header.reset(0);
-
- /* exit when an error was signaled */
- if (st) {
- if (m_device->is_open())
- m_device->close();
- return (st);
- }
-
- /* now read the "real" header page and store it in the Environment */
- page = new Page(m_device.get());
- page->fetch(0);
- m_header.reset(new EnvironmentHeader(page));
- }
-
- /* load page manager after setting up the blobmanager and the device! */
- m_page_manager.reset(new PageManager(this));
-
- /* check if recovery is required */
- if (get_flags() & HAM_ENABLE_RECOVERY)
- recover(m_config.flags);
-
- /* load the state of the PageManager */
- if (m_header->get_page_manager_blobid() != 0)
- m_page_manager->initialize(m_header->get_page_manager_blobid());
-
- return (0);
-}
-
-ham_status_t
-LocalEnvironment::do_get_database_names(uint16_t *names, uint32_t *count)
-{
- uint16_t name;
- uint32_t i = 0;
- uint32_t max_names = 0;
-
- max_names = *count;
- *count = 0;
-
- /* copy each database name to the array */
- ham_assert(m_header->get_max_databases() > 0);
- for (i = 0; i < m_header->get_max_databases(); i++) {
- name = btree_header(i)->get_dbname();
- if (name == 0)
- continue;
-
- if (*count >= max_names)
- return (HAM_LIMITS_REACHED);
-
- names[(*count)++] = name;
- }
-
- return 0;
-}
-
-ham_status_t
-LocalEnvironment::do_get_parameters(ham_parameter_t *param)
-{
- ham_parameter_t *p = param;
-
- if (p) {
- for (; p->name; p++) {
- switch (p->name) {
- case HAM_PARAM_CACHE_SIZE:
- p->value = m_config.cache_size_bytes;
- break;
- case HAM_PARAM_PAGE_SIZE:
- p->value = m_config.page_size_bytes;
- break;
- case HAM_PARAM_MAX_DATABASES:
- p->value = m_header->get_max_databases();
- break;
- case HAM_PARAM_FLAGS:
- p->value = get_flags();
- break;
- case HAM_PARAM_FILEMODE:
- p->value = m_config.file_mode;
- break;
- case HAM_PARAM_FILENAME:
- if (m_config.filename.size())
- p->value = (uint64_t)(PTR_TO_U64(m_config.filename.c_str()));
- else
- p->value = 0;
- break;
- case HAM_PARAM_LOG_DIRECTORY:
- if (m_config.log_filename.size())
- p->value = (uint64_t)(PTR_TO_U64(m_config.log_filename.c_str()));
- else
- p->value = 0;
- break;
- case HAM_PARAM_JOURNAL_SWITCH_THRESHOLD:
- p->value = m_config.journal_switch_threshold;
- break;
- case HAM_PARAM_JOURNAL_COMPRESSION:
- p->value = 0;
- break;
- case HAM_PARAM_POSIX_FADVISE:
- p->value = m_config.posix_advice;
- break;
- default:
- ham_trace(("unknown parameter %d", (int)p->name));
- return (HAM_INV_PARAMETER);
- }
- }
- }
-
- return (0);
-}
-
-ham_status_t
-LocalEnvironment::do_flush(uint32_t flags)
-{
- Context context(this, 0, 0);
-
- /* flush all committed transactions */
- if (m_txn_manager)
- m_txn_manager->flush_committed_txns(&context);
-
- if (flags & HAM_FLUSH_COMMITTED_TRANSACTIONS || get_flags() & HAM_IN_MEMORY)
- return (0);
-
- /* flush the header page */
- m_header->get_header_page()->flush();
-
- /* flush all open pages to disk */
- m_page_manager->flush(false);
-
- /* flush the device - this usually causes a fsync() */
- m_device->flush();
- return (0);
-}
-
-ham_status_t
-LocalEnvironment::do_create_db(Database **pdb, DatabaseConfiguration &config,
- const ham_parameter_t *param)
-{
- if (get_flags() & HAM_READ_ONLY) {
- ham_trace(("cannot create database in a read-only environment"));
- return (HAM_WRITE_PROTECTED);
- }
-
- if (param) {
- for (; param->name; param++) {
- switch (param->name) {
- case HAM_PARAM_RECORD_COMPRESSION:
- ham_trace(("Record compression is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- case HAM_PARAM_KEY_COMPRESSION:
- ham_trace(("Key compression is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- case HAM_PARAM_KEY_TYPE:
- config.key_type = (uint16_t)param->value;
- break;
- case HAM_PARAM_KEY_SIZE:
- if (param->value != 0) {
- if (param->value > 0xffff) {
- ham_trace(("invalid key size %u - must be < 0xffff"));
- return (HAM_INV_KEY_SIZE);
- }
- if (config.flags & HAM_RECORD_NUMBER32) {
- if (param->value > 0 && param->value != sizeof(uint32_t)) {
- ham_trace(("invalid key size %u - must be 4 for "
- "HAM_RECORD_NUMBER32 databases",
- (unsigned)param->value));
- return (HAM_INV_KEY_SIZE);
- }
- }
- if (config.flags & HAM_RECORD_NUMBER64) {
- if (param->value > 0 && param->value != sizeof(uint64_t)) {
- ham_trace(("invalid key size %u - must be 8 for "
- "HAM_RECORD_NUMBER64 databases",
- (unsigned)param->value));
- return (HAM_INV_KEY_SIZE);
- }
- }
- config.key_size = (uint16_t)param->value;
- }
- break;
- case HAM_PARAM_RECORD_SIZE:
- config.record_size = (uint32_t)param->value;
- break;
- default:
- ham_trace(("invalid parameter 0x%x (%d)", param->name, param->name));
- return (HAM_INV_PARAMETER);
- }
- }
- }
-
- if (config.flags & HAM_RECORD_NUMBER32) {
- if (config.key_type == HAM_TYPE_UINT8
- || config.key_type == HAM_TYPE_UINT16
- || config.key_type == HAM_TYPE_UINT64
- || config.key_type == HAM_TYPE_REAL32
- || config.key_type == HAM_TYPE_REAL64) {
- ham_trace(("HAM_RECORD_NUMBER32 not allowed in combination with "
- "fixed length type"));
- return (HAM_INV_PARAMETER);
- }
- config.key_type = HAM_TYPE_UINT32;
- }
- else if (config.flags & HAM_RECORD_NUMBER64) {
- if (config.key_type == HAM_TYPE_UINT8
- || config.key_type == HAM_TYPE_UINT16
- || config.key_type == HAM_TYPE_UINT32
- || config.key_type == HAM_TYPE_REAL32
- || config.key_type == HAM_TYPE_REAL64) {
- ham_trace(("HAM_RECORD_NUMBER64 not allowed in combination with "
- "fixed length type"));
- return (HAM_INV_PARAMETER);
- }
- config.key_type = HAM_TYPE_UINT64;
- }
-
- uint32_t mask = HAM_FORCE_RECORDS_INLINE
- | HAM_FLUSH_WHEN_COMMITTED
- | HAM_ENABLE_DUPLICATE_KEYS
- | HAM_RECORD_NUMBER32
- | HAM_RECORD_NUMBER64;
- if (config.flags & ~mask) {
- ham_trace(("invalid flags(s) 0x%x", config.flags & ~mask));
- return (HAM_INV_PARAMETER);
- }
-
- /* create a new Database object */
- LocalDatabase *db = new LocalDatabase(this, config);
-
- Context context(this, 0, db);
-
- /* check if this database name is unique */
- uint16_t dbi;
- for (uint32_t i = 0; i < m_header->get_max_databases(); i++) {
- uint16_t name = btree_header(i)->get_dbname();
- if (!name)
- continue;
- if (name == config.db_name) {
- delete db;
- return (HAM_DATABASE_ALREADY_EXISTS);
- }
- }
-
- /* find a free slot in the PBtreeHeader array and store the name */
- for (dbi = 0; dbi < m_header->get_max_databases(); dbi++) {
- uint16_t name = btree_header(dbi)->get_dbname();
- if (!name) {
- btree_header(dbi)->set_dbname(config.db_name);
- break;
- }
- }
- if (dbi == m_header->get_max_databases()) {
- delete db;
- return (HAM_LIMITS_REACHED);
- }
-
- mark_header_page_dirty(&context);
-
- /* initialize the Database */
- ham_status_t st = db->create(&context, btree_header(dbi));
- if (st) {
- delete db;
- return (st);
- }
-
- /* force-flush the changeset */
- if (get_flags() & HAM_ENABLE_RECOVERY)
- context.changeset.flush(next_lsn());
-
- *pdb = db;
- return (0);
-}
-
-ham_status_t
-LocalEnvironment::do_open_db(Database **pdb, DatabaseConfiguration &config,
- const ham_parameter_t *param)
-{
- *pdb = 0;
-
- uint32_t mask = HAM_FORCE_RECORDS_INLINE
- | HAM_FLUSH_WHEN_COMMITTED
- | HAM_READ_ONLY;
- if (config.flags & ~mask) {
- ham_trace(("invalid flags(s) 0x%x", config.flags & ~mask));
- return (HAM_INV_PARAMETER);
- }
-
- if (param) {
- for (; param->name; param++) {
- switch (param->name) {
- case HAM_PARAM_RECORD_COMPRESSION:
- ham_trace(("Record compression is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- case HAM_PARAM_KEY_COMPRESSION:
- ham_trace(("Key compression is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- default:
- ham_trace(("invalid parameter 0x%x (%d)", param->name, param->name));
- return (HAM_INV_PARAMETER);
- }
- }
- }
-
- /* create a new Database object */
- LocalDatabase *db = new LocalDatabase(this, config);
-
- Context context(this, 0, db);
-
- ham_assert(0 != m_header->get_header_page());
-
- /* search for a database with this name */
- uint16_t dbi;
- for (dbi = 0; dbi < m_header->get_max_databases(); dbi++) {
- uint16_t name = btree_header(dbi)->get_dbname();
- if (!name)
- continue;
- if (config.db_name == name)
- break;
- }
-
- if (dbi == m_header->get_max_databases()) {
- delete db;
- return (HAM_DATABASE_NOT_FOUND);
- }
-
- /* open the database */
- ham_status_t st = db->open(&context, btree_header(dbi));
- if (st) {
- delete db;
- ham_trace(("Database could not be opened"));
- return (st);
- }
-
- *pdb = db;
- return (0);
-}
-
-ham_status_t
-LocalEnvironment::do_rename_db(uint16_t oldname, uint16_t newname,
- uint32_t flags)
-{
- Context context(this);
-
- /*
- * check if a database with the new name already exists; also search
- * for the database with the old name
- */
- uint16_t max = m_header->get_max_databases();
- uint16_t slot = max;
- ham_assert(max > 0);
- for (uint16_t dbi = 0; dbi < max; dbi++) {
- uint16_t name = btree_header(dbi)->get_dbname();
- if (name == newname)
- return (HAM_DATABASE_ALREADY_EXISTS);
- if (name == oldname)
- slot = dbi;
- }
-
- if (slot == max)
- return (HAM_DATABASE_NOT_FOUND);
-
- /* replace the database name with the new name */
- btree_header(slot)->set_dbname(newname);
- mark_header_page_dirty(&context);
-
- /* if the database with the old name is currently open: notify it */
- Environment::DatabaseMap::iterator it = m_database_map.find(oldname);
- if (it != m_database_map.end()) {
- Database *db = it->second;
- it->second->set_name(newname);
- m_database_map.erase(oldname);
- m_database_map.insert(DatabaseMap::value_type(newname, db));
- }
-
- return (0);
-}
-
-ham_status_t
-LocalEnvironment::do_erase_db(uint16_t name, uint32_t flags)
-{
- /* check if this database is still open */
- if (m_database_map.find(name) != m_database_map.end())
- return (HAM_DATABASE_ALREADY_OPEN);
-
- /*
- * if it's an in-memory environment then it's enough to purge the
- * database from the environment header
- */
- if (get_flags() & HAM_IN_MEMORY) {
- for (uint16_t dbi = 0; dbi < m_header->get_max_databases(); dbi++) {
- PBtreeHeader *desc = btree_header(dbi);
- if (name == desc->get_dbname()) {
- desc->set_dbname(0);
- return (0);
- }
- }
- return (HAM_DATABASE_NOT_FOUND);
- }
-
- /* temporarily load the database */
- LocalDatabase *db;
- DatabaseConfiguration config;
- config.db_name = name;
- ham_status_t st = do_open_db((Database **)&db, config, 0);
- if (st)
- return (st);
-
- Context context(this, 0, db);
-
- /*
- * delete all blobs and extended keys, also from the cache and
- * the extkey-cache
- *
- * also delete all pages and move them to the freelist; if they're
- * cached, delete them from the cache
- */
- st = db->drop(&context);
- if (st)
- return (st);
-
- /* now set database name to 0 and set the header page to dirty */
- for (uint16_t dbi = 0; dbi < m_header->get_max_databases(); dbi++) {
- PBtreeHeader *desc = btree_header(dbi);
- if (name == desc->get_dbname()) {
- desc->set_dbname(0);
- break;
- }
- }
-
- mark_header_page_dirty(&context);
- context.changeset.clear();
-
- (void)ham_db_close((ham_db_t *)db, HAM_DONT_LOCK);
-
- return (0);
-}
-
-Transaction *
-LocalEnvironment::do_txn_begin(const char *name, uint32_t flags)
-{
- Transaction *txn = new LocalTransaction(this, name, flags);
- m_txn_manager->begin(txn);
- return (txn);
-}
-
-ham_status_t
-LocalEnvironment::do_txn_commit(Transaction *txn, uint32_t flags)
-{
- return (m_txn_manager->commit(txn, flags));
-}
-
-ham_status_t
-LocalEnvironment::do_txn_abort(Transaction *txn, uint32_t flags)
-{
- return (m_txn_manager->abort(txn, flags));
-}
-
-ham_status_t
-LocalEnvironment::do_close(uint32_t flags)
-{
- Context context(this);
-
- /* flush all committed transactions */
- if (m_txn_manager)
- m_txn_manager->flush_committed_txns(&context);
-
- /* flush all pages and the freelist, reduce the file size */
- if (m_page_manager)
- m_page_manager->close(&context);
-
- /* if we're not in read-only mode, and not an in-memory-database,
- * and the dirty-flag is true: flush the page-header to disk */
- if (m_header && m_header->get_header_page() && !(get_flags() & HAM_IN_MEMORY)
- && m_device.get() && m_device.get()->is_open()
- && (!(get_flags() & HAM_READ_ONLY))) {
- m_header->get_header_page()->flush();
- }
-
- /* close the header page */
- if (m_header && m_header->get_header_page()) {
- Page *page = m_header->get_header_page();
- if (page->get_data())
- m_device->free_page(page);
- delete page;
- m_header.reset();
- }
-
- /* close the device */
- if (m_device) {
- if (m_device->is_open()) {
- if (!(get_flags() & HAM_READ_ONLY))
- m_device->flush();
- m_device->close();
- }
- }
-
- /* close the log and the journal */
- if (m_journal)
- m_journal->close(!!(flags & HAM_DONT_CLEAR_LOG));
-
- return (0);
-}
-
-void
-LocalEnvironment::do_fill_metrics(ham_env_metrics_t *metrics) const
-{
- // PageManager metrics (incl. cache and freelist)
- m_page_manager->fill_metrics(metrics);
- // the BlobManagers
- m_blob_manager->fill_metrics(metrics);
- // the Journal (if available)
- if (m_journal)
- m_journal->fill_metrics(metrics);
- // the (first) database
- if (!m_database_map.empty()) {
- LocalDatabase *db = (LocalDatabase *)m_database_map.begin()->second;
- db->fill_metrics(metrics);
- }
- // and of the btrees
- BtreeIndex::fill_metrics(metrics);
- // SIMD support enabled?
- metrics->simd_lane_width = os_get_simd_lane_width();
-}
-
-void
-LocalEnvironmentTest::set_journal(Journal *journal)
-{
- m_env->m_journal.reset(journal);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local.h b/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local.h
deleted file mode 100644
index 7800ee37de..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_ENV_LOCAL_H
-#define HAM_ENV_LOCAL_H
-
-#include "ham/hamsterdb.h"
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/scoped_ptr.h"
-#include "2lsn_manager/lsn_manager.h"
-#include "3journal/journal.h"
-#include "4env/env.h"
-#include "4env/env_header.h"
-#include "4env/env_local_test.h"
-#include "4context/context.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class PBtreeHeader;
-class PFreelistPayload;
-class Journal;
-class PageManager;
-class BlobManager;
-class LocalTransaction;
-struct MessageBase;
-
-//
-// The Environment implementation for local file access
-//
-class LocalEnvironment : public Environment
-{
- public:
- LocalEnvironment(EnvironmentConfiguration &config);
-
- // Returns the Device object
- Device *device() {
- return (m_device.get());
- }
-
- // Returns the Environment's header object with the persistent configuration
- EnvironmentHeader *header() {
- return (m_header.get());
- }
-
- // Returns the blob manager
- BlobManager *blob_manager() {
- return (m_blob_manager.get());
- }
-
- // Returns the PageManager instance
- PageManager *page_manager() {
- return (m_page_manager.get());
- }
-
- // Returns the Journal
- Journal *journal() {
- return (m_journal.get());
- }
-
- // Returns the lsn manager
- LsnManager *lsn_manager() {
- return (&m_lsn_manager);
- }
-
- // The transaction manager
- TransactionManager *txn_manager() {
- return (m_txn_manager.get());
- }
-
- // Increments the lsn and returns the incremented value
- uint64_t next_lsn() {
- return (m_lsn_manager.next());
- }
-
- // Returns a test gateway
- LocalEnvironmentTest test();
-
- protected:
- // Creates a new Environment (ham_env_create)
- virtual ham_status_t do_create();
-
- // Opens a new Environment (ham_env_open)
- virtual ham_status_t do_open();
-
- // Returns all database names (ham_env_get_database_names)
- virtual ham_status_t do_get_database_names(uint16_t *names,
- uint32_t *count);
-
- // Returns environment parameters and flags (ham_env_get_parameters)
- virtual ham_status_t do_get_parameters(ham_parameter_t *param);
-
- // Flushes the environment and its databases to disk (ham_env_flush)
- virtual ham_status_t do_flush(uint32_t flags);
-
- // Creates a new database in the environment (ham_env_create_db)
- virtual ham_status_t do_create_db(Database **db,
- DatabaseConfiguration &config,
- const ham_parameter_t *param);
-
- // Opens an existing database in the environment (ham_env_open_db)
- virtual ham_status_t do_open_db(Database **db,
- DatabaseConfiguration &config,
- const ham_parameter_t *param);
-
- // Renames a database in the Environment (ham_env_rename_db)
- virtual ham_status_t do_rename_db(uint16_t oldname, uint16_t newname,
- uint32_t flags);
-
- // Erases (deletes) a database from the Environment (ham_env_erase_db)
- virtual ham_status_t do_erase_db(uint16_t name, uint32_t flags);
-
- // Begins a new transaction (ham_txn_begin)
- virtual Transaction *do_txn_begin(const char *name, uint32_t flags);
-
- // Commits a transaction (ham_txn_commit)
- virtual ham_status_t do_txn_commit(Transaction *txn, uint32_t flags);
-
- // Commits a transaction (ham_txn_abort)
- virtual ham_status_t do_txn_abort(Transaction *txn, uint32_t flags);
-
- // Closes the Environment (ham_env_close)
- virtual ham_status_t do_close(uint32_t flags);
-
- // Fills in the current metrics
- virtual void do_fill_metrics(ham_env_metrics_t *metrics) const;
-
- private:
- friend class LocalEnvironmentTest;
-
- // Runs the recovery process
- void recover(uint32_t flags);
-
- // Get the btree configuration of the database #i, where |i| is a
- // zero-based index
- PBtreeHeader *btree_header(int i);
-
- // Sets the dirty-flag of the header page and adds the header page
- // to the Changeset (if recovery is enabled)
- void mark_header_page_dirty(Context *context) {
- Page *page = m_header->get_header_page();
- page->set_dirty(true);
- if (get_flags() & HAM_ENABLE_RECOVERY)
- context->changeset.put(page);
- }
-
- // The Environment's header page/configuration
- ScopedPtr<EnvironmentHeader> m_header;
-
- // The device instance (either a file or an in-memory-db)
- ScopedPtr<Device> m_device;
-
- // The BlobManager instance
- ScopedPtr<BlobManager> m_blob_manager;
-
- // The PageManager instance
- ScopedPtr<PageManager> m_page_manager;
-
- // The logical journal
- ScopedPtr<Journal> m_journal;
-
- // The lsn manager
- LsnManager m_lsn_manager;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_ENV_LOCAL_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local_test.h b/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local_test.h
deleted file mode 100644
index ea045e18dc..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_local_test.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: no
- * @thread_safe: no
- */
-
-#ifndef HAM_ENV_LOCAL_TEST_H
-#define HAM_ENV_LOCAL_TEST_H
-
-#include "ham/hamsterdb.h"
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Journal;
-class LocalEnvironment;
-
-class LocalEnvironmentTest
-{
- public:
- LocalEnvironmentTest(LocalEnvironment *env)
- : m_env(env) {
- }
-
- // Sets a new journal object
- void set_journal(Journal *journal);
-
- private:
- LocalEnvironment *m_env;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_ENV_LOCAL_TEST_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_remote.cc b/plugins/Dbx_kv/src/hamsterdb/src/4env/env_remote.cc
deleted file mode 100644
index 6e53543c8b..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_remote.cc
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifdef HAM_ENABLE_REMOTE
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1os/os.h"
-#include "1base/scoped_ptr.h"
-#include "2protobuf/protocol.h"
-#include "4cursor/cursor.h"
-#include "4db/db_remote.h"
-#include "4env/env_remote.h"
-#include "4txn/txn_remote.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-RemoteEnvironment::RemoteEnvironment(EnvironmentConfiguration config)
- : Environment(config), m_remote_handle(0), m_buffer(1024 * 4)
-{
-}
-
-Protocol *
-RemoteEnvironment::perform_request(Protocol *request)
-{
- // use ByteArray to avoid frequent reallocs!
- m_buffer.clear();
-
- if (!request->pack(&m_buffer)) {
- ham_log(("protoype Protocol::pack failed"));
- throw Exception(HAM_INTERNAL_ERROR);
- }
-
- m_socket.send((uint8_t *)m_buffer.get_ptr(), m_buffer.get_size());
-
- // now block and wait for the reply; first read the header, then the
- // remaining data
- m_socket.recv((uint8_t *)m_buffer.get_ptr(), 8);
-
- // no need to check the magic; it's verified in Protocol::unpack
- uint32_t size = *(uint32_t *)((char *)m_buffer.get_ptr() + 4);
- m_buffer.resize(size + 8);
- m_socket.recv((uint8_t *)m_buffer.get_ptr() + 8, size);
-
- return (Protocol::unpack((const uint8_t *)m_buffer.get_ptr(), size + 8));
-}
-
-void
-RemoteEnvironment::perform_request(SerializedWrapper *request,
- SerializedWrapper *reply)
-{
- int size_left = (int)request->get_size();
- request->size = size_left;
- request->magic = HAM_TRANSFER_MAGIC_V2;
- m_buffer.resize(request->size);
-
- uint8_t *ptr = (uint8_t *)m_buffer.get_ptr();
- request->serialize(&ptr, &size_left);
- ham_assert(size_left == 0);
-
- m_socket.send((uint8_t *)m_buffer.get_ptr(), request->size);
-
- // now block and wait for the reply; first read the header, then the
- // remaining data
- m_socket.recv((uint8_t *)m_buffer.get_ptr(), 8);
-
- // now check the magic and receive the remaining data
- uint32_t magic = *(uint32_t *)((char *)m_buffer.get_ptr() + 0);
- if (magic != HAM_TRANSFER_MAGIC_V2)
- throw Exception(HAM_INTERNAL_ERROR);
- // TODO check the magic
- int size = (int)*(uint32_t *)((char *)m_buffer.get_ptr() + 4);
- m_buffer.resize(size);
- m_socket.recv((uint8_t *)m_buffer.get_ptr() + 8, size - 8);
-
- ptr = (uint8_t *)m_buffer.get_ptr();
- reply->deserialize(&ptr, &size);
- ham_assert(size == 0);
-}
-
-ham_status_t
-RemoteEnvironment::do_create()
-{
- // the 'create' operation is identical to 'open'
- return (do_open());
-}
-
-ham_status_t
-RemoteEnvironment::do_open()
-{
- m_socket.close();
-
- const char *url = m_config.filename.c_str();
-
- ham_assert(url != 0);
- ham_assert(::strstr(url, "ham://") == url);
- const char *ip = url + 6;
- const char *port_str = strstr(ip, ":");
- if (!port_str) {
- ham_trace(("remote uri does not include port - expected "
- "`ham://<ip>:<port>`"));
- return (HAM_INV_PARAMETER);
- }
- uint16_t port = (uint16_t)atoi(port_str + 1);
- if (!port) {
- ham_trace(("remote uri includes invalid port - expected "
- "`ham://<ip>:<port>`"));
- return (HAM_INV_PARAMETER);
- }
-
- const char *filename = strstr(port_str, "/");
-
- std::string hostname(ip, port_str);
- m_socket.connect(hostname.c_str(), port, m_config.remote_timeout_sec);
-
- Protocol request(Protocol::CONNECT_REQUEST);
- request.mutable_connect_request()->set_path(filename);
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- ham_assert(reply->type() == Protocol::CONNECT_REPLY);
-
- ham_status_t st = reply->connect_reply().status();
- if (st == 0) {
- m_config.flags |= reply->connect_reply().env_flags();
- m_remote_handle = reply->connect_reply().env_handle();
-
- if (get_flags() & HAM_ENABLE_TRANSACTIONS)
- m_txn_manager.reset(new RemoteTransactionManager(this));
- }
-
- return (st);
-}
-
-ham_status_t
-RemoteEnvironment::do_get_database_names(uint16_t *names, uint32_t *count)
-{
- Protocol request(Protocol::ENV_GET_DATABASE_NAMES_REQUEST);
- request.mutable_env_get_database_names_request();
- request.mutable_env_get_database_names_request()->set_env_handle(m_remote_handle);
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- ham_assert(reply->has_env_get_database_names_reply());
-
- ham_status_t st = reply->env_get_database_names_reply().status();
- if (st)
- return (st);
-
- /* copy the retrieved names */
- uint32_t i;
- for (i = 0;
- i < (uint32_t)reply->env_get_database_names_reply().names_size()
- && i < *count;
- i++) {
- names[i] = (uint16_t)*(reply->mutable_env_get_database_names_reply()->mutable_names()->mutable_data() + i);
- }
-
- *count = i;
- return (0);
-}
-
-ham_status_t
-RemoteEnvironment::do_get_parameters(ham_parameter_t *param)
-{
- static char filename[1024]; // TODO not threadsafe!!
- ham_parameter_t *p = param;
-
- Protocol request(Protocol::ENV_GET_PARAMETERS_REQUEST);
- request.mutable_env_get_parameters_request()->set_env_handle(m_remote_handle);
- while (p && p->name != 0) {
- request.mutable_env_get_parameters_request()->add_names(p->name);
- p++;
- }
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- ham_assert(reply->has_env_get_parameters_reply());
-
- ham_status_t st = reply->env_get_parameters_reply().status();
- if (st)
- return (st);
-
- p = param;
- while (p && p->name) {
- switch (p->name) {
- case HAM_PARAM_CACHESIZE:
- ham_assert(reply->env_get_parameters_reply().has_cache_size());
- p->value = reply->env_get_parameters_reply().cache_size();
- break;
- case HAM_PARAM_PAGESIZE:
- ham_assert(reply->env_get_parameters_reply().has_page_size());
- p->value = reply->env_get_parameters_reply().page_size();
- break;
- case HAM_PARAM_MAX_DATABASES:
- ham_assert(reply->env_get_parameters_reply().has_max_env_databases());
- p->value = reply->env_get_parameters_reply().max_env_databases();
- break;
- case HAM_PARAM_FLAGS:
- ham_assert(reply->env_get_parameters_reply().has_flags());
- p->value = reply->env_get_parameters_reply().flags();
- break;
- case HAM_PARAM_FILEMODE:
- ham_assert(reply->env_get_parameters_reply().has_filemode());
- p->value = reply->env_get_parameters_reply().filemode();
- break;
- case HAM_PARAM_FILENAME:
- if (reply->env_get_parameters_reply().has_filename()) {
- strncpy(filename, reply->env_get_parameters_reply().filename().c_str(),
- sizeof(filename) - 1);
- filename[sizeof(filename) - 1] = 0;
- p->value = (uint64_t)(&filename[0]);
- }
- break;
- default:
- ham_trace(("unknown parameter %d", (int)p->name));
- break;
- }
- p++;
- }
- return (0);
-}
-
-ham_status_t
-RemoteEnvironment::do_flush(uint32_t flags)
-{
- Protocol request(Protocol::ENV_FLUSH_REQUEST);
- request.mutable_env_flush_request()->set_flags(flags);
- request.mutable_env_flush_request()->set_env_handle(m_remote_handle);
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- ham_assert(reply->has_env_flush_reply());
-
- return (reply->env_flush_reply().status());
-}
-
-ham_status_t
-RemoteEnvironment::do_create_db(Database **pdb, DatabaseConfiguration &config,
- const ham_parameter_t *param)
-{
- Protocol request(Protocol::ENV_CREATE_DB_REQUEST);
- request.mutable_env_create_db_request()->set_env_handle(m_remote_handle);
- request.mutable_env_create_db_request()->set_dbname(config.db_name);
- request.mutable_env_create_db_request()->set_flags(config.flags);
-
- const ham_parameter_t *p = param;
- if (p) {
- for (; p->name; p++) {
- request.mutable_env_create_db_request()->add_param_names(p->name);
- request.mutable_env_create_db_request()->add_param_values(p->value);
- }
- }
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- ham_assert(reply->has_env_create_db_reply());
-
- ham_status_t st = reply->env_create_db_reply().status();
- if (st)
- return (st);
-
- config.flags = reply->env_create_db_reply().db_flags();
- RemoteDatabase *rdb = new RemoteDatabase(this, config,
- reply->env_create_db_reply().db_handle());
-
- *pdb = rdb;
- return (0);
-}
-
-ham_status_t
-RemoteEnvironment::do_open_db(Database **pdb, DatabaseConfiguration &config,
- const ham_parameter_t *param)
-{
- Protocol request(Protocol::ENV_OPEN_DB_REQUEST);
- request.mutable_env_open_db_request()->set_env_handle(m_remote_handle);
- request.mutable_env_open_db_request()->set_dbname(config.db_name);
- request.mutable_env_open_db_request()->set_flags(config.flags);
-
- const ham_parameter_t *p = param;
- if (p) {
- for (; p->name; p++) {
- request.mutable_env_open_db_request()->add_param_names(p->name);
- request.mutable_env_open_db_request()->add_param_values(p->value);
- }
- }
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- ham_assert(reply->has_env_open_db_reply());
-
- ham_status_t st = reply->env_open_db_reply().status();
- if (st)
- return (st);
-
- config.flags = reply->env_open_db_reply().db_flags();
- RemoteDatabase *rdb = new RemoteDatabase(this, config,
- reply->env_open_db_reply().db_handle());
-
- *pdb = rdb;
- return (0);
-}
-
-ham_status_t
-RemoteEnvironment::do_rename_db( uint16_t oldname, uint16_t newname,
- uint32_t flags)
-{
- Protocol request(Protocol::ENV_RENAME_REQUEST);
- request.mutable_env_rename_request()->set_env_handle(m_remote_handle);
- request.mutable_env_rename_request()->set_oldname(oldname);
- request.mutable_env_rename_request()->set_newname(newname);
- request.mutable_env_rename_request()->set_flags(flags);
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- ham_assert(reply->has_env_rename_reply());
-
- return (reply->env_rename_reply().status());
-}
-
-ham_status_t
-RemoteEnvironment::do_erase_db(uint16_t name, uint32_t flags)
-{
- Protocol request(Protocol::ENV_ERASE_DB_REQUEST);
- request.mutable_env_erase_db_request()->set_env_handle(m_remote_handle);
- request.mutable_env_erase_db_request()->set_name(name);
- request.mutable_env_erase_db_request()->set_flags(flags);
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- ham_assert(reply->has_env_erase_db_reply());
-
- return (reply->env_erase_db_reply().status());
-}
-
-Transaction *
-RemoteEnvironment::do_txn_begin(const char *name, uint32_t flags)
-{
- SerializedWrapper request;
- request.id = kTxnBeginRequest;
- request.txn_begin_request.env_handle = m_remote_handle;
- request.txn_begin_request.flags = flags;
- if (name) {
- request.txn_begin_request.name.value = (uint8_t *)name;
- request.txn_begin_request.name.size = strlen(name) + 1;
- }
-
- SerializedWrapper reply;
- perform_request(&request, &reply);
- ham_assert(reply.id == kTxnBeginReply);
-
- ham_status_t st = reply.txn_begin_reply.status;
- if (st)
- throw Exception(st);
-
- Transaction *txn = new RemoteTransaction(this, name, flags,
- reply.txn_begin_reply.txn_handle);
- m_txn_manager->begin(txn);
- return (txn);
-}
-
-ham_status_t
-RemoteEnvironment::do_txn_commit(Transaction *txn, uint32_t flags)
-{
- RemoteTransaction *rtxn = dynamic_cast<RemoteTransaction *>(txn);
-
- SerializedWrapper request;
- request.id = kTxnCommitRequest;
- request.txn_commit_request.txn_handle = rtxn->get_remote_handle();
- request.txn_commit_request.flags = flags;
-
- SerializedWrapper reply;
- perform_request(&request, &reply);
- ham_assert(reply.id == kTxnCommitReply);
-
- ham_status_t st = reply.txn_commit_reply.status;
- if (st)
- return (st);
-
- return (m_txn_manager->commit(txn, flags));
-}
-
-ham_status_t
-RemoteEnvironment::do_txn_abort(Transaction *txn, uint32_t flags)
-{
- RemoteTransaction *rtxn = dynamic_cast<RemoteTransaction *>(txn);
-
- SerializedWrapper request;
- request.id = kTxnAbortRequest;
- request.txn_abort_request.txn_handle = rtxn->get_remote_handle();
- request.txn_abort_request.flags = flags;
-
- SerializedWrapper reply;
- perform_request(&request, &reply);
- ham_assert(reply.id == kTxnAbortReply);
- ham_status_t st = reply.txn_abort_reply.status;
- if (st)
- return (st);
-
- return (m_txn_manager->abort(txn, flags));
-}
-
-ham_status_t
-RemoteEnvironment::do_close(uint32_t flags)
-{
- Protocol request(Protocol::DISCONNECT_REQUEST);
- request.mutable_disconnect_request()->set_env_handle(m_remote_handle);
-
- ScopedPtr<Protocol> reply(perform_request(&request));
-
- // ignore the reply
-
- m_socket.close();
- m_remote_handle = 0;
- return (0);
-}
-
-void
-RemoteEnvironment::do_fill_metrics(ham_env_metrics_t *metrics) const
-{
- throw Exception(HAM_NOT_IMPLEMENTED);
-}
-
-} // namespace hamsterdb
-
-#endif // HAM_ENABLE_REMOTE
-
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_remote.h b/plugins/Dbx_kv/src/hamsterdb/src/4env/env_remote.h
deleted file mode 100644
index c45fd5b222..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_remote.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_ENV_REMOTE_H
-#define HAM_ENV_REMOTE_H
-
-#ifdef HAM_ENABLE_REMOTE
-
-#include "0root/root.h"
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1os/socket.h"
-#include "1base/dynamic_array.h"
-#include "2protobuf/protocol.h"
-#include "2protoserde/messages.h"
-#include "4env/env.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-//
-// The Environment implementation for remote file access
-//
-class RemoteEnvironment : public Environment
-{
- public:
- // Constructor
- RemoteEnvironment(EnvironmentConfiguration config);
-
- // Sends a |request| message with the Google Protocol Buffers API. Blocks
- // till the reply was fully received. Returns the reply structure.
- Protocol *perform_request(Protocol *request);
-
- // Sends |request| message with the builtin Serde API. Blocks till the
- // reply was fully received. Fills |reply| with the received data.
- void perform_request(SerializedWrapper *request, SerializedWrapper *reply);
-
- protected:
- // Creates a new Environment (ham_env_create)
- virtual ham_status_t do_create();
-
- // Opens a new Environment (ham_env_open)
- virtual ham_status_t do_open();
-
- // Returns all database names (ham_env_get_database_names)
- virtual ham_status_t do_get_database_names(uint16_t *names,
- uint32_t *count);
-
- // Returns environment parameters and flags (ham_env_get_parameters)
- virtual ham_status_t do_get_parameters(ham_parameter_t *param);
-
- // Flushes the environment and its databases to disk (ham_env_flush)
- virtual ham_status_t do_flush(uint32_t flags);
-
- // Creates a new database in the environment (ham_env_create_db)
- virtual ham_status_t do_create_db(Database **db,
- DatabaseConfiguration &config,
- const ham_parameter_t *param);
-
- // Opens an existing database in the environment (ham_env_open_db)
- virtual ham_status_t do_open_db(Database **db,
- DatabaseConfiguration &config,
- const ham_parameter_t *param);
-
- // Renames a database in the Environment (ham_env_rename_db)
- virtual ham_status_t do_rename_db(uint16_t oldname, uint16_t newname,
- uint32_t flags);
-
- // Erases (deletes) a database from the Environment (ham_env_erase_db)
- virtual ham_status_t do_erase_db(uint16_t name, uint32_t flags);
-
- // Begins a new transaction (ham_txn_begin)
- virtual Transaction *do_txn_begin(const char *name, uint32_t flags);
-
- // Commits a transaction (ham_txn_commit)
- virtual ham_status_t do_txn_commit(Transaction *txn, uint32_t flags);
-
- // Commits a transaction (ham_txn_abort)
- virtual ham_status_t do_txn_abort(Transaction *txn, uint32_t flags);
-
- // Closes the Environment (ham_env_close)
- virtual ham_status_t do_close(uint32_t flags);
-
- // Fills in the current metrics
- virtual void do_fill_metrics(ham_env_metrics_t *metrics) const;
-
- private:
- // the remote handle
- uint64_t m_remote_handle;
-
- // the socket
- Socket m_socket;
-
- // a buffer to avoid frequent memory allocations
- ByteArray m_buffer;
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_ENABLE_REMOTE
-
-#endif /* HAM_ENV_REMOTE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_test.h b/plugins/Dbx_kv/src/hamsterdb/src/4env/env_test.h
deleted file mode 100644
index 0d9fa76cec..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4env/env_test.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: no
- * @thread_safe: no
- */
-
-#ifndef HAM_ENV_TEST_H
-#define HAM_ENV_TEST_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "4env/env.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class EnvironmentTest
-{
- public:
- // Constructor
- EnvironmentTest(EnvironmentConfiguration &config)
- : m_config(config) {
- }
-
- // Returns the Environment's configuration
- EnvironmentConfiguration &config() {
- return (m_config);
- }
-
- void set_filename(const std::string &filename) {
- m_config.filename = filename;
- }
-
- private:
- // Reference to the Environment's configuration
- EnvironmentConfiguration &m_config;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_ENV_TEST_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn.h b/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn.h
deleted file mode 100644
index e38e6155dc..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * The hamsterdb Transaction implementation
- *
- * hamsterdb stores Transactions in volatile RAM (with an append-only journal
- * in case the RAM is lost). Each Transaction and each modification *in* a
- * Transaction is stored in a complex data structure.
- *
- * When a Database is created, it contains a BtreeIndex for persistent
- * (committed and flushed) data, and a TransactionIndex for active Transactions
- * and those Transactions which were committed but not yet flushed to disk.
- * This TransactionTree is implemented as a binary search tree (see rb.h).
- *
- * Each node in the TransactionTree is implemented by TransactionNode. Each
- * node is identified by its database key, and groups all modifications of this
- * key (of all Transactions!).
- *
- * Each modification in the node is implemented by TransactionOperation. There
- * is one such TransactionOperation for 'insert', 'erase' etc. The
- * TransactionOperations form two linked lists - one stored in the Transaction
- * ("all operations from this Transaction") and another one stored in the
- * TransactionNode ("all operations on the same key").
- *
- * All Transactions in an Environment for a linked list, where the tail is
- * the chronologically newest Transaction and the head is the oldest
- * (see Transaction::get_newer and Transaction::get_older).
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_TXN_H
-#define HAM_TXN_H
-
-#include "0root/root.h"
-
-#include <string>
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/dynamic_array.h"
-#include "1base/error.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-//
-// A helper structure; ham_txn_t is declared in ham/hamsterdb.h as an
-// opaque C structure, but internally we use a C++ class. The ham_txn_t
-// struct satisfies the C compiler, and internally we just cast the pointers.
-//
-struct ham_txn_t
-{
- int dummy;
-};
-
-namespace hamsterdb {
-
-struct Context;
-class Environment;
-
-//
-// An abstract base class for a Transaction. Overwritten for local and
-// remote implementations
-//
-class Transaction
-{
- protected:
- enum {
- // Transaction was aborted
- kStateAborted = 0x10000,
-
- // Transaction was committed
- kStateCommitted = 0x20000
- };
-
- public:
- // Constructor; "begins" the Transaction
- // supported flags: HAM_TXN_READ_ONLY, HAM_TXN_TEMPORARY
- Transaction(Environment *env, const char *name, uint32_t flags)
- : m_id(0), m_env(env), m_flags(flags), m_next(0), m_cursor_refcount(0) {
- if (name)
- m_name = name;
- }
-
- // Destructor
- virtual ~Transaction() { }
-
- // Commits the Transaction
- virtual void commit(uint32_t flags = 0) = 0;
-
- // Aborts the Transaction
- virtual void abort(uint32_t flags = 0) = 0;
-
- // Returns true if the Transaction was aborted
- bool is_aborted() const {
- return (m_flags & kStateAborted) != 0;
- }
-
- // Returns true if the Transaction was committed
- bool is_committed() const {
- return (m_flags & kStateCommitted) != 0;
- }
-
- // Returns the unique id of this Transaction
- uint64_t get_id() const {
- return (m_id);
- }
-
- // Returns the environment pointer
- Environment *get_env() const {
- return (m_env);
- }
-
- // Returns the txn name
- const std::string &get_name() const {
- return (m_name);
- }
-
- // Returns the flags
- uint32_t get_flags() const {
- return (m_flags);
- }
-
- // Returns the cursor refcount (numbers of Cursors using this Transaction)
- uint32_t get_cursor_refcount() const {
- return (m_cursor_refcount);
- }
-
- // Increases the cursor refcount (numbers of Cursors using this Transaction)
- void increase_cursor_refcount() {
- m_cursor_refcount++;
- }
-
- // Decreases the cursor refcount (numbers of Cursors using this Transaction)
- void decrease_cursor_refcount() {
- ham_assert(m_cursor_refcount > 0);
- m_cursor_refcount--;
- }
-
- // Returns the memory buffer for the key data.
- // Used to allocate array in ham_find, ham_cursor_move etc. which is
- // then returned to the user.
- ByteArray &key_arena() {
- return (m_key_arena);
- }
-
- // Returns the memory buffer for the record data.
- // Used to allocate array in ham_find, ham_cursor_move etc. which is
- // then returned to the user.
- ByteArray &record_arena() {
- return (m_record_arena);
- }
-
- // Returns the next Transaction in the linked list */
- Transaction *get_next() const {
- return (m_next);
- }
-
- // Sets the next Transaction in the linked list */
- void set_next(Transaction *n) {
- m_next = n;
- }
-
- protected:
- // the id of this Transaction
- uint64_t m_id;
-
- // the Environment pointer
- Environment *m_env;
-
- // flags for this Transaction
- uint32_t m_flags;
-
- // the Transaction name
- std::string m_name;
-
- // the linked list of all transactions
- Transaction *m_next;
-
- // reference counter for cursors (number of cursors attached to this txn)
- uint32_t m_cursor_refcount;
-
- // this is where key->data points to when returning a key to the user
- ByteArray m_key_arena;
-
- // this is where record->data points to when returning a record to the user
- ByteArray m_record_arena;
-
- private:
- friend class Journal;
-
- // Sets the unique id of this Transaction; the journal needs this to patch
- // in the id when recovering a Transaction
- void set_id(uint64_t id) {
- m_id = id;
- }
-};
-
-
-//
-// An abstract base class for the TransactionManager. Overwritten for local and
-// remote implementations.
-//
-// The TransactionManager is part of the Environment and manages all
-// Transactions.
-//
-class TransactionManager
-{
- public:
- // Constructor
- TransactionManager(Environment *env)
- : m_env(env), m_oldest_txn(0), m_newest_txn(0) {
- }
-
- // Destructor
- virtual ~TransactionManager() { }
-
- // Begins a new Transaction
- virtual void begin(Transaction *txn) = 0;
-
- // Commits a Transaction; the derived subclass has to take care of
- // flushing and/or releasing memory
- virtual ham_status_t commit(Transaction *txn, uint32_t flags = 0) = 0;
-
- // Aborts a Transaction; the derived subclass has to take care of
- // flushing and/or releasing memory
- virtual ham_status_t abort(Transaction *txn, uint32_t flags = 0) = 0;
-
- // Flushes committed (queued) transactions
- virtual void flush_committed_txns(Context *context = 0) = 0;
-
- // Returns the oldest transaction which not yet flushed to disk
- Transaction *get_oldest_txn() {
- return (m_oldest_txn);
- }
-
- // Returns the newest transaction which not yet flushed to disk
- Transaction *get_newest_txn() {
- return (m_newest_txn);
- }
-
- protected:
- // Adds a new transaction to this Environment
- void append_txn_at_tail(Transaction *txn) {
- if (!m_newest_txn) {
- ham_assert(m_oldest_txn == 0);
- m_oldest_txn = txn;
- m_newest_txn = txn;
- }
- else {
- m_newest_txn->set_next(txn);
- m_newest_txn = txn;
- /* if there's no oldest txn (this means: all txn's but the
- * current one were already flushed) then set this txn as
- * the oldest txn */
- if (!m_oldest_txn)
- m_oldest_txn = txn;
- }
- }
-
- // Removes a transaction from this Environment
- void remove_txn_from_head(Transaction *txn) {
- if (m_newest_txn == txn)
- m_newest_txn = 0;
-
- ham_assert(m_oldest_txn == txn);
- m_oldest_txn = txn->get_next();
- }
-
- // The Environment which created this TransactionManager
- Environment *m_env;
-
- // The head of the transaction list (the oldest transaction)
- Transaction *m_oldest_txn;
-
- // The tail of the transaction list (the youngest/newest transaction)
- Transaction *m_newest_txn;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_TXN_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_cursor.cc b/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_cursor.cc
deleted file mode 100644
index b91469239f..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_cursor.cc
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "3btree/btree_cursor.h"
-#include "4db/db.h"
-#include "4txn/txn.h"
-#include "4txn/txn_cursor.h"
-#include "4txn/txn_local.h"
-#include "4env/env.h"
-#include "4cursor/cursor.h"
-#include "4context/context.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-void
-TransactionCursor::clone(const TransactionCursor *other)
-{
- m_coupled_op = 0;
- m_coupled_next = 0;
- m_coupled_previous = 0;
-
- if (!other->is_nil())
- couple_to_op(other->get_coupled_op());
-}
-
-void
-TransactionCursor::set_to_nil()
-{
- /* uncoupled cursor? remove from the txn_op structure */
- if (!is_nil()) {
- TransactionOperation *op = get_coupled_op();
- if (op)
- remove_cursor_from_op(op);
- m_coupled_op = 0;
- }
-
- /* otherwise cursor is already nil */
-}
-
-void
-TransactionCursor::couple_to_op(TransactionOperation *op)
-{
- set_to_nil();
- m_coupled_op = op;
-
- m_coupled_next = op->cursor_list();
- m_coupled_previous = 0;
-
- if (op->cursor_list()) {
- TransactionCursor *old = op->cursor_list();
- old->m_coupled_previous = this;
- }
-
- op->set_cursor_list(this);
-}
-
-ham_status_t
-TransactionCursor::overwrite(Context *context, LocalTransaction *txn,
- ham_record_t *record)
-{
- ham_assert(context->txn == txn);
-
- if (is_nil())
- return (HAM_CURSOR_IS_NIL);
-
- TransactionNode *node = m_coupled_op->get_node();
-
- /* an overwrite is actually an insert w/ HAM_OVERWRITE of the
- * current key */
- return (((LocalDatabase *)get_db())->insert_txn(context, node->get_key(),
- record, HAM_OVERWRITE, this));
-}
-
-ham_status_t
-TransactionCursor::move_top_in_node(TransactionNode *node,
- TransactionOperation *op, bool ignore_conflicts, uint32_t flags)
-{
- Transaction *optxn = 0;
-
- if (!op)
- op = node->get_newest_op();
- else
- goto next;
-
- while (op) {
- optxn = op->get_txn();
- /* only look at ops from the current transaction and from
- * committed transactions */
- if (optxn == m_parent->get_txn() || optxn->is_committed()) {
- /* a normal (overwriting) insert will return this key */
- if ((op->get_flags() & TransactionOperation::kInsert)
- || (op->get_flags() & TransactionOperation::kInsertOverwrite)) {
- couple_to_op(op);
- return (0);
- }
- /* retrieve a duplicate key */
- if (op->get_flags() & TransactionOperation::kInsertDuplicate) {
- /* the duplicates are handled by the caller. here we only
- * couple to the first op */
- couple_to_op(op);
- return (0);
- }
- /* a normal erase will return an error (but we still couple the
- * cursor because the caller might need to know WHICH key was
- * deleted!) */
- if (op->get_flags() & TransactionOperation::kErase) {
- couple_to_op(op);
- return (HAM_KEY_ERASED_IN_TXN);
- }
- /* everything else is a bug! */
- ham_assert(op->get_flags() == TransactionOperation::kNop);
- }
- else if (optxn->is_aborted())
- ; /* nop */
- else if (!ignore_conflicts) {
- /* we still have to couple, because higher-level functions
- * will need to know about the op when consolidating the trees */
- couple_to_op(op);
- return (HAM_TXN_CONFLICT);
- }
-
-next:
- m_parent->set_dupecache_index(0);
- op = op->get_previous_in_node();
- }
-
- return (HAM_KEY_NOT_FOUND);
-}
-
-ham_status_t
-TransactionCursor::move(uint32_t flags)
-{
- ham_status_t st;
- TransactionNode *node;
-
- if (flags & HAM_CURSOR_FIRST) {
- /* first set cursor to nil */
- set_to_nil();
-
- node = get_db()->txn_index()->get_first();
- if (!node)
- return (HAM_KEY_NOT_FOUND);
- return (move_top_in_node(node, 0, false, flags));
- }
- else if (flags & HAM_CURSOR_LAST) {
- /* first set cursor to nil */
- set_to_nil();
-
- node = get_db()->txn_index()->get_last();
- if (!node)
- return (HAM_KEY_NOT_FOUND);
- return (move_top_in_node(node, 0, false, flags));
- }
- else if (flags & HAM_CURSOR_NEXT) {
- if (is_nil())
- return (HAM_CURSOR_IS_NIL);
-
- node = m_coupled_op->get_node();
-
- ham_assert(!is_nil());
-
- /* first move to the next key in the current node; if we fail,
- * then move to the next node. repeat till we've found a key or
- * till we've reached the end of the tree */
- while (1) {
- node = node->get_next_sibling();
- if (!node)
- return (HAM_KEY_NOT_FOUND);
- st = move_top_in_node(node, 0, true, flags);
- if (st == HAM_KEY_NOT_FOUND)
- continue;
- return (st);
- }
- }
- else if (flags & HAM_CURSOR_PREVIOUS) {
- if (is_nil())
- return (HAM_CURSOR_IS_NIL);
-
- node = m_coupled_op->get_node();
-
- ham_assert(!is_nil());
-
- /* first move to the previous key in the current node; if we fail,
- * then move to the previous node. repeat till we've found a key or
- * till we've reached the end of the tree */
- while (1) {
- node = node->get_previous_sibling();
- if (!node)
- return (HAM_KEY_NOT_FOUND);
- st = move_top_in_node(node, 0, true, flags);
- if (st == HAM_KEY_NOT_FOUND)
- continue;
- return (st);
- }
- }
- else {
- ham_assert(!"this flag is not yet implemented");
- }
-
- return (0);
-}
-
-ham_status_t
-TransactionCursor::find(ham_key_t *key, uint32_t flags)
-{
- TransactionNode *node = 0;
-
- /* first set cursor to nil */
- set_to_nil();
-
- /* then lookup the node */
- if (get_db()->txn_index())
- node = get_db()->txn_index()->get(key, flags);
- if (!node)
- return (HAM_KEY_NOT_FOUND);
-
- while (1) {
- /* and then move to the newest insert*-op */
- ham_status_t st = move_top_in_node(node, 0, false, 0);
- if (st != HAM_KEY_ERASED_IN_TXN)
- return (st);
-
- /* if the key was erased and approx. matching is enabled, then move
- * next/prev till we found a valid key. */
- if (flags & HAM_FIND_GT_MATCH)
- node = node->get_next_sibling();
- else if (flags & HAM_FIND_LT_MATCH)
- node = node->get_previous_sibling();
- else
- return (st);
-
- if (!node)
- return (HAM_KEY_NOT_FOUND);
- }
-
- ham_assert(!"should never reach this");
- return (0);
-}
-
-void
-TransactionCursor::copy_coupled_key(ham_key_t *key)
-{
- Transaction *txn = m_parent->get_txn();
- ham_key_t *source = 0;
-
- ByteArray *arena = &get_db()->key_arena(txn);
-
- /* coupled cursor? get key from the txn_op structure */
- if (!is_nil()) {
- TransactionNode *node = m_coupled_op->get_node();
-
- ham_assert(get_db() == node->get_db());
- source = node->get_key();
-
- key->size = source->size;
- if (source->data && source->size) {
- if (!(key->flags & HAM_KEY_USER_ALLOC)) {
- arena->resize(source->size);
- key->data = arena->get_ptr();
- }
- memcpy(key->data, source->data, source->size);
- }
- else
- key->data = 0;
- return;
- }
-
- /* otherwise cursor is nil and we cannot return a key */
- throw Exception(HAM_CURSOR_IS_NIL);
-}
-
-void
-TransactionCursor::copy_coupled_record(ham_record_t *record)
-{
- ham_record_t *source = 0;
- Transaction *txn = m_parent->get_txn();
-
- ByteArray *arena = &get_db()->record_arena(txn);
-
- /* coupled cursor? get record from the txn_op structure */
- if (!is_nil()) {
- source = m_coupled_op->get_record();
-
- record->size = source->size;
- if (source->data && source->size) {
- if (!(record->flags & HAM_RECORD_USER_ALLOC)) {
- arena->resize(source->size);
- record->data = arena->get_ptr();
- }
- memcpy(record->data, source->data, source->size);
- }
- else
- record->data = 0;
- return;
- }
-
- /* otherwise cursor is nil and we cannot return a key */
- throw Exception(HAM_CURSOR_IS_NIL);
-}
-
-uint64_t
-TransactionCursor::get_record_size()
-{
- /* coupled cursor? get record from the txn_op structure */
- if (!is_nil())
- return (m_coupled_op->get_record()->size);
-
- /* otherwise cursor is nil and we cannot return a key */
- throw Exception(HAM_CURSOR_IS_NIL);
-}
-
-LocalDatabase *
-TransactionCursor::get_db()
-{
- return (m_parent->get_db());
-}
-
-ham_status_t
-TransactionCursor::test_insert(ham_key_t *key, ham_record_t *record,
- uint32_t flags)
-{
- LocalTransaction *txn = dynamic_cast<LocalTransaction *>(m_parent->get_txn());
- Context context(get_db()->lenv(), txn, get_db());
-
- return (get_db()->insert_txn(&context, key, record, flags, this));
-}
-
-void
-TransactionCursor::remove_cursor_from_op(TransactionOperation *op)
-{
- ham_assert(!is_nil());
-
- if (op->cursor_list() == this) {
- op->set_cursor_list(m_coupled_next);
- if (m_coupled_next)
- m_coupled_next->m_coupled_previous = 0;
- }
- else {
- if (m_coupled_next)
- m_coupled_next->m_coupled_previous = m_coupled_previous;
- if (m_coupled_previous)
- m_coupled_previous->m_coupled_next = m_coupled_next;
- }
- m_coupled_next = 0;
- m_coupled_previous = 0;
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_cursor.h b/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_cursor.h
deleted file mode 100644
index d2f4462f76..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_cursor.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A cursor which can iterate over transaction nodes and operations
- *
- * A Transaction Cursor can walk over Transaction trees (TransactionIndex).
- *
- * Transaction Cursors are only used as part of the Cursor structure as defined
- * in cursor.h. Like all Transaction operations it is in-memory only,
- * traversing the red-black tree that is implemented in txn.h, and
- * consolidating multiple operations in a node (i.e. if a Transaction first
- * overwrites a record, and another transaction then erases the key).
- *
- * The Transaction Cursor has two states: either it is coupled to a
- * Transaction operation (TransactionOperation) or it is unused.
- *
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_TXN_CURSOR_H
-#define HAM_TXN_CURSOR_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "4txn/txn_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-class Cursor;
-struct Context;
-
-//
-// An cursor which can iterate over Transaction nodes
-//
-class TransactionCursor
-{
- public:
- // Constructor
- TransactionCursor(Cursor *parent)
- : m_parent(parent) {
- m_coupled_op = 0;
- m_coupled_next = 0;
- m_coupled_previous = 0;
- }
-
- // Destructor; asserts that the cursor is nil
- ~TransactionCursor() {
- ham_assert(is_nil());
- }
-
- // Clones another TransactionCursor
- void clone(const TransactionCursor *other);
-
- // Returns the parent cursor
- // TODO this should be private
- Cursor *get_parent() {
- return (m_parent);
- }
-
- // Couples this cursor to a TransactionOperation structure
- void couple_to_op(TransactionOperation *op);
-
- // Returns the pointer to the coupled TransactionOperation
- TransactionOperation *get_coupled_op() const {
- return (m_coupled_op);
- }
-
- // Sets the cursor to nil
- void set_to_nil();
-
- // Returns true if the cursor is nil (does not point to any item)
- bool is_nil() const {
- return (m_coupled_op == 0);
- }
-
- // Retrieves the key from the current item; creates a deep copy.
- //
- // If the cursor is uncoupled, HAM_CURSOR_IS_NIL is returned. this
- // means that the item was already flushed to the btree, and the caller has
- // to use the btree lookup function to retrieve the key.
- void copy_coupled_key(ham_key_t *key);
-
- // Retrieves the record from the current item; creates a deep copy.
- //
- // If the cursor is uncoupled, HAM_CURSOR_IS_NIL will be returned. this
- // means that the item was already flushed to the btree, and the caller has
- // to use the btree lookup function to retrieve the record.
- void copy_coupled_record(ham_record_t *record);
-
- // Moves the cursor to first, last, previous or next
- ham_status_t move(uint32_t flags);
-
- // Overwrites the record of a cursor
- ham_status_t overwrite(Context *context, LocalTransaction *txn,
- ham_record_t *record);
-
- // Looks up an item, places the cursor
- ham_status_t find(ham_key_t *key, uint32_t flags);
-
- // Retrieves the record size of the current item
- uint64_t get_record_size();
-
- // Returns the pointer to the next cursor in the linked list of coupled
- // cursors
- TransactionCursor *get_coupled_next() {
- return (m_coupled_next);
- }
-
- // Closes the cursor
- void close() {
- set_to_nil();
- }
-
- private:
- friend struct TxnCursorFixture;
-
- // Removes this cursor from this TransactionOperation
- void remove_cursor_from_op(TransactionOperation *op);
-
- // Inserts an item, places the cursor on the new item.
- // This function is only used in the unittests.
- ham_status_t test_insert(ham_key_t *key, ham_record_t *record,
- uint32_t flags);
-
- // Returns the database pointer
- LocalDatabase *get_db();
-
- // Moves the cursor to the first valid Operation in a Node
- ham_status_t move_top_in_node(TransactionNode *node,
- TransactionOperation *op, bool ignore_conflicts,
- uint32_t flags);
-
- // The parent cursor
- Cursor *m_parent;
-
- // A Cursor can either be coupled or nil ("not in list"). If it's
- // coupled, it directly points to a TransactionOperation structure.
- // If it's nil then |m_coupled_op| is null.
- //
- // the txn operation to which we're pointing
- TransactionOperation *m_coupled_op;
-
- // a double linked list with other cursors that are coupled
- // to the same Operation
- TransactionCursor *m_coupled_next, *m_coupled_previous;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_TXN_CURSOR_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_factory.h b/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_factory.h
deleted file mode 100644
index 2738f1b4d7..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_factory.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * A factory to create TransactionOperation and TransactionNode instances.
- *
- * @exception_safe: strong
- * @thread_safe: yes
- */
-
-#ifndef HAM_TXN_FACTORY_H
-#define HAM_TXN_FACTORY_H
-
-#include "0root/root.h"
-
-#include "ham/types.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1mem/mem.h"
-#include "4txn/txn.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct TransactionFactory
-{
- // Creates a new TransactionOperation
- static TransactionOperation *create_operation(LocalTransaction *txn,
- TransactionNode *node, uint32_t flags, uint32_t orig_flags,
- uint64_t lsn, ham_key_t *key, ham_record_t *record) {
- TransactionOperation *op;
- op = Memory::allocate<TransactionOperation>(sizeof(*op)
- + (record ? record->size : 0)
- + (key ? key->size : 0));
- op->initialize(txn, node, flags, orig_flags, lsn, key, record);
- return (op);
- }
-
- // Destroys a TransactionOperation
- static void destroy_operation(TransactionOperation *op) {
- op->destroy();
- }
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_TXN_FACTORY_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_local.cc b/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_local.cc
deleted file mode 100644
index 8014b6330f..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_local.cc
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "3btree/btree_index.h"
-#include "3journal/journal.h"
-#include "4txn/txn_local.h"
-#include "4txn/txn_factory.h"
-#include "4txn/txn_cursor.h"
-#include "4env/env_local.h"
-#include "4cursor/cursor.h"
-#include "4context/context.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-/* stuff for rb.h */
-#ifndef __ssize_t_defined
-typedef signed ssize_t;
-#endif
-#ifndef __cplusplus
-typedef int bool;
-#define true 1
-#define false (!true)
-#endif /* __cpluscplus */
-
-static int
-compare(void *vlhs, void *vrhs)
-{
- TransactionNode *lhs = (TransactionNode *)vlhs;
- TransactionNode *rhs = (TransactionNode *)vrhs;
- LocalDatabase *db = lhs->get_db();
-
- if (lhs == rhs)
- return (0);
-
- ham_key_t *lhskey = lhs->get_key();
- ham_key_t *rhskey = rhs->get_key();
- ham_assert(lhskey && rhskey);
- return (db->btree_index()->compare_keys(lhskey, rhskey));
-}
-
-rb_proto(static, rbt_, TransactionIndex, TransactionNode)
-rb_gen(static, rbt_, TransactionIndex, TransactionNode, node, compare)
-
-void
-TransactionOperation::initialize(LocalTransaction *txn, TransactionNode *node,
- uint32_t flags, uint32_t orig_flags, uint64_t lsn,
- ham_key_t *key, ham_record_t *record)
-{
- memset(this, 0, sizeof(*this));
-
- m_txn = txn;
- m_node = node;
- m_flags = flags;
- m_lsn = lsn;
- m_orig_flags = orig_flags;
-
- /* copy the key data */
- if (key) {
- m_key = *key;
- if (key->size) {
- m_key.data = &m_data[0];
- memcpy(m_key.data, key->data, key->size);
- }
- }
-
- /* copy the record data */
- if (record) {
- m_record = *record;
- if (record->size) {
- m_record.data = &m_data[key ? key->size : 0];
- memcpy(m_record.data, record->data, record->size);
- }
- }
-}
-
-void
-TransactionOperation::destroy()
-{
- bool delete_node = false;
-
- /* remove this op from the node */
- TransactionNode *node = get_node();
- if (node->get_oldest_op() == this) {
- /* if the node is empty: remove the node from the tree */
- // TODO should this be done in here??
- if (get_next_in_node() == 0) {
- node->get_db()->txn_index()->remove(node);
- delete_node = true;
- }
- node->set_oldest_op(get_next_in_node());
- }
-
- /* remove this operation from the two linked lists */
- TransactionOperation *next = get_next_in_node();
- TransactionOperation *prev = get_previous_in_node();
- if (next)
- next->set_previous_in_node(prev);
- if (prev)
- prev->set_next_in_node(next);
-
- next = get_next_in_txn();
- prev = get_previous_in_txn();
- if (next)
- next->set_previous_in_txn(prev);
- if (prev)
- prev->set_next_in_txn(next);
-
- if (delete_node)
- delete node;
-
- Memory::release(this);
-}
-
-TransactionNode *
-TransactionNode::get_next_sibling()
-{
- return (rbt_next(get_db()->txn_index(), this));
-}
-
-TransactionNode *
-TransactionNode::get_previous_sibling()
-{
- return (rbt_prev(get_db()->txn_index(), this));
-}
-
-TransactionNode::TransactionNode(LocalDatabase *db, ham_key_t *key)
- : m_db(db), m_oldest_op(0), m_newest_op(0), m_key(key)
-{
- /* make sure that a node with this key does not yet exist */
- // TODO re-enable this; currently leads to a stack overflow because
- // TransactionIndex::get() creates a new TransactionNode
- // ham_assert(TransactionIndex::get(key, 0) == 0);
-}
-
-TransactionNode::~TransactionNode()
-{
-}
-
-TransactionOperation *
-TransactionNode::append(LocalTransaction *txn, uint32_t orig_flags,
- uint32_t flags, uint64_t lsn, ham_key_t *key,
- ham_record_t *record)
-{
- TransactionOperation *op = TransactionFactory::create_operation(txn,
- this, flags, orig_flags, lsn,
- key, record);
-
- /* store it in the chronological list which is managed by the node */
- if (!get_newest_op()) {
- ham_assert(get_oldest_op() == 0);
- set_newest_op(op);
- set_oldest_op(op);
- }
- else {
- TransactionOperation *newest = get_newest_op();
- newest->set_next_in_node(op);
- op->set_previous_in_node(newest);
- set_newest_op(op);
- }
-
- /* store it in the chronological list which is managed by the transaction */
- if (!txn->get_newest_op()) {
- ham_assert(txn->get_oldest_op() == 0);
- txn->set_newest_op(op);
- txn->set_oldest_op(op);
- }
- else {
- TransactionOperation *newest = txn->get_newest_op();
- newest->set_next_in_txn(op);
- op->set_previous_in_txn(newest);
- txn->set_newest_op(op);
- }
-
- // now that an operation is attached make sure that the node no
- // longer uses the temporary key pointer
- m_key = 0;
-
- return (op);
-}
-
-void
-TransactionIndex::store(TransactionNode *node)
-{
- rbt_insert(this, node);
-}
-
-void
-TransactionIndex::remove(TransactionNode *node)
-{
-#ifdef HAM_DEBUG
- bool found = false;
- TransactionNode *n = rbt_first(this);
- while (n) {
- if (n == node) {
- found = true;
- break;
- }
- n = rbt_next(this, n);
- }
- ham_assert(found == true);
-#endif
-
- rbt_remove(this, node);
-}
-
-LocalTransactionManager::LocalTransactionManager(Environment *env)
- : TransactionManager(env), m_txn_id(0), m_queued_txn_for_flush(0),
- m_queued_ops_for_flush(0), m_queued_bytes_for_flush(0),
- m_txn_threshold(kFlushTxnThreshold),
- m_ops_threshold(kFlushOperationsThreshold),
- m_bytes_threshold(kFlushBytesThreshold)
-{
- if (m_env->get_flags() & HAM_FLUSH_WHEN_COMMITTED) {
- m_txn_threshold = 0;
- m_ops_threshold = 0;
- m_bytes_threshold = 0;
- }
-}
-
-LocalTransaction::LocalTransaction(LocalEnvironment *env, const char *name,
- uint32_t flags)
- : Transaction(env, name, flags), m_log_desc(0), m_oldest_op(0),
- m_newest_op(0), m_op_counter(0), m_accum_data_size(0)
-{
- LocalTransactionManager *ltm =
- (LocalTransactionManager *)env->txn_manager();
- m_id = ltm->get_incremented_txn_id();
-
- /* append journal entry */
- if (env->get_flags() & HAM_ENABLE_RECOVERY
- && env->get_flags() & HAM_ENABLE_TRANSACTIONS
- && !(flags & HAM_TXN_TEMPORARY)) {
- env->journal()->append_txn_begin(this, name,
- env->next_lsn());
- }
-}
-
-LocalTransaction::~LocalTransaction()
-{
- free_operations();
-}
-
-void
-LocalTransaction::commit(uint32_t flags)
-{
- /* are cursors attached to this txn? if yes, fail */
- if (get_cursor_refcount()) {
- ham_trace(("Transaction cannot be committed till all attached "
- "Cursors are closed"));
- throw Exception(HAM_CURSOR_STILL_OPEN);
- }
-
- /* this transaction is now committed! */
- m_flags |= kStateCommitted;
-}
-
-void
-LocalTransaction::abort(uint32_t flags)
-{
- /* are cursors attached to this txn? if yes, fail */
- if (get_cursor_refcount()) {
- ham_trace(("Transaction cannot be aborted till all attached "
- "Cursors are closed"));
- throw Exception(HAM_CURSOR_STILL_OPEN);
- }
-
- /* this transaction is now aborted! */
- m_flags |= kStateAborted;
-
- /* immediately release memory of the cached operations */
- free_operations();
-}
-
-void
-LocalTransaction::free_operations()
-{
- TransactionOperation *n, *op = get_oldest_op();
-
- while (op) {
- n = op->get_next_in_txn();
- TransactionFactory::destroy_operation(op);
- op = n;
- }
-
- set_oldest_op(0);
- set_newest_op(0);
-}
-
-TransactionIndex::TransactionIndex(LocalDatabase *db)
- : m_db(db)
-{
- rbt_new(this);
-}
-
-TransactionIndex::~TransactionIndex()
-{
- TransactionNode *node;
-
- while ((node = rbt_last(this))) {
- remove(node);
- delete node;
- }
-
- // re-initialize the tree
- rbt_new(this);
-}
-
-TransactionNode *
-TransactionIndex::get(ham_key_t *key, uint32_t flags)
-{
- TransactionNode *node = 0;
- int match = 0;
-
- /* create a temporary node that we can search for */
- TransactionNode tmp(m_db, key);
-
- /* search if node already exists - if yes, return it */
- if ((flags & HAM_FIND_GEQ_MATCH) == HAM_FIND_GEQ_MATCH) {
- node = rbt_nsearch(this, &tmp);
- if (node)
- match = compare(&tmp, node);
- }
- else if ((flags & HAM_FIND_LEQ_MATCH) == HAM_FIND_LEQ_MATCH) {
- node = rbt_psearch(this, &tmp);
- if (node)
- match = compare(&tmp, node);
- }
- else if (flags & HAM_FIND_GT_MATCH) {
- node = rbt_search(this, &tmp);
- if (node)
- node = node->get_next_sibling();
- else
- node = rbt_nsearch(this, &tmp);
- match = 1;
- }
- else if (flags & HAM_FIND_LT_MATCH) {
- node = rbt_search(this, &tmp);
- if (node)
- node = node->get_previous_sibling();
- else
- node = rbt_psearch(this, &tmp);
- match = -1;
- }
- else
- return (rbt_search(this, &tmp));
-
- /* tree is empty? */
- if (!node)
- return (0);
-
- /* approx. matching: set the key flag */
- if (match < 0)
- ham_key_set_intflags(key, (ham_key_get_intflags(key)
- & ~BtreeKey::kApproximate) | BtreeKey::kLower);
- else if (match > 0)
- ham_key_set_intflags(key, (ham_key_get_intflags(key)
- & ~BtreeKey::kApproximate) | BtreeKey::kGreater);
-
- return (node);
-}
-
-TransactionNode *
-TransactionIndex::get_first()
-{
- return (rbt_first(this));
-}
-
-TransactionNode *
-TransactionIndex::get_last()
-{
- return (rbt_last(this));
-}
-
-void
-TransactionIndex::enumerate(Context *context,
- TransactionIndex::Visitor *visitor)
-{
- TransactionNode *node = rbt_first(this);
-
- while (node) {
- visitor->visit(context, node);
- node = rbt_next(this, node);
- }
-}
-
-struct KeyCounter : public TransactionIndex::Visitor
-{
- KeyCounter(LocalDatabase *_db, LocalTransaction *_txn, bool _distinct)
- : counter(0), distinct(_distinct), txn(_txn), db(_db) {
- }
-
- void visit(Context *context, TransactionNode *node) {
- BtreeIndex *be = db->btree_index();
- TransactionOperation *op;
-
- /*
- * look at each tree_node and walk through each operation
- * in reverse chronological order (from newest to oldest):
- * - is this op part of an aborted txn? then skip it
- * - is this op part of a committed txn? then include it
- * - is this op part of an txn which is still active? then include it
- * - if a committed txn has erased the item then there's no need
- * to continue checking older, committed txns of the same key
- *
- * !!
- * if keys are overwritten or a duplicate key is inserted, then
- * we have to consolidate the btree keys with the txn-tree keys.
- */
- op = node->get_newest_op();
- while (op) {
- LocalTransaction *optxn = op->get_txn();
- if (optxn->is_aborted())
- ; // nop
- else if (optxn->is_committed() || txn == optxn) {
- if (op->get_flags() & TransactionOperation::kIsFlushed)
- ; // nop
- // if key was erased then it doesn't exist
- else if (op->get_flags() & TransactionOperation::kErase)
- return;
- else if (op->get_flags() & TransactionOperation::kInsert) {
- counter++;
- return;
- }
- // key exists - include it
- else if ((op->get_flags() & TransactionOperation::kInsert)
- || (op->get_flags() & TransactionOperation::kInsertOverwrite)) {
- // check if the key already exists in the btree - if yes,
- // we do not count it (it will be counted later)
- if (HAM_KEY_NOT_FOUND == be->find(context, 0, node->get_key(), 0, 0, 0, 0))
- counter++;
- return;
- }
- else if (op->get_flags() & TransactionOperation::kInsertDuplicate) {
- // check if btree has other duplicates
- if (0 == be->find(context, 0, node->get_key(), 0, 0, 0, 0)) {
- // yes, there's another one
- if (distinct)
- return;
- counter++;
- }
- else {
- // check if other key is in this node
- counter++;
- if (distinct)
- return;
- }
- }
- else if (!(op->get_flags() & TransactionOperation::kNop)) {
- ham_assert(!"shouldn't be here");
- return;
- }
- }
- else { // txn is still active
- counter++;
- }
-
- op = op->get_previous_in_node();
- }
- }
-
- uint64_t counter;
- bool distinct;
- LocalTransaction *txn;
- LocalDatabase *db;
-};
-
-uint64_t
-TransactionIndex::count(Context *context, LocalTransaction *txn, bool distinct)
-{
- KeyCounter k(m_db, txn, distinct);
- enumerate(context, &k);
- return (k.counter);
-}
-
-void
-LocalTransactionManager::begin(Transaction *txn)
-{
- append_txn_at_tail(txn);
-}
-
-ham_status_t
-LocalTransactionManager::commit(Transaction *htxn, uint32_t flags)
-{
- LocalTransaction *txn = dynamic_cast<LocalTransaction *>(htxn);
- Context context(lenv(), txn, 0);
-
- try {
- txn->commit(flags);
-
- /* append journal entry */
- if (m_env->get_flags() & HAM_ENABLE_RECOVERY
- && m_env->get_flags() & HAM_ENABLE_TRANSACTIONS
- && !(txn->get_flags() & HAM_TXN_TEMPORARY))
- lenv()->journal()->append_txn_commit(txn,
- lenv()->next_lsn());
-
- /* flush committed transactions */
- m_queued_txn_for_flush++;
- m_queued_ops_for_flush += txn->get_op_counter();
- m_queued_bytes_for_flush += txn->get_accum_data_size();
- maybe_flush_committed_txns(&context);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
- return (0);
-}
-
-ham_status_t
-LocalTransactionManager::abort(Transaction *htxn, uint32_t flags)
-{
- LocalTransaction *txn = dynamic_cast<LocalTransaction *>(htxn);
- Context context(lenv(), txn, 0);
-
- try {
- txn->abort(flags);
-
- /* append journal entry */
- if (m_env->get_flags() & HAM_ENABLE_RECOVERY
- && m_env->get_flags() & HAM_ENABLE_TRANSACTIONS
- && !(txn->get_flags() & HAM_TXN_TEMPORARY))
- lenv()->journal()->append_txn_abort(txn,
- lenv()->next_lsn());
-
- /* flush committed transactions; while this one was not committed,
- * we might have cleared the way now to flush other committed
- * transactions */
- m_queued_txn_for_flush++;
-
- /* no need to increment m_queued_{ops,bytes}_for_flush because this
- * operation does no longer contain any operations */
- maybe_flush_committed_txns(&context);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
- return (0);
-}
-
-void
-LocalTransactionManager::maybe_flush_committed_txns(Context *context)
-{
- if (m_queued_txn_for_flush > m_txn_threshold
- || m_queued_ops_for_flush > m_ops_threshold
- || m_queued_bytes_for_flush > m_bytes_threshold)
- flush_committed_txns_impl(context);
-}
-
-void
-LocalTransactionManager::flush_committed_txns(Context *context /* = 0 */)
-{
- if (!context) {
- Context new_context(lenv(), 0, 0);
- flush_committed_txns_impl(&new_context);
- }
- else
- flush_committed_txns_impl(context);
-}
-
-void
-LocalTransactionManager::flush_committed_txns_impl(Context *context)
-{
- LocalTransaction *oldest;
- Journal *journal = lenv()->journal();
- uint64_t highest_lsn = 0;
-
- ham_assert(context->changeset.is_empty());
-
- /* always get the oldest transaction; if it was committed: flush
- * it; if it was aborted: discard it; otherwise return */
- while ((oldest = (LocalTransaction *)get_oldest_txn())) {
- if (oldest->is_committed()) {
- m_queued_ops_for_flush -= oldest->get_op_counter();
- ham_assert(m_queued_ops_for_flush >= 0);
- m_queued_bytes_for_flush -= oldest->get_accum_data_size();
- ham_assert(m_queued_bytes_for_flush >= 0);
- uint64_t lsn = flush_txn(context, (LocalTransaction *)oldest);
- if (lsn > highest_lsn)
- highest_lsn = lsn;
-
- /* this transaction was flushed! */
- if (journal && (oldest->get_flags() & HAM_TXN_TEMPORARY) == 0)
- journal->transaction_flushed(oldest);
- }
- else if (oldest->is_aborted()) {
- ; /* nop */
- }
- else
- break;
-
- /* it's possible that Transactions were aborted directly, and not through
- * the TransactionManager (i.e. in Journal::abort_uncommitted_txns).
- * so don't rely on m_queued_txn_for_flush, it might be zero */
- if (m_queued_txn_for_flush > 0)
- m_queued_txn_for_flush--;
-
- /* now remove the txn from the linked list */
- remove_txn_from_head(oldest);
-
- /* and release the memory */
- delete oldest;
- }
-
- /* now flush the changeset and write the modified pages to disk */
- if (highest_lsn && m_env->get_flags() & HAM_ENABLE_RECOVERY)
- context->changeset.flush(highest_lsn);
- else
- context->changeset.clear();
-
- ham_assert(context->changeset.is_empty());
-}
-
-uint64_t
-LocalTransactionManager::flush_txn(Context *context, LocalTransaction *txn)
-{
- TransactionOperation *op = txn->get_oldest_op();
- TransactionCursor *cursor = 0;
- uint64_t highest_lsn = 0;
-
- while (op) {
- TransactionNode *node = op->get_node();
-
- if (op->get_flags() & TransactionOperation::kIsFlushed)
- goto next_op;
-
- // perform the actual operation in the btree
- node->get_db()->flush_txn_operation(context, txn, op);
-
- /*
- * this op is about to be flushed!
- *
- * as a consequence, all (txn)cursors which are coupled to this op
- * have to be uncoupled, as their parent (btree) cursor was
- * already coupled to the btree item instead
- */
- op->set_flushed();
-next_op:
- while ((cursor = op->cursor_list())) {
- Cursor *pc = cursor->get_parent();
- ham_assert(pc->get_txn_cursor() == cursor);
- pc->couple_to_btree(); // TODO merge both calls?
- if (!pc->is_nil(Cursor::kTxn))
- pc->set_to_nil(Cursor::kTxn);
- }
-
- ham_assert(op->get_lsn() > highest_lsn);
- highest_lsn = op->get_lsn();
-
- /* continue with the next operation of this txn */
- op = op->get_next_in_txn();
- }
-
- return (highest_lsn);
-}
-
-} // namespace hamsterdb
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_local.h b/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_local.h
deleted file mode 100644
index cfb563466a..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_local.h
+++ /dev/null
@@ -1,566 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_TXN_LOCAL_H
-#define HAM_TXN_LOCAL_H
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1rb/rb.h"
-#include "4txn/txn.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-class TransactionNode;
-class TransactionIndex;
-class TransactionCursor;
-class LocalTransaction;
-class LocalDatabase;
-class LocalEnvironment;
-
-
-//
-// The TransactionOperation class describes a single operation (i.e.
-// insert or erase) in a Transaction.
-//
-class TransactionOperation
-{
- public:
- enum {
- // a NOP operation (empty)
- kNop = 0x000000u,
-
- // txn operation is an insert
- kInsert = 0x010000u,
-
- // txn operation is an insert w/ overwrite
- kInsertOverwrite = 0x020000u,
-
- // txn operation is an insert w/ duplicate
- kInsertDuplicate = 0x040000u,
-
- // txn operation erases the key
- kErase = 0x080000u,
-
- // txn operation was already flushed
- kIsFlushed = 0x100000u
- };
-
- // Returns the flags
- uint32_t get_flags() const {
- return (m_flags);
- }
-
- // This Operation was flushed to disk
- void set_flushed() {
- m_flags |= kIsFlushed;
- }
-
- // Returns the original flags of ham_insert/ham_cursor_insert/ham_erase...
- uint32_t get_orig_flags() const {
- return (m_orig_flags);
- }
-
- // Returns the referenced duplicate id
- uint32_t get_referenced_dupe() const {
- return (m_referenced_dupe);
- }
-
- // Sets the referenced duplicate id
- void set_referenced_dupe(uint32_t id) {
- m_referenced_dupe = id;
- }
-
- // Returns a pointer to the Transaction of this update
- LocalTransaction *get_txn() {
- return (m_txn);
- }
-
- // Returns a pointer to the parent node of this update */
- TransactionNode *get_node() {
- return (m_node);
- }
-
- // Returns the lsn of this operation
- uint64_t get_lsn() const {
- return (m_lsn);
- }
-
- // Returns the key of this operation
- ham_key_t *get_key() {
- return (&m_key);
- }
-
- // Returns the record of this operation
- ham_record_t *get_record() {
- return (&m_record);
- }
-
- // Returns the list of Cursors coupled to this operation
- TransactionCursor *cursor_list() {
- return (m_cursor_list);
- }
-
- // Sets the list of Cursors coupled to this operation
- void set_cursor_list(TransactionCursor *cursors) {
- m_cursor_list = cursors;
- }
-
- // Returns the next TransactionOperation which modifies the
- // same TransactionNode
- TransactionOperation *get_next_in_node() {
- return (m_node_next);
- }
-
- // Returns the previous TransactionOperation which modifies the
- // same TransactionNode
- TransactionOperation *get_previous_in_node() {
- return (m_node_prev);
- }
-
- // Returns the next TransactionOperation in the same Transaction
- TransactionOperation *get_next_in_txn() {
- return (m_txn_next);
- }
-
- // Returns the previous TransactionOperation in the same Transaction
- TransactionOperation *get_previous_in_txn() {
- return (m_txn_prev);
- }
-
- private:
- friend class TransactionNode;
- friend struct TransactionFactory;
-
- // Initialization
- void initialize(LocalTransaction *txn, TransactionNode *node,
- uint32_t flags, uint32_t orig_flags, uint64_t lsn,
- ham_key_t *key, ham_record_t *record);
-
- // Destructor
- void destroy();
-
- // Sets the next TransactionOperation which modifies the
- // same TransactionNode
- void set_next_in_node(TransactionOperation *next) {
- m_node_next = next;
- }
-
- // Sets the previous TransactionOperation which modifies the
- // same TransactionNode
- void set_previous_in_node(TransactionOperation *prev) {
- m_node_prev = prev;
- }
-
- // Sets the next TransactionOperation in the same Transaction
- void set_next_in_txn(TransactionOperation *next) {
- m_txn_next = next;
- }
-
- // Sets the previous TransactionOperation in the same Transaction
- void set_previous_in_txn(TransactionOperation *prev) {
- m_txn_prev = prev;
- }
-
- // the Transaction of this operation
- LocalTransaction *m_txn;
-
- // the parent node
- TransactionNode *m_node;
-
- // flags and type of this operation; defined in this file
- uint32_t m_flags;
-
- // the original flags of this operation, used when calling
- // ham_cursor_insert, ham_insert, ham_erase etc
- uint32_t m_orig_flags;
-
- // the referenced duplicate id (if neccessary) - used if this is
- // i.e. a ham_cursor_erase, ham_cursor_overwrite or ham_cursor_insert
- // with a DUPLICATE_AFTER/BEFORE flag
- // this is 1-based (like dupecache-index, which is also 1-based)
- uint32_t m_referenced_dupe;
-
- // the log serial number (lsn) of this operation
- uint64_t m_lsn;
-
- // a linked list of cursors which are attached to this operation
- TransactionCursor *m_cursor_list;
-
- // next in linked list (managed in TransactionNode)
- TransactionOperation *m_node_next;
-
- // previous in linked list (managed in TransactionNode)
- TransactionOperation *m_node_prev;
-
- // next in linked list (managed in Transaction)
- TransactionOperation *m_txn_next;
-
- // previous in linked list (managed in Transaction)
- TransactionOperation *m_txn_prev;
-
- // the key which is inserted or overwritten
- ham_key_t m_key;
-
- // the record which is inserted or overwritten
- ham_record_t m_record;
-
- // Storage for record->data. This saves us one memory allocation.
- uint8_t m_data[1];
-};
-
-
-//
-// A node in the Transaction Index, used as the node structure in rb.h.
-// Manages a group of TransactionOperation objects which all modify the
-// same key.
-//
-// To avoid chicken-egg problems when inserting a new TransactionNode
-// into the TransactionTree, it is possible to assign a temporary key
-// to this node. However, as soon as an operation is attached to this node,
-// the TransactionNode class will use the key structure in this operation.
-//
-// This basically avoids one memory allocation.
-//
-class TransactionNode
-{
- public:
- // Constructor;
- // The default parameters are required for the compilation of rb.h.
- // |key| is just a temporary pointer which allows to create a
- // TransactionNode without further memory allocations/copying. The actual
- // key is then fetched from |m_oldest_op| as soon as this node is fully
- // initialized.
- TransactionNode(LocalDatabase *db = 0, ham_key_t *key = 0);
-
- // Destructor; removes this node from the tree, unless |dont_insert|
- // was set to true
- ~TransactionNode();
-
- // Returns the database
- LocalDatabase *get_db() {
- return (m_db);
- }
-
- // Returns the modified key
- ham_key_t *get_key() {
- return (m_oldest_op ? m_oldest_op->get_key() : m_key);
- }
-
- // Retrieves the next larger sibling of a given node, or NULL if there
- // is no sibling
- TransactionNode *get_next_sibling();
-
- // Retrieves the previous larger sibling of a given node, or NULL if there
- // is no sibling
- TransactionNode *get_previous_sibling();
-
- // Returns the first (oldest) TransactionOperation in this node
- TransactionOperation *get_oldest_op() {
- return (m_oldest_op);
- };
-
- // Sets the first (oldest) TransactionOperation in this node
- void set_oldest_op(TransactionOperation *oldest) {
- m_oldest_op = oldest;
- }
-
- // Returns the last (newest) TransactionOperation in this node
- TransactionOperation *get_newest_op() {
- return (m_newest_op);
- };
-
- // Sets the last (newest) TransactionOperation in this node
- void set_newest_op(TransactionOperation *newest) {
- m_newest_op = newest;
- }
-
- // Appends an actual operation to this node
- TransactionOperation *append(LocalTransaction *txn, uint32_t orig_flags,
- uint32_t flags, uint64_t lsn, ham_key_t *key,
- ham_record_t *record);
-
- // red-black tree stub, required for rb.h
- rb_node(TransactionNode) node;
-
- private:
- friend struct TxnFixture;
-
- // the database - need this to get the compare function
- LocalDatabase *m_db;
-
- // the linked list of operations - head is oldest operation
- TransactionOperation *m_oldest_op;
-
- // the linked list of operations - tail is newest operation
- TransactionOperation *m_newest_op;
-
- // Pointer to the key data; only used as long as there are no operations
- // attached. Otherwise we have a chicken-egg problem in rb.h.
- ham_key_t *m_key;
-};
-
-
-//
-// Each Database has a binary tree which stores the current Transaction
-// operations; this tree is implemented in TransactionIndex
-//
-class TransactionIndex
-{
- public:
- // Traverses a TransactionIndex; for each node, a callback is executed
- struct Visitor {
- virtual void visit(Context *context, TransactionNode *node) = 0;
- };
-
- // Constructor
- TransactionIndex(LocalDatabase *db);
-
- // Destructor; frees all nodes and their operations
- ~TransactionIndex();
-
- // Stores a new TransactionNode in the index
- void store(TransactionNode *node);
-
- // Removes a TransactionNode from the index
- void remove(TransactionNode *node);
-
- // Visits every node in the TransactionTree
- void enumerate(Context *context, Visitor *visitor);
-
- // Returns an opnode for an optree; if a node with this
- // key already exists then the existing node is returned, otherwise NULL.
- // |flags| can be HAM_FIND_GEQ_MATCH, HAM_FIND_LEQ_MATCH etc
- TransactionNode *get(ham_key_t *key, uint32_t flags);
-
- // Returns the first (= "smallest") node of the tree, or NULL if the
- // tree is empty
- TransactionNode *get_first();
-
- // Returns the last (= "greatest") node of the tree, or NULL if the
- // tree is empty
- TransactionNode *get_last();
-
- // Returns the key count of this index
- uint64_t count(Context *context, LocalTransaction *txn, bool distinct);
-
- // private: //TODO re-enable this; currently disabled because rb.h needs it
- // the Database for all operations in this tree
- LocalDatabase *m_db;
-
- // stuff for rb.h
- TransactionNode *rbt_root;
- TransactionNode rbt_nil;
-};
-
-
-//
-// A local Transaction
-//
-class LocalTransaction : public Transaction
-{
- public:
- // Constructor; "begins" the Transaction
- // supported flags: HAM_TXN_READ_ONLY, HAM_TXN_TEMPORARY
- LocalTransaction(LocalEnvironment *env, const char *name, uint32_t flags);
-
- // Destructor; frees all TransactionOperation structures associated
- // with this Transaction
- virtual ~LocalTransaction();
-
- // Commits the Transaction
- void commit(uint32_t flags = 0);
-
- // Aborts the Transaction
- void abort(uint32_t flags = 0);
-
- // Returns the first (or 'oldest') TransactionOperation of this Transaction
- TransactionOperation *get_oldest_op() const {
- return (m_oldest_op);
- }
-
- // Sets the first (or 'oldest') TransactionOperation of this Transaction
- void set_oldest_op(TransactionOperation *op) {
- m_oldest_op = op;
- }
-
- // Returns the last (or 'newest') TransactionOperation of this Transaction
- TransactionOperation *get_newest_op() const {
- return (m_newest_op);
- }
-
- // Sets the last (or 'newest') TransactionOperation of this Transaction
- void set_newest_op(TransactionOperation *op) {
- if (op) {
- m_op_counter++;
- m_accum_data_size += op->get_record()
- ? op->get_record()->size
- : 0;
- m_accum_data_size += op->get_node()->get_key()->size;
- }
- m_newest_op = op;
- }
-
- // Returns the number of operations attached to this Transaction
- int get_op_counter() const {
- return (m_op_counter);
- }
-
- // Returns the accumulated data size of all operations
- int get_accum_data_size() const {
- return (m_accum_data_size);
- }
-
- private:
- friend class Journal;
- friend struct TxnFixture;
- friend struct TxnCursorFixture;
-
- // Frees the internal structures; releases all the memory. This is
- // called in the destructor, but also when aborting a Transaction
- // (before it's deleted by the Environment).
- void free_operations();
-
- // Returns the index of the journal's log file descriptor
- int get_log_desc() const {
- return (m_log_desc);
- }
-
- // Sets the index of the journal's log file descriptor
- void set_log_desc(int desc) {
- m_log_desc = desc;
- }
-
- // index of the log file descriptor for this transaction [0..1]
- int m_log_desc;
-
- // the linked list of operations - head is oldest operation
- TransactionOperation *m_oldest_op;
-
- // the linked list of operations - tail is newest operation
- TransactionOperation *m_newest_op;
-
- // For counting the operations
- int m_op_counter;
-
- // The approximate accumulated memory consumed by this Transaction
- // (sums up key->size and record->size over all operations)
- int m_accum_data_size;
-};
-
-
-//
-// A TransactionManager for local Transactions
-//
-class LocalTransactionManager : public TransactionManager
-{
- enum {
- // flush if this limit is exceeded
- kFlushTxnThreshold = 64,
-
- // flush if this limit is exceeded
- kFlushOperationsThreshold = kFlushTxnThreshold * 20,
-
- // flush if this limit is exceeded
- kFlushBytesThreshold = 1024 * 1024 // 1 mb - same as journal buffer
- };
-
- public:
- // Constructor
- LocalTransactionManager(Environment *env);
-
- // Begins a new Transaction
- virtual void begin(Transaction *txn);
-
- // Commits a Transaction; the derived subclass has to take care of
- // flushing and/or releasing memory
- virtual ham_status_t commit(Transaction *txn, uint32_t flags = 0);
-
- // Aborts a Transaction; the derived subclass has to take care of
- // flushing and/or releasing memory
- virtual ham_status_t abort(Transaction *txn, uint32_t flags = 0);
-
- // Flushes committed (queued) transactions
- virtual void flush_committed_txns(Context *context = 0);
-
- // Increments the global transaction ID and returns the new value.
- uint64_t get_incremented_txn_id() {
- return (++m_txn_id);
- }
-
- // Returns the current transaction ID; only for testing!
- uint64_t test_get_txn_id() const {
- return (m_txn_id);
- }
-
- // Sets the current transaction ID; used by the Journal to
- // reset the original txn id during recovery.
- void set_txn_id(uint64_t id) {
- m_txn_id = id;
- }
-
- private:
- void flush_committed_txns_impl(Context *context);
-
- // Flushes a single committed Transaction; returns the lsn of the
- // last operation in this transaction
- uint64_t flush_txn(Context *context, LocalTransaction *txn);
-
- // Casts m_env to a LocalEnvironment
- LocalEnvironment *lenv() {
- return ((LocalEnvironment *)m_env);
- }
-
- // Flushes committed transactions if there are enough committed
- // transactions waiting to be flushed, or if other conditions apply
- void maybe_flush_committed_txns(Context *context);
-
- // The current transaction ID
- uint64_t m_txn_id;
-
- // Number of Transactions waiting to be flushed
- int m_queued_txn_for_flush;
-
- // Combined number of Operations in these transactions waiting to be flushed
- int m_queued_ops_for_flush;
-
- // Approx. memory consumption of all these operations in the flush queue
- int m_queued_bytes_for_flush;
-
- // Threshold for transactio queue
- int m_txn_threshold;
-
- // Threshold for transactio queue
- int m_ops_threshold;
-
- // Threshold for transactio queue
- int m_bytes_threshold;
-};
-
-} // namespace hamsterdb
-
-#endif /* HAM_TXN_LOCAL_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_remote.cc b/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_remote.cc
deleted file mode 100644
index 2d4403b077..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_remote.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifdef HAM_ENABLE_REMOTE
-
-#include "0root/root.h"
-
-#include <string.h>
-
-// Always verify that a file of level N does not include headers > N!
-#include "2protobuf/protocol.h"
-#include "4txn/txn_remote.h"
-#include "4env/env_remote.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-RemoteTransaction::RemoteTransaction(Environment *env, const char *name,
- uint32_t flags, uint64_t remote_handle)
- : Transaction(env, name, flags), m_remote_handle(remote_handle)
-{
-}
-
-void
-RemoteTransaction::commit(uint32_t flags)
-{
- /* There's nothing else to do for this Transaction, therefore set it
- * to 'aborted' (although it was committed) */
- m_flags |= kStateAborted;
-}
-
-void
-RemoteTransaction::abort(uint32_t flags)
-{
- /* this transaction is now aborted! */
- m_flags |= kStateAborted;
-}
-
-void
-RemoteTransactionManager::begin(Transaction *txn)
-{
- append_txn_at_tail(txn);
-}
-
-ham_status_t
-RemoteTransactionManager::commit(Transaction *txn, uint32_t flags)
-{
- try {
- txn->commit(flags);
-
- /* "flush" (remove) committed and aborted transactions */
- flush_committed_txns();
- }
- catch (Exception &ex) {
- return (ex.code);
- }
- return (0);
-}
-
-ham_status_t
-RemoteTransactionManager::abort(Transaction *txn, uint32_t flags)
-{
- try {
- txn->abort(flags);
-
- /* "flush" (remove) committed and aborted transactions */
- flush_committed_txns();
- }
- catch (Exception &ex) {
- return (ex.code);
- }
- return (0);
-}
-
-void
-RemoteTransactionManager::flush_committed_txns(Context *context /* = 0 */)
-{
- Transaction *oldest;
-
- while ((oldest = get_oldest_txn())) {
- if (oldest->is_committed() || oldest->is_aborted()) {
- remove_txn_from_head(oldest);
- delete oldest;
- }
- else
- return;
- }
-}
-
-} // namespace hamsterdb
-
-#endif // HAM_ENABLE_REMOTE
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_remote.h b/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_remote.h
deleted file mode 100644
index 4c7d6f46e5..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/4txn/txn_remote.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * @exception_safe: unknown
- * @thread_safe: unknown
- */
-
-#ifndef HAM_TXN_REMOTE_H
-#define HAM_TXN_REMOTE_H
-
-#ifdef HAM_ENABLE_REMOTE
-
-#include "0root/root.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "4txn/txn.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-namespace hamsterdb {
-
-struct Context;
-
-//
-// A remote Transaction
-//
-class RemoteTransaction : public Transaction
-{
- public:
- // Constructor; "begins" the Transaction
- // supported flags: HAM_TXN_READ_ONLY, HAM_TXN_TEMPORARY
- RemoteTransaction(Environment *env, const char *name, uint32_t flags,
- uint64_t remote_handle);
-
- // Commits the Transaction
- virtual void commit(uint32_t flags = 0);
-
- // Aborts the Transaction
- virtual void abort(uint32_t flags = 0);
-
- // Returns the remote Transaction handle
- uint64_t get_remote_handle() const {
- return (m_remote_handle);
- }
-
- private:
- // The remote Transaction handle
- uint64_t m_remote_handle;
-};
-
-
-//
-// A TransactionManager for remote Transactions
-//
-class RemoteTransactionManager : public TransactionManager
-{
- public:
- // Constructor
- RemoteTransactionManager(Environment *env)
- : TransactionManager(env) {
- }
-
- // Begins a new Transaction
- virtual void begin(Transaction *txn);
-
- // Commits a Transaction; the derived subclass has to take care of
- // flushing and/or releasing memory
- virtual ham_status_t commit(Transaction *txn, uint32_t flags = 0);
-
- // Aborts a Transaction; the derived subclass has to take care of
- // flushing and/or releasing memory
- virtual ham_status_t abort(Transaction *txn, uint32_t flags = 0);
-
- // Flushes committed (queued) transactions
- virtual void flush_committed_txns(Context *context = 0);
-};
-
-} // namespace hamsterdb
-
-#endif // HAM_ENABLE_REMOTE
-
-#endif /* HAM_TXN_REMOTE_H */
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/5hamsterdb/hamsterdb.cc b/plugins/Dbx_kv/src/hamsterdb/src/5hamsterdb/hamsterdb.cc
deleted file mode 100644
index ed366ed374..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/5hamsterdb/hamsterdb.cc
+++ /dev/null
@@ -1,1633 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "ham/hamsterdb.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "1base/dynamic_array.h"
-#include "1mem/mem.h"
-#include "2config/db_config.h"
-#include "2config/env_config.h"
-#include "2page/page.h"
-#ifdef HAM_ENABLE_REMOTE
-# include "2protobuf/protocol.h"
-#endif
-#include "2device/device.h"
-#include "3btree/btree_stats.h"
-#include "3blob_manager/blob_manager.h"
-#include "3btree/btree_index.h"
-#include "3btree/btree_cursor.h"
-#include "4cursor/cursor.h"
-#include "4db/db.h"
-#include "4env/env.h"
-#include "4env/env_header.h"
-#include "4env/env_local.h"
-#include "4env/env_remote.h"
-#include "4txn/txn.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-/* return true if the filename is for a local file */
-static bool
-filename_is_local(const char *filename)
-{
- return (!filename || strstr(filename, "ham://") != filename);
-}
-
-ham_status_t
-ham_txn_begin(ham_txn_t **htxn, ham_env_t *henv, const char *name,
- void *, uint32_t flags)
-{
- Transaction **ptxn = (Transaction **)htxn;
-
- if (!ptxn) {
- ham_trace(("parameter 'txn' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- *ptxn = 0;
-
- if (!henv) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Environment *env = (Environment *)henv;
-
- return (env->txn_begin(ptxn, name, flags));
-}
-
-HAM_EXPORT const char *
-ham_txn_get_name(ham_txn_t *htxn)
-{
- Transaction *txn = (Transaction *)htxn;
- if (!txn)
- return (0);
-
- const std::string &name = txn->get_env()->txn_get_name(txn);
- return (name.empty() ? 0 : name.c_str());
-}
-
-ham_status_t
-ham_txn_commit(ham_txn_t *htxn, uint32_t flags)
-{
- Transaction *txn = (Transaction *)htxn;
- if (!txn) {
- ham_trace(("parameter 'txn' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Environment *env = txn->get_env();
-
- return (env->txn_commit(txn, flags));
-}
-
-ham_status_t
-ham_txn_abort(ham_txn_t *htxn, uint32_t flags)
-{
- Transaction *txn = (Transaction *)htxn;
- if (!txn) {
- ham_trace(("parameter 'txn' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Environment *env = txn->get_env();
-
- return (env->txn_abort(txn, flags));
-}
-
-const char * HAM_CALLCONV
-ham_strerror(ham_status_t result)
-{
- switch (result) {
- case HAM_SUCCESS:
- return ("Success");
- case HAM_INV_KEY_SIZE:
- return ("Invalid key size");
- case HAM_INV_RECORD_SIZE:
- return ("Invalid record size");
- case HAM_INV_PAGESIZE:
- return ("Invalid page size");
- case HAM_OUT_OF_MEMORY:
- return ("Out of memory");
- case HAM_INV_PARAMETER:
- return ("Invalid parameter");
- case HAM_INV_FILE_HEADER:
- return ("Invalid database file header");
- case HAM_INV_FILE_VERSION:
- return ("Invalid database file version");
- case HAM_KEY_NOT_FOUND:
- return ("Key not found");
- case HAM_DUPLICATE_KEY:
- return ("Duplicate key");
- case HAM_INTEGRITY_VIOLATED:
- return ("Internal integrity violated");
- case HAM_INTERNAL_ERROR:
- return ("Internal error");
- case HAM_WRITE_PROTECTED:
- return ("Database opened in read-only mode");
- case HAM_BLOB_NOT_FOUND:
- return ("Data blob not found");
- case HAM_IO_ERROR:
- return ("System I/O error");
- case HAM_NOT_IMPLEMENTED:
- return ("Operation not implemented");
- case HAM_FILE_NOT_FOUND:
- return ("File not found");
- case HAM_WOULD_BLOCK:
- return ("Operation would block");
- case HAM_NOT_READY:
- return ("Object was not initialized correctly");
- case HAM_CURSOR_STILL_OPEN:
- return ("Cursor must be closed prior to Transaction abort/commit");
- case HAM_FILTER_NOT_FOUND:
- return ("Record filter or file filter not found");
- case HAM_TXN_CONFLICT:
- return ("Operation conflicts with another Transaction");
- case HAM_TXN_STILL_OPEN:
- return ("Database cannot be closed because it is modified in a "
- "Transaction");
- case HAM_CURSOR_IS_NIL:
- return ("Cursor points to NIL");
- case HAM_DATABASE_NOT_FOUND:
- return ("Database not found");
- case HAM_DATABASE_ALREADY_EXISTS:
- return ("Database name already exists");
- case HAM_DATABASE_ALREADY_OPEN:
- return ("Database already open, or: Database handle "
- "already initialized");
- case HAM_ENVIRONMENT_ALREADY_OPEN:
- return ("Environment already open, or: Environment handle "
- "already initialized");
- case HAM_LIMITS_REACHED:
- return ("Database limits reached");
- case HAM_ALREADY_INITIALIZED:
- return ("Object was already initialized");
- case HAM_NEED_RECOVERY:
- return ("Database needs recovery");
- case HAM_LOG_INV_FILE_HEADER:
- return ("Invalid log file header");
- case HAM_NETWORK_ERROR:
- return ("Remote I/O error/Network error");
- default:
- return ("Unknown error");
- }
-}
-
-/**
- * Prepares a @ref ham_key_t structure for returning key data in.
- *
- * This function checks whether the @ref ham_key_t structure has been
- * properly initialized by the user and resets all internal used elements.
- *
- * @return true when the @a key structure has been initialized correctly
- * before.
- *
- * @return false when the @a key structure has @e not been initialized
- * correctly before.
- */
-static inline bool
-__prepare_key(ham_key_t *key)
-{
- if (unlikely(key->size && !key->data)) {
- ham_trace(("key->size != 0, but key->data is NULL"));
- return (false);
- }
- if (unlikely(key->flags != 0 && key->flags != HAM_KEY_USER_ALLOC)) {
- ham_trace(("invalid flag in key->flags"));
- return (false);
- }
- key->_flags = 0;
- return (true);
-}
-
-/**
- * Prepares a @ref ham_record_t structure for returning record data in.
- *
- * This function checks whether the @ref ham_record_t structure has been
- * properly initialized by the user and resets all internal used elements.
- *
- * @return true when the @a record structure has been initialized
- * correctly before.
- *
- * @return false when the @a record structure has @e not been
- * initialized correctly before.
- */
-static inline bool
-__prepare_record(ham_record_t *record)
-{
- if (unlikely(record->size && !record->data)) {
- ham_trace(("record->size != 0, but record->data is NULL"));
- return false;
- }
- if (unlikely(record->flags & HAM_DIRECT_ACCESS))
- record->flags &= ~HAM_DIRECT_ACCESS;
- if (unlikely(record->flags != 0 && record->flags != HAM_RECORD_USER_ALLOC)) {
- ham_trace(("invalid flag in record->flags"));
- return (false);
- }
- return (true);
-}
-
-void HAM_CALLCONV
-ham_get_version(uint32_t *major, uint32_t *minor, uint32_t *revision)
-{
- if (major)
- *major = HAM_VERSION_MAJ;
- if (minor)
- *minor = HAM_VERSION_MIN;
- if (revision)
- *revision = HAM_VERSION_REV;
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_create(ham_env_t **henv, const char *filename,
- uint32_t flags, uint32_t mode, const ham_parameter_t *param)
-{
- EnvironmentConfiguration config;
- config.filename = filename ? filename : "";
- config.file_mode = mode;
-
- if (!henv) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- *henv = 0;
-
- /* creating a file in READ_ONLY mode? doesn't make sense */
- if (flags & HAM_READ_ONLY) {
- ham_trace(("cannot create a file in read-only mode"));
- return (HAM_INV_PARAMETER);
- }
-
- /* in-memory? recovery is not possible */
- if ((flags & HAM_IN_MEMORY) && (flags & HAM_ENABLE_RECOVERY)) {
- ham_trace(("combination of HAM_IN_MEMORY and HAM_ENABLE_RECOVERY "
- "not allowed"));
- return (HAM_INV_PARAMETER);
- }
-
- if (flags & HAM_ENABLE_CRC32) {
- ham_trace(("Crc32 is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- }
-
- /* HAM_ENABLE_TRANSACTIONS implies HAM_ENABLE_RECOVERY, unless explicitly
- * disabled */
- if ((flags & HAM_ENABLE_TRANSACTIONS) && !(flags & HAM_DISABLE_RECOVERY))
- flags |= HAM_ENABLE_RECOVERY;
-
- /* flag HAM_AUTO_RECOVERY implies HAM_ENABLE_RECOVERY */
- if (flags & HAM_AUTO_RECOVERY)
- flags |= HAM_ENABLE_RECOVERY;
-
- /* in-memory with Transactions? disable recovery */
- if (flags & HAM_IN_MEMORY)
- flags &= ~HAM_ENABLE_RECOVERY;
-
- if (param) {
- for (; param->name; param++) {
- switch (param->name) {
- case HAM_PARAM_JOURNAL_COMPRESSION:
- ham_trace(("Journal compression is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- case HAM_PARAM_CACHE_SIZE:
- if (flags & HAM_IN_MEMORY && param->value != 0) {
- ham_trace(("combination of HAM_IN_MEMORY and cache size != 0 "
- "not allowed"));
- return (HAM_INV_PARAMETER);
- }
- /* don't allow cache limits with unlimited cache */
- if (flags & HAM_CACHE_UNLIMITED && param->value != 0) {
- ham_trace(("combination of HAM_CACHE_UNLIMITED and cache size != 0 "
- "not allowed"));
- return (HAM_INV_PARAMETER);
- }
- if (param->value > 0)
- config.cache_size_bytes = (size_t)param->value;
- break;
- case HAM_PARAM_PAGE_SIZE:
- if (param->value != 1024 && param->value % 2048 != 0) {
- ham_trace(("invalid page size - must be 1024 or a multiple of 2048"));
- return (HAM_INV_PAGESIZE);
- }
- if (param->value > 0)
- config.page_size_bytes = (uint32_t)param->value;
- break;
- case HAM_PARAM_FILE_SIZE_LIMIT:
- if (param->value > 0)
- config.file_size_limit_bytes = (size_t)param->value;
- break;
- case HAM_PARAM_JOURNAL_SWITCH_THRESHOLD:
- config.journal_switch_threshold = (uint32_t)param->value;
- break;
- case HAM_PARAM_LOG_DIRECTORY:
- config.log_filename = (const char *)param->value;
- break;
- case HAM_PARAM_NETWORK_TIMEOUT_SEC:
- config.remote_timeout_sec = (uint32_t)param->value;
- break;
- case HAM_PARAM_ENCRYPTION_KEY:
- ham_trace(("Encryption is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- case HAM_PARAM_POSIX_FADVISE:
- config.posix_advice = (int)param->value;
- break;
- default:
- ham_trace(("unknown parameter %d", (int)param->name));
- return (HAM_INV_PARAMETER);
- }
- }
- }
-
- if (config.filename.empty() && !(flags & HAM_IN_MEMORY)) {
- ham_trace(("filename is missing"));
- return (HAM_INV_PARAMETER);
- }
-
- config.flags = flags;
-
- /*
- * make sure that max_databases actually fit in a header
- * page!
- * leave at least 128 bytes for other header data
- */
- config.max_databases = config.page_size_bytes
- - sizeof(PEnvironmentHeader) - 128;
- config.max_databases /= sizeof(PBtreeHeader);
-
- ham_status_t st = 0;
- Environment *env = 0;
-
- if (filename_is_local(config.filename.c_str())) {
- env = new LocalEnvironment(config);
- }
- else {
-#ifndef HAM_ENABLE_REMOTE
- return (HAM_NOT_IMPLEMENTED);
-#else // HAM_ENABLE_REMOTE
- env = new RemoteEnvironment(config);
-#endif
- }
-
-#ifdef HAM_ENABLE_REMOTE
- atexit(Protocol::shutdown);
-#endif
-
- /* and finish the initialization of the Environment */
- st = env->create();
-
- /* flush the environment to make sure that the header page is written
- * to disk TODO required?? */
- if (st == 0)
- st = env->flush(0);
-
- if (st) {
- env->close(HAM_AUTO_CLEANUP);
- delete env;
- return (st);
- }
-
- *henv = (ham_env_t *)env;
- return (0);
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_create_db(ham_env_t *henv, ham_db_t **hdb, uint16_t db_name,
- uint32_t flags, const ham_parameter_t *param)
-{
- Environment *env = (Environment *)henv;
- DatabaseConfiguration config;
-
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- *hdb = 0;
-
- if (!db_name || (db_name >= 0xf000)) {
- ham_trace(("invalid database name"));
- return (HAM_INV_PARAMETER);
- }
-
- config.db_name = db_name;
- config.flags = flags;
-
- return (env->create_db((Database **)hdb, config, param));
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_open_db(ham_env_t *henv, ham_db_t **hdb, uint16_t db_name,
- uint32_t flags, const ham_parameter_t *param)
-{
- Environment *env = (Environment *)henv;
- DatabaseConfiguration config;
-
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- *hdb = 0;
-
- if (!db_name) {
- ham_trace(("parameter 'db_name' must not be 0"));
- return (HAM_INV_PARAMETER);
- }
- if (db_name >= 0xf000) {
- ham_trace(("database name must be lower than 0xf000"));
- return (HAM_INV_PARAMETER);
- }
- if (env->get_flags() & HAM_IN_MEMORY) {
- ham_trace(("cannot open a Database in an In-Memory Environment"));
- return (HAM_INV_PARAMETER);
- }
-
- config.flags = flags;
- config.db_name = db_name;
-
- return (env->open_db((Database **)hdb, config, param));
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_open(ham_env_t **henv, const char *filename, uint32_t flags,
- const ham_parameter_t *param)
-{
- EnvironmentConfiguration config;
- config.filename = filename ? filename : "";
-
- if (!henv) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- *henv = 0;
-
- /* cannot open an in-memory-db */
- if (flags & HAM_IN_MEMORY) {
- ham_trace(("cannot open an in-memory database"));
- return (HAM_INV_PARAMETER);
- }
-
- /* HAM_ENABLE_DUPLICATE_KEYS has to be specified in ham_env_create_db,
- * not ham_env_open */
- if (flags & HAM_ENABLE_DUPLICATE_KEYS) {
- ham_trace(("invalid flag HAM_ENABLE_DUPLICATE_KEYS (only allowed when "
- "creating a database"));
- return (HAM_INV_PARAMETER);
- }
-
- if (flags & HAM_ENABLE_CRC32) {
- ham_trace(("Crc32 is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- }
-
- /* HAM_ENABLE_TRANSACTIONS implies HAM_ENABLE_RECOVERY, unless explicitly
- * disabled */
- if ((flags & HAM_ENABLE_TRANSACTIONS) && !(flags & HAM_DISABLE_RECOVERY))
- flags |= HAM_ENABLE_RECOVERY;
-
- /* flag HAM_AUTO_RECOVERY implies HAM_ENABLE_RECOVERY */
- if (flags & HAM_AUTO_RECOVERY)
- flags |= HAM_ENABLE_RECOVERY;
-
- if (config.filename.empty() && !(flags & HAM_IN_MEMORY)) {
- ham_trace(("filename is missing"));
- return (HAM_INV_PARAMETER);
- }
-
- if (param) {
- for (; param->name; param++) {
- switch (param->name) {
- case HAM_PARAM_JOURNAL_COMPRESSION:
- ham_trace(("Journal compression is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- case HAM_PARAM_CACHE_SIZE:
- /* don't allow cache limits with unlimited cache */
- if (flags & HAM_CACHE_UNLIMITED && param->value != 0) {
- ham_trace(("combination of HAM_CACHE_UNLIMITED and cache size != 0 "
- "not allowed"));
- return (HAM_INV_PARAMETER);
- }
- if (param->value > 0)
- config.cache_size_bytes = param->value;
- break;
- case HAM_PARAM_FILE_SIZE_LIMIT:
- if (param->value > 0)
- config.file_size_limit_bytes = (size_t)param->value;
- break;
- case HAM_PARAM_JOURNAL_SWITCH_THRESHOLD:
- config.journal_switch_threshold = (uint32_t)param->value;
- break;
- case HAM_PARAM_LOG_DIRECTORY:
- config.log_filename = (const char *)param->value;
- break;
- case HAM_PARAM_NETWORK_TIMEOUT_SEC:
- config.remote_timeout_sec = (uint32_t)param->value;
- break;
- case HAM_PARAM_ENCRYPTION_KEY:
- ham_trace(("Encryption is only available in hamsterdb pro"));
- return (HAM_NOT_IMPLEMENTED);
- case HAM_PARAM_POSIX_FADVISE:
- config.posix_advice = (int)param->value;
- break;
- default:
- ham_trace(("unknown parameter %d", (int)param->name));
- return (HAM_INV_PARAMETER);
- }
- }
- }
-
- config.flags = flags;
-
- ham_status_t st = 0;
- Environment *env = 0;
-
- if (filename_is_local(config.filename.c_str())) {
- env = new LocalEnvironment(config);
- }
- else {
-#ifndef HAM_ENABLE_REMOTE
- return (HAM_NOT_IMPLEMENTED);
-#else // HAM_ENABLE_REMOTE
- env = new RemoteEnvironment(config);
-#endif
- }
-
-#ifdef HAM_ENABLE_REMOTE
- atexit(Protocol::shutdown);
-#endif
-
- /* and finish the initialization of the Environment */
- st = env->open();
-
- if (st) {
- (void)env->close(HAM_AUTO_CLEANUP);
- delete env;
- return (st);
- }
-
- *henv = (ham_env_t *)env;
- return (0);
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_rename_db(ham_env_t *henv, uint16_t oldname, uint16_t newname,
- uint32_t flags)
-{
- Environment *env = (Environment *)henv;
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- if (!oldname) {
- ham_trace(("parameter 'oldname' must not be 0"));
- return (HAM_INV_PARAMETER);
- }
- if (!newname) {
- ham_trace(("parameter 'newname' must not be 0"));
- return (HAM_INV_PARAMETER);
- }
- if (newname >= 0xf000) {
- ham_trace(("parameter 'newname' must be lower than 0xf000"));
- return (HAM_INV_PARAMETER);
- }
-
- /* no need to do anything if oldname==newname */
- if (oldname == newname)
- return (0);
-
- /* rename the database */
- return (env->rename_db(oldname, newname, flags));
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_erase_db(ham_env_t *henv, uint16_t name, uint32_t flags)
-{
- Environment *env = (Environment *)henv;
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- if (!name) {
- ham_trace(("parameter 'name' must not be 0"));
- return (HAM_INV_PARAMETER);
- }
-
- /* erase the database */
- return (env->erase_db(name, flags));
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_get_database_names(ham_env_t *henv, uint16_t *names, uint32_t *count)
-{
- Environment *env = (Environment *)henv;
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- if (!names) {
- ham_trace(("parameter 'names' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!count) {
- ham_trace(("parameter 'count' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- /* get all database names */
- return (env->get_database_names(names, count));
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_env_get_parameters(ham_env_t *henv, ham_parameter_t *param)
-{
- Environment *env = (Environment *)henv;
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- if (!param) {
- ham_trace(("parameter 'param' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- /* get the parameters */
- return (env->get_parameters(param));
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_flush(ham_env_t *henv, uint32_t flags)
-{
- Environment *env = (Environment *)henv;
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- if (flags && flags != HAM_FLUSH_COMMITTED_TRANSACTIONS) {
- ham_trace(("parameter 'flags' is unused, set to 0"));
- return (HAM_INV_PARAMETER);
- }
-
- /* flush the Environment */
- return (env->flush(flags));
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_close(ham_env_t *henv, uint32_t flags)
-{
- ham_status_t st;
- Environment *env = (Environment *)henv;
-
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- try {
- /* close the environment */
- st = env->close(flags);
- if (st)
- return (st);
-
- delete env;
- return (0);
- }
- catch (Exception &ex) {
- return (ex.code);
- }
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_get_parameters(ham_db_t *hdb, ham_parameter_t *param)
-{
- Database *db = (Database *)hdb;
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- if (!param) {
- ham_trace(("parameter 'param' must not be NULL"));
- return HAM_INV_PARAMETER;
- }
-
- ScopedLock lock(db->get_env()->mutex());
-
- /* get the parameters */
- return (db->set_error(db->get_parameters(param)));
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_get_error(ham_db_t *hdb)
-{
- Database *db = (Database *)hdb;
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (0);
- }
-
- ScopedLock lock;
- if (db->get_env())
- lock = ScopedLock(db->get_env()->mutex());
-
- return (db->get_error());
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_set_compare_func(ham_db_t *hdb, ham_compare_func_t foo)
-{
- Database *db = (Database *)hdb;
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!foo) {
- ham_trace(("function pointer must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- LocalDatabase *ldb = dynamic_cast<LocalDatabase *>(db);
- if (!ldb) {
- ham_trace(("operation not possible for remote databases"));
- return (HAM_INV_PARAMETER);
- }
-
- ScopedLock lock(ldb->get_env()->mutex());
-
- /* set the compare functions */
- return (ldb->set_error(ldb->set_compare_func(foo)));
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_find(ham_db_t *hdb, ham_txn_t *htxn, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- Database *db = (Database *)hdb;
- Transaction *txn = (Transaction *)htxn;
- Environment *env;
-
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- env = db->get_env();
-
- ScopedLock lock(env->mutex());
-
- if (!key) {
- ham_trace(("parameter 'key' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (!record) {
- ham_trace(("parameter 'record' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_PREPEND) {
- ham_trace(("flag HAM_HINT_PREPEND is only allowed in "
- "ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_APPEND) {
- ham_trace(("flag HAM_HINT_APPEND is only allowed in "
- "ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_DIRECT_ACCESS)
- && !(env->get_flags() & HAM_IN_MEMORY)) {
- ham_trace(("flag HAM_DIRECT_ACCESS is only allowed in "
- "In-Memory Databases"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_DIRECT_ACCESS)
- && (env->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("flag HAM_DIRECT_ACCESS is not allowed in "
- "combination with Transactions"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_PARTIAL)
- && (db->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("flag HAM_PARTIAL is not allowed in combination with "
- "transactions"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- /* record number: make sure that we have a valid key structure */
- if ((db->get_flags() & HAM_RECORD_NUMBER32) && !key->data) {
- ham_trace(("key->data must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((db->get_flags() & HAM_RECORD_NUMBER64) && !key->data) {
- ham_trace(("key->data must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- if (!__prepare_key(key) || !__prepare_record(record))
- return (db->set_error(HAM_INV_PARAMETER));
-
- return (db->set_error(db->find(0, txn, key, record, flags)));
-}
-
-HAM_EXPORT int HAM_CALLCONV
-ham_key_get_approximate_match_type(ham_key_t *key)
-{
- if (key && (ham_key_get_intflags(key) & BtreeKey::kApproximate)) {
- int rv = (ham_key_get_intflags(key) & BtreeKey::kLower) ? -1 : +1;
- return (rv);
- }
-
- return (0);
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_insert(ham_db_t *hdb, ham_txn_t *htxn, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- Database *db = (Database *)hdb;
- Transaction *txn = (Transaction *)htxn;
- Environment *env;
-
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return HAM_INV_PARAMETER;
- }
- env = db->get_env();
-
- ScopedLock lock;
- if (!(flags & HAM_DONT_LOCK))
- lock = ScopedLock(env->mutex());
-
- if (!key) {
- ham_trace(("parameter 'key' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (!record) {
- ham_trace(("parameter 'record' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_APPEND) {
- ham_trace(("flags HAM_HINT_APPEND is only allowed in "
- "ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_PREPEND) {
- ham_trace(("flags HAM_HINT_PREPEND is only allowed in "
- "ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (db->get_flags() & HAM_READ_ONLY) {
- ham_trace(("cannot insert in a read-only database"));
- return (db->set_error(HAM_WRITE_PROTECTED));
- }
- if ((flags & HAM_OVERWRITE) && (flags & HAM_DUPLICATE)) {
- ham_trace(("cannot combine HAM_OVERWRITE and HAM_DUPLICATE"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_PARTIAL)
- && (db->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("flag HAM_PARTIAL is not allowed in combination with "
- "transactions"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_PARTIAL) && (record->size <= sizeof(uint64_t))) {
- ham_trace(("flag HAM_PARTIAL is not allowed if record->size "
- "<= 8"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_PARTIAL)
- && (record->partial_size + record->partial_offset > record->size)) {
- ham_trace(("partial offset+size is greater than the total "
- "record size"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_DUPLICATE)
- && !(db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS)) {
- ham_trace(("database does not support duplicate keys "
- "(see HAM_ENABLE_DUPLICATE_KEYS)"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_DUPLICATE_INSERT_AFTER)
- || (flags & HAM_DUPLICATE_INSERT_BEFORE)
- || (flags & HAM_DUPLICATE_INSERT_LAST)
- || (flags & HAM_DUPLICATE_INSERT_FIRST)) {
- ham_trace(("function does not support flags HAM_DUPLICATE_INSERT_*; "
- "see ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- if (!__prepare_key(key) || !__prepare_record(record))
- return (db->set_error(HAM_INV_PARAMETER));
-
- /* allocate temp. storage for a recno key */
- if ((db->get_flags() & HAM_RECORD_NUMBER32)
- || (db->get_flags() & HAM_RECORD_NUMBER64)) {
- if (flags & HAM_OVERWRITE) {
- if (!key->data) {
- ham_trace(("key->data must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- }
- else {
- if (key->flags & HAM_KEY_USER_ALLOC) {
- if (!key->data) {
- ham_trace(("key->data must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- }
- else {
- if (key->data || key->size) {
- ham_trace(("key->size must be 0, key->data must be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- }
- }
- }
-
- return (db->set_error(db->insert(0, txn, key, record, flags)));
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_erase(ham_db_t *hdb, ham_txn_t *htxn, ham_key_t *key, uint32_t flags)
-{
- Database *db = (Database *)hdb;
- Transaction *txn = (Transaction *)htxn;
- Environment *env;
-
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- env = db->get_env();
-
- ScopedLock lock;
- if (!(flags & HAM_DONT_LOCK))
- lock = ScopedLock(env->mutex());
-
- if (!key) {
- ham_trace(("parameter 'key' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_PREPEND) {
- ham_trace(("flag HAM_HINT_PREPEND is only allowed in "
- "ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_APPEND) {
- ham_trace(("flag HAM_HINT_APPEND is only allowed in "
- "ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (db->get_flags() & HAM_READ_ONLY) {
- ham_trace(("cannot erase from a read-only database"));
- return (HAM_WRITE_PROTECTED);
- }
-
- if (!__prepare_key(key))
- return (db->set_error(HAM_INV_PARAMETER));
-
- return (db->set_error(db->erase(0, txn, key, flags)));
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_check_integrity(ham_db_t *hdb, uint32_t flags)
-{
- Database *db = (Database *)hdb;
-
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- if (flags && flags != HAM_PRINT_GRAPH) {
- ham_trace(("unknown flag 0x%u", flags));
- return (HAM_INV_PARAMETER);
- }
-
- ScopedLock lock(db->get_env()->mutex());
-
- return (db->set_error(db->check_integrity(flags)));
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_db_close(ham_db_t *hdb, uint32_t flags)
-{
- Database *db = (Database *)hdb;
-
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- if ((flags & HAM_TXN_AUTO_ABORT) && (flags & HAM_TXN_AUTO_COMMIT)) {
- ham_trace(("invalid combination of flags: HAM_TXN_AUTO_ABORT + "
- "HAM_TXN_AUTO_COMMIT"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- Environment *env = db->get_env();
-
- /* it's ok to close an uninitialized Database */
- if (!env) {
- delete db;
- return (0);
- }
-
- return (env->close_db(db, flags));
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_create(ham_cursor_t **hcursor, ham_db_t *hdb, ham_txn_t *htxn,
- uint32_t flags)
-{
- Database *db = (Database *)hdb;
- Transaction *txn = (Transaction *)htxn;
- Environment *env;
- Cursor **cursor = 0;
-
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- cursor = (Cursor **)hcursor;
- env = db->get_env();
-
- ScopedLock lock;
- if (!(flags & HAM_DONT_LOCK))
- lock = ScopedLock(env->mutex());
-
- return (db->set_error(db->cursor_create(cursor, txn, flags)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_clone(ham_cursor_t *hsrc, ham_cursor_t **hdest)
-{
- Database *db;
-
- if (!hsrc) {
- ham_trace(("parameter 'src' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!hdest) {
- ham_trace(("parameter 'dest' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *src, **dest;
- src = (Cursor *)hsrc;
- dest = (Cursor **)hdest;
-
- db = src->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- return (db->set_error(db->cursor_clone(dest, src)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_overwrite(ham_cursor_t *hcursor, ham_record_t *record,
- uint32_t flags)
-{
- Database *db;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- if (flags) {
- ham_trace(("function does not support a non-zero flags value; "
- "see ham_cursor_insert for an alternative then"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (!record) {
- ham_trace(("parameter 'record' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (!__prepare_record(record))
- return (db->set_error(HAM_INV_PARAMETER));
- if (db->get_flags() & HAM_READ_ONLY) {
- ham_trace(("cannot overwrite in a read-only database"));
- return (db->set_error(HAM_WRITE_PROTECTED));
- }
-
- return (db->set_error(db->cursor_overwrite(cursor, record, flags)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_move(ham_cursor_t *hcursor, ham_key_t *key,
- ham_record_t *record, uint32_t flags)
-{
- Database *db;
- Environment *env;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- if ((flags & HAM_ONLY_DUPLICATES) && (flags & HAM_SKIP_DUPLICATES)) {
- ham_trace(("combination of HAM_ONLY_DUPLICATES and "
- "HAM_SKIP_DUPLICATES not allowed"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- env = db->get_env();
-
- if ((flags & HAM_DIRECT_ACCESS)
- && !(env->get_flags() & HAM_IN_MEMORY)) {
- ham_trace(("flag HAM_DIRECT_ACCESS is only allowed in "
- "In-Memory Databases"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_DIRECT_ACCESS)
- && (env->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("flag HAM_DIRECT_ACCESS is not allowed in "
- "combination with Transactions"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_PARTIAL)
- && (db->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("flag HAM_PARTIAL is not allowed in combination with "
- "transactions"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- if (key && !__prepare_key(key))
- return (db->set_error(HAM_INV_PARAMETER));
- if (record && !__prepare_record(record))
- return (db->set_error(HAM_INV_PARAMETER));
-
- return (db->set_error(db->cursor_move(cursor, key, record, flags)));
-}
-
-HAM_EXPORT ham_status_t HAM_CALLCONV
-ham_cursor_find(ham_cursor_t *hcursor, ham_key_t *key, ham_record_t *record,
- uint32_t flags)
-{
- Database *db;
- Environment *env;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
- env = db->get_env();
-
- ScopedLock lock;
- if (!(flags & HAM_DONT_LOCK))
- lock = ScopedLock(env->mutex());
-
- if (!key) {
- ham_trace(("parameter 'key' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_DIRECT_ACCESS)
- && !(env->get_flags() & HAM_IN_MEMORY)) {
- ham_trace(("flag HAM_DIRECT_ACCESS is only allowed in "
- "In-Memory Databases"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_DIRECT_ACCESS)
- && (env->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("flag HAM_DIRECT_ACCESS is not allowed in "
- "combination with Transactions"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_PREPEND) {
- ham_trace(("flag HAM_HINT_PREPEND is only allowed in "
- "ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_APPEND) {
- ham_trace(("flag HAM_HINT_APPEND is only allowed in "
- "ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_PARTIAL)
- && (db->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("flag HAM_PARTIAL is not allowed in combination with "
- "transactions"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- if (key && !__prepare_key(key))
- return (db->set_error(HAM_INV_PARAMETER));
- if (record && !__prepare_record(record))
- return (db->set_error(HAM_INV_PARAMETER));
-
- return (db->set_error(db->find(cursor, cursor->get_txn(),
- key, record, flags)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_insert(ham_cursor_t *hcursor, ham_key_t *key, ham_record_t *record,
- uint32_t flags)
-{
- Database *db;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- if (!key) {
- ham_trace(("parameter 'key' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (!record) {
- ham_trace(("parameter 'record' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags&HAM_HINT_APPEND) && (flags&HAM_HINT_PREPEND)) {
- ham_trace(("flags HAM_HINT_APPEND and HAM_HINT_PREPEND "
- "are mutually exclusive"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (!__prepare_key(key) || !__prepare_record(record))
- return (db->set_error(HAM_INV_PARAMETER));
-
- if (db->get_flags() & HAM_READ_ONLY) {
- ham_trace(("cannot insert to a read-only database"));
- return (db->set_error(HAM_WRITE_PROTECTED));
- }
- if ((flags & HAM_DUPLICATE) && (flags & HAM_OVERWRITE)) {
- ham_trace(("cannot combine HAM_DUPLICATE and HAM_OVERWRITE"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_DUPLICATE)
- && !(db->get_flags() & HAM_ENABLE_DUPLICATE_KEYS)) {
- ham_trace(("database does not support duplicate keys "
- "(see HAM_ENABLE_DUPLICATE_KEYS)"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_PARTIAL)
- && (db->get_flags() & HAM_ENABLE_TRANSACTIONS)) {
- ham_trace(("flag HAM_PARTIAL is not allowed in combination with "
- "transactions"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags&HAM_PARTIAL)
- && (record->partial_size + record->partial_offset > record->size)) {
- ham_trace(("partial offset+size is greater than the total "
- "record size"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if ((flags & HAM_PARTIAL) && (record->size <= sizeof(uint64_t))) {
- ham_trace(("flag HAM_PARTIAL is not allowed if record->size <= 8"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- /*
- * set flag HAM_DUPLICATE if one of DUPLICATE_INSERT* is set, but do
- * not allow these flags if duplicate sorting is enabled
- */
- if (flags & (HAM_DUPLICATE_INSERT_AFTER
- | HAM_DUPLICATE_INSERT_BEFORE
- | HAM_DUPLICATE_INSERT_LAST
- | HAM_DUPLICATE_INSERT_FIRST)) {
- flags |= HAM_DUPLICATE;
- }
-
- /* allocate temp. storage for a recno key */
- if ((db->get_flags() & HAM_RECORD_NUMBER32)
- || (db->get_flags() & HAM_RECORD_NUMBER64)) {
- if (flags & HAM_OVERWRITE) {
- if (!key->data) {
- ham_trace(("key->data must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- }
- else {
- if (key->flags & HAM_KEY_USER_ALLOC) {
- if (!key->data) {
- ham_trace(("key->data must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- }
- else {
- if (key->data || key->size) {
- ham_trace(("key->size must be 0, key->data must be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- }
- }
- }
-
- return (db->set_error(db->insert(cursor, cursor->get_txn(), key,
- record, flags)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_erase(ham_cursor_t *hcursor, uint32_t flags)
-{
- Database *db;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- if (db->get_flags() & HAM_READ_ONLY) {
- ham_trace(("cannot erase from a read-only database"));
- return (db->set_error(HAM_WRITE_PROTECTED));
- }
- if (flags & HAM_HINT_PREPEND) {
- ham_trace(("flags HAM_HINT_PREPEND only allowed in ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
- if (flags & HAM_HINT_APPEND) {
- ham_trace(("flags HAM_HINT_APPEND only allowed in ham_cursor_insert"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- return (db->set_error(db->erase(cursor, cursor->get_txn(), 0, flags)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_get_duplicate_count(ham_cursor_t *hcursor, uint32_t *count,
- uint32_t flags)
-{
- Database *db;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- if (!count) {
- ham_trace(("parameter 'count' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- return (db->set_error(db->cursor_get_record_count(cursor, flags, count)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_get_duplicate_position(ham_cursor_t *hcursor, uint32_t *position)
-{
- Database *db;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- if (!position) {
- ham_trace(("parameter 'position' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- return (db->set_error(db->cursor_get_duplicate_position(cursor, position)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_get_record_size(ham_cursor_t *hcursor, uint64_t *size)
-{
- Database *db;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- if (!size) {
- ham_trace(("parameter 'size' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- return (db->set_error(db->cursor_get_record_size(cursor, size)));
-}
-
-ham_status_t HAM_CALLCONV
-ham_cursor_close(ham_cursor_t *hcursor)
-{
- Database *db;
-
- if (!hcursor) {
- ham_trace(("parameter 'cursor' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Cursor *cursor = (Cursor *)hcursor;
-
- db = cursor->get_db();
-
- ScopedLock lock(db->get_env()->mutex());
-
- return (db->set_error(db->cursor_close(cursor)));
-}
-
-void HAM_CALLCONV
-ham_set_context_data(ham_db_t *hdb, void *data)
-{
- Database *db = (Database *)hdb;
-
- if (!db)
- return;
-
- ScopedLock lock(db->get_env()->mutex());
- db->set_context_data(data);
-}
-
-void * HAM_CALLCONV
-ham_get_context_data(ham_db_t *hdb, ham_bool_t dont_lock)
-{
- Database *db = (Database *)hdb;
- if (!db)
- return (0);
-
- if (dont_lock)
- return (db->get_context_data());
-
- ScopedLock lock(db->get_env()->mutex());
- return (db->get_context_data());
-}
-
-ham_db_t * HAM_CALLCONV
-ham_cursor_get_database(ham_cursor_t *hcursor)
-{
- if (hcursor) {
- Cursor *cursor = (Cursor *)hcursor;
- return ((ham_db_t *)cursor->get_db());
- }
- return (0);
-}
-
-ham_env_t * HAM_CALLCONV
-ham_db_get_env(ham_db_t *hdb)
-{
- Database *db = (Database *)hdb;
- if (!db)
- return (0);
-
- return ((ham_env_t *)db->get_env());
-}
-
-ham_status_t HAM_CALLCONV
-ham_db_get_key_count(ham_db_t *hdb, ham_txn_t *htxn, uint32_t flags,
- uint64_t *keycount)
-{
- Database *db = (Database *)hdb;
- Transaction *txn = (Transaction *)htxn;
-
- if (!db) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (flags & ~(HAM_SKIP_DUPLICATES)) {
- ham_trace(("parameter 'flag' contains unsupported flag bits: %08x",
- flags & (~HAM_SKIP_DUPLICATES)));
- return (HAM_INV_PARAMETER);
- }
- if (!keycount) {
- ham_trace(("parameter 'keycount' must not be NULL"));
- return (db->set_error(HAM_INV_PARAMETER));
- }
-
- ScopedLock lock(db->get_env()->mutex());
-
- return (db->set_error(db->count(txn, (flags & HAM_SKIP_DUPLICATES) != 0,
- keycount)));
-}
-
-void HAM_CALLCONV
-ham_set_errhandler(ham_errhandler_fun f)
-{
- if (f)
- hamsterdb::Globals::ms_error_handler = f;
- else
- hamsterdb::Globals::ms_error_handler = hamsterdb::default_errhandler;
-}
-
-ham_status_t HAM_CALLCONV
-ham_env_get_metrics(ham_env_t *henv, ham_env_metrics_t *metrics)
-{
- Environment *env = (Environment *)henv;
- if (!env) {
- ham_trace(("parameter 'env' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!metrics) {
- ham_trace(("parameter 'metrics' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- memset(metrics, 0, sizeof(ham_env_metrics_t));
- metrics->version = HAM_METRICS_VERSION;
-
- // fill in memory metrics
- Memory::get_global_metrics(metrics);
- // ... and everything else
- return (env->fill_metrics(metrics));
-}
-
-ham_bool_t HAM_CALLCONV
-ham_is_debug()
-{
-#ifdef HAM_DEBUG
- return (HAM_TRUE);
-#else
- return (HAM_FALSE);
-#endif
-}
-
-ham_bool_t HAM_CALLCONV
-ham_is_pro()
-{
- return (HAM_FALSE);
-}
-
-uint32_t HAM_CALLCONV
-ham_is_pro_evaluation()
-{
- return (0);
-}
diff --git a/plugins/Dbx_kv/src/hamsterdb/src/5hamsterdb/hola.cc b/plugins/Dbx_kv/src/hamsterdb/src/5hamsterdb/hola.cc
deleted file mode 100644
index a5a56a1814..0000000000
--- a/plugins/Dbx_kv/src/hamsterdb/src/5hamsterdb/hola.cc
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
- * Copyright (C) 2005-2015 Christoph Rupp (chris@crupp.de).
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "0root/root.h"
-
-#include "ham/hamsterdb_ola.h"
-
-// Always verify that a file of level N does not include headers > N!
-#include "1base/error.h"
-#include "3btree/btree_visitor.h"
-#include "4db/db.h"
-#include "4db/db_local.h"
-
-#ifndef HAM_ROOT_H
-# error "root.h was not included"
-#endif
-
-using namespace hamsterdb;
-
-ham_status_t HAM_CALLCONV
-hola_count(ham_db_t *hdb, ham_txn_t *htxn, hola_result_t *result)
-{
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!result) {
- ham_trace(("parameter 'result' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Database *db = (Database *)hdb;
- Transaction *txn = (Transaction *)htxn;
-
- result->type = HAM_TYPE_UINT64;
- result->u.result_u64 = 0;
-
- ScopedLock lock(db->get_env()->mutex());
- return (db->set_error(db->count(txn, false, &result->u.result_u64)));
-}
-
-//
-// A ScanVisitor for hola_count_if
-//
-template<typename PodType>
-struct CountIfScanVisitor : public ScanVisitor {
- CountIfScanVisitor(hola_bool_predicate_t *pred)
- : m_count(0), m_pred(pred) {
- }
-
- // Operates on a single key
- virtual void operator()(const void *key_data, uint16_t key_size,
- size_t duplicate_count) {
- if (m_pred->predicate_func(key_data, key_size, m_pred->context))
- m_count++;
- }
-
- // Operates on an array of keys
- virtual void operator()(const void *key_array, size_t key_count) {
- const PodType *p = (const PodType *)key_array;
- const PodType *end = &p[key_count];
- for (; p < end; p++) {
- if (m_pred->predicate_func(p, sizeof(PodType), m_pred->context))
- m_count++;
- }
- }
-
- // Assigns the result to |result|
- virtual void assign_result(hola_result_t *result) {
- memcpy(&result->u.result_u64, &m_count, sizeof(uint64_t));
- }
-
- // The counter
- uint64_t m_count;
-
- // The user's predicate
- hola_bool_predicate_t *m_pred;
-};
-
-//
-// A ScanVisitor for hola_count_if on binary keys
-//
-struct CountIfScanVisitorBinary : public ScanVisitor {
- CountIfScanVisitorBinary(size_t key_size, hola_bool_predicate_t *pred)
- : m_count(0), m_key_size(key_size), m_pred(pred) {
- }
-
- // Operates on a single key
- virtual void operator()(const void *key_data, uint16_t key_size,
- size_t duplicate_count) {
- if (m_pred->predicate_func(key_data, key_size, m_pred->context))
- m_count++;
- }
-
- // Operates on an array of keys
- virtual void operator()(const void *key_array, size_t key_count) {
- assert(m_key_size != HAM_KEY_SIZE_UNLIMITED);
- const uint8_t *p = (const uint8_t *)key_array;
- const uint8_t *end = &p[key_count * m_key_size];
- for (; p < end; p += m_key_size) {
- if (m_pred->predicate_func(p, m_key_size, m_pred->context))
- m_count++;
- }
- }
-
- // Assigns the result to |result|
- virtual void assign_result(hola_result_t *result) {
- memcpy(&result->u.result_u64, &m_count, sizeof(uint64_t));
- }
-
- // The counter
- uint64_t m_count;
-
- // The key size
- uint16_t m_key_size;
-
- // The user's predicate
- hola_bool_predicate_t *m_pred;
-};
-
-ham_status_t HAM_CALLCONV
-hola_count_if(ham_db_t *hdb, ham_txn_t *txn, hola_bool_predicate_t *pred,
- hola_result_t *result)
-{
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!pred) {
- ham_trace(("parameter 'pred' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!result) {
- ham_trace(("parameter 'result' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- // Remote databases are not yet supported
- LocalDatabase *db = dynamic_cast<LocalDatabase *>((Database *)hdb);
- if (!db) {
- ham_trace(("hola_* functions are not yet supported for remote databases"));
- return (HAM_INV_PARAMETER);
- }
-
- std::auto_ptr<ScanVisitor> visitor;
- result->u.result_u64 = 0;
- result->type = HAM_TYPE_UINT64;
-
- switch (db->config().key_type) {
- case HAM_TYPE_UINT8:
- visitor.reset(new CountIfScanVisitor<uint8_t>(pred));
- break;
- case HAM_TYPE_UINT16:
- visitor.reset(new CountIfScanVisitor<uint16_t>(pred));
- break;
- case HAM_TYPE_UINT32:
- visitor.reset(new CountIfScanVisitor<uint32_t>(pred));
- break;
- case HAM_TYPE_UINT64:
- visitor.reset(new CountIfScanVisitor<uint64_t>(pred));
- break;
- case HAM_TYPE_REAL32:
- visitor.reset(new CountIfScanVisitor<float>(pred));
- break;
- case HAM_TYPE_REAL64:
- visitor.reset(new CountIfScanVisitor<double>(pred));
- break;
- case HAM_TYPE_BINARY:
- visitor.reset(new CountIfScanVisitorBinary(db->config().key_size,
- pred));
- break;
- default:
- ham_assert(!"shouldn't be here");
- return (HAM_INV_PARAMETER);
- }
-
- ScopedLock lock(db->get_env()->mutex());
- ham_status_t st = db->scan((Transaction *)txn, visitor.get(), false);
- if (st == 0)
- visitor->assign_result(result);
- return (db->set_error(st));
-}
-
-ham_status_t HAM_CALLCONV
-hola_count_distinct(ham_db_t *hdb, ham_txn_t *htxn, hola_result_t *result)
-{
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!result) {
- ham_trace(("parameter 'result' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- Database *db = (Database *)hdb;
- Transaction *txn = (Transaction *)htxn;
-
- result->type = HAM_TYPE_UINT64;
- result->u.result_u64 = 0;
-
- ScopedLock lock(db->get_env()->mutex());
- return (db->set_error(db->count(txn, true, &result->u.result_u64)));
-}
-
-ham_status_t HAM_CALLCONV
-hola_count_distinct_if(ham_db_t *hdb, ham_txn_t *txn,
- hola_bool_predicate_t *pred, hola_result_t *result)
-{
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!pred) {
- ham_trace(("parameter 'pred' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!result) {
- ham_trace(("parameter 'result' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- // Remote databases are not yet supported
- LocalDatabase *db = dynamic_cast<LocalDatabase *>((Database *)hdb);
- if (!db) {
- ham_trace(("hola_* functions are not yet supported for remote databases"));
- return (HAM_INV_PARAMETER);
- }
-
- std::auto_ptr<ScanVisitor> visitor;
- result->u.result_u64 = 0;
- result->type = HAM_TYPE_UINT64;
-
- switch (db->config().key_type) {
- case HAM_TYPE_UINT8:
- visitor.reset(new CountIfScanVisitor<uint8_t>(pred));
- break;
- case HAM_TYPE_UINT16:
- visitor.reset(new CountIfScanVisitor<uint16_t>(pred));
- break;
- case HAM_TYPE_UINT32:
- visitor.reset(new CountIfScanVisitor<uint32_t>(pred));
- break;
- case HAM_TYPE_UINT64:
- visitor.reset(new CountIfScanVisitor<uint64_t>(pred));
- break;
- case HAM_TYPE_REAL32:
- visitor.reset(new CountIfScanVisitor<float>(pred));
- break;
- case HAM_TYPE_REAL64:
- visitor.reset(new CountIfScanVisitor<double>(pred));
- break;
- case HAM_TYPE_BINARY:
- visitor.reset(new CountIfScanVisitorBinary(db->config().key_size,
- pred));
- break;
- default:
- ham_assert(!"shouldn't be here");
- return (HAM_INV_PARAMETER);
- }
-
- ScopedLock lock(db->get_env()->mutex());
- ham_status_t st = db->scan((Transaction *)txn, visitor.get(), true);
- if (st == 0)
- visitor->assign_result(result);
- return (db->set_error(st));
-}
-
-//
-// A ScanVisitor for hola_average
-//
-template<typename PodType, typename ResultType>
-struct AverageScanVisitor : public ScanVisitor {
- AverageScanVisitor()
- : m_sum(0), m_count(0) {
- }
-
- // Operates on a single key
- virtual void operator()(const void *key_data, uint16_t key_size,
- size_t duplicate_count) {
- ham_assert(key_size == sizeof(PodType));
-
- m_sum += *(const PodType *)key_data * duplicate_count;
- m_count++;
- }
-
- // Operates on an array of keys
- virtual void operator()(const void *key_array, size_t key_count) {
- const PodType *p = (const PodType *)key_array;
- const PodType *end = &p[key_count];
- for (; p < end; p++)
- m_sum += *p;
- m_count += key_count;
- }
-
- // Assigns the result to |result|
- virtual void assign_result(hola_result_t *result) {
- ResultType res = m_sum / m_count;
- memcpy(&result->u.result_u64, &res, sizeof(uint64_t));
- }
-
- // The sum of all keys
- ResultType m_sum;
-
- // For counting the keys
- uint64_t m_count;
-};
-
-ham_status_t HAM_CALLCONV
-hola_average(ham_db_t *hdb, ham_txn_t *txn, hola_result_t *result)
-{
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!result) {
- ham_trace(("parameter 'result' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- // Remote databases are not yet supported
- LocalDatabase *db = dynamic_cast<LocalDatabase *>((Database *)hdb);
- if (!db) {
- ham_trace(("hola_* functions are not yet supported for remote databases"));
- return (HAM_INV_PARAMETER);
- }
-
- std::auto_ptr<ScanVisitor> visitor;
- result->u.result_u64 = 0;
-
- switch (db->config().key_type) {
- case HAM_TYPE_UINT8:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new AverageScanVisitor<uint8_t, uint64_t>());
- break;
- case HAM_TYPE_UINT16:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new AverageScanVisitor<uint16_t, uint64_t>());
- break;
- case HAM_TYPE_UINT32:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new AverageScanVisitor<uint32_t, uint64_t>());
- break;
- case HAM_TYPE_UINT64:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new AverageScanVisitor<uint64_t, uint64_t>());
- break;
- case HAM_TYPE_REAL32:
- result->type = HAM_TYPE_REAL64;
- visitor.reset(new AverageScanVisitor<float, double>());
- break;
- case HAM_TYPE_REAL64:
- result->type = HAM_TYPE_REAL64;
- visitor.reset(new AverageScanVisitor<double, double>());
- break;
- default:
- ham_trace(("hola_avg* can only be applied to numerical data"));
- return (HAM_INV_PARAMETER);
- }
-
- ScopedLock lock(db->get_env()->mutex());
- ham_status_t st = db->scan((Transaction *)txn, visitor.get(), false);
- if (st == 0)
- visitor->assign_result(result);
- return (db->set_error(st));
-}
-
-//
-// A ScanVisitor for hola_average_if
-//
-template<typename PodType, typename ResultType>
-struct AverageIfScanVisitor : public ScanVisitor {
- AverageIfScanVisitor(hola_bool_predicate_t *pred)
- : m_sum(0), m_count(0), m_pred(pred) {
- }
-
- // Operates on a single key
- virtual void operator()(const void *key_data, uint16_t key_size,
- size_t duplicate_count) {
- ham_assert(key_size == sizeof(PodType));
-
- if (m_pred->predicate_func(key_data, key_size, m_pred->context)) {
- m_sum += *(const PodType *)key_data * duplicate_count;
- m_count++;
- }
- }
-
- // Operates on an array of keys
- virtual void operator()(const void *key_array, size_t key_count) {
- const PodType *p = (const PodType *)key_array;
- const PodType *end = &p[key_count];
- for (; p < end; p++) {
- if (m_pred->predicate_func(p, sizeof(PodType), m_pred->context)) {
- m_sum += *p;
- m_count++;
- }
- }
- }
-
- // Assigns the result to |result|
- virtual void assign_result(hola_result_t *result) {
- ResultType res = m_sum / m_count;
- memcpy(&result->u.result_u64, &res, sizeof(uint64_t));
- }
-
- // The sum of all keys
- ResultType m_sum;
-
- // For counting the keys
- uint64_t m_count;
-
- // The user's predicate function
- hola_bool_predicate_t *m_pred;
-};
-
-ham_status_t HAM_CALLCONV
-hola_average_if(ham_db_t *hdb, ham_txn_t *txn, hola_bool_predicate_t *pred,
- hola_result_t *result)
-{
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!pred) {
- ham_trace(("parameter 'pred' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!result) {
- ham_trace(("parameter 'result' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- // Remote databases are not yet supported
- LocalDatabase *db = dynamic_cast<LocalDatabase *>((Database *)hdb);
- if (!db) {
- ham_trace(("hola_* functions are not yet supported for remote databases"));
- return (HAM_INV_PARAMETER);
- }
-
- std::auto_ptr<ScanVisitor> visitor;
- result->u.result_u64 = 0;
-
- switch (db->config().key_type) {
- case HAM_TYPE_UINT8:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new AverageIfScanVisitor<uint8_t, uint64_t>(pred));
- break;
- case HAM_TYPE_UINT16:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new AverageIfScanVisitor<uint16_t, uint64_t>(pred));
- break;
- case HAM_TYPE_UINT32:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new AverageIfScanVisitor<uint32_t, uint64_t>(pred));
- break;
- case HAM_TYPE_UINT64:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new AverageIfScanVisitor<uint64_t, uint64_t>(pred));
- break;
- case HAM_TYPE_REAL32:
- result->type = HAM_TYPE_REAL64;
- visitor.reset(new AverageIfScanVisitor<float, double>(pred));
- break;
- case HAM_TYPE_REAL64:
- result->type = HAM_TYPE_REAL64;
- visitor.reset(new AverageIfScanVisitor<double, double>(pred));
- break;
- default:
- ham_trace(("hola_avg* can only be applied to numerical data"));
- return (HAM_INV_PARAMETER);
- }
-
- ScopedLock lock(db->get_env()->mutex());
- ham_status_t st = db->scan((Transaction *)txn, visitor.get(), false);
- if (st == 0)
- visitor->assign_result(result);
- return (db->set_error(st));
-}
-
-//
-// A ScanVisitor for hola_sum
-//
-template<typename PodType, typename ResultType>
-struct SumScanVisitor : public ScanVisitor {
- SumScanVisitor()
- : m_sum(0) {
- }
-
- // Operates on a single key
- virtual void operator()(const void *key_data, uint16_t key_size,
- size_t duplicate_count) {
- ham_assert(key_size == sizeof(PodType));
- m_sum += *(const PodType *)key_data * duplicate_count;
- }
-
- // Operates on an array of keys
- virtual void operator()(const void *key_array, size_t key_count) {
- const PodType *p = (const PodType *)key_array;
- const PodType *end = &p[key_count];
- const int kMax = 8;
- ResultType sums[kMax] = {0};
- for (; p + kMax < end; p += kMax) {
-#if defined __GNUC__
- __builtin_prefetch(((char *)p) + kMax * sizeof(PodType));
-#endif
- sums[0] += p[0];
- sums[1] += p[1];
- sums[2] += p[2];
- sums[3] += p[3];
- sums[4] += p[4];
- sums[5] += p[5];
- sums[6] += p[6];
- sums[7] += p[7];
- }
- for (; p < end; p++)
- m_sum += *p;
- for (int i = 0; i < kMax; i++)
- m_sum += sums[i];
- }
-
- // Assigns the result to |result|
- virtual void assign_result(hola_result_t *result) {
- memcpy(&result->u.result_u64, &m_sum, sizeof(uint64_t));
- }
-
- // The sum of all keys
- ResultType m_sum;
-};
-
-ham_status_t HAM_CALLCONV
-hola_sum(ham_db_t *hdb, ham_txn_t *txn, hola_result_t *result)
-{
- if (!hdb) {
- ham_trace(("parameter 'hdb' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!result) {
- ham_trace(("parameter 'result' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- std::auto_ptr<ScanVisitor> visitor;
- result->u.result_u64 = 0;
-
- // Remote databases are not yet supported
- LocalDatabase *db = dynamic_cast<LocalDatabase *>((Database *)hdb);
- if (!db) {
- ham_trace(("hola_* functions are not yet supported for remote databases"));
- return (HAM_INV_PARAMETER);
- }
-
- switch (db->config().key_type) {
- case HAM_TYPE_UINT8:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new SumScanVisitor<uint8_t, uint64_t>());
- break;
- case HAM_TYPE_UINT16:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new SumScanVisitor<uint16_t, uint64_t>());
- break;
- case HAM_TYPE_UINT32:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new SumScanVisitor<uint32_t, uint64_t>());
- break;
- case HAM_TYPE_UINT64:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new SumScanVisitor<uint64_t, uint64_t>());
- break;
- case HAM_TYPE_REAL32:
- result->type = HAM_TYPE_REAL64;
- visitor.reset(new SumScanVisitor<float, double>());
- break;
- case HAM_TYPE_REAL64:
- result->type = HAM_TYPE_REAL64;
- visitor.reset(new SumScanVisitor<double, double>());
- break;
- default:
- ham_trace(("hola_sum* can only be applied to numerical data"));
- return (HAM_INV_PARAMETER);
- }
-
- ScopedLock lock(db->get_env()->mutex());
- ham_status_t st = db->scan((Transaction *)txn, visitor.get(), false);
- if (st == 0)
- visitor->assign_result(result);
- return (db->set_error(st));
-}
-
-//
-// A ScanVisitor for hola_sum_if
-//
-template<typename PodType, typename ResultType>
-struct SumIfScanVisitor : public ScanVisitor {
- SumIfScanVisitor(hola_bool_predicate_t *pred)
- : m_sum(0), m_pred(pred) {
- }
-
- // Operates on a single key
- virtual void operator()(const void *key_data, uint16_t key_size,
- size_t duplicate_count) {
- ham_assert(key_size == sizeof(PodType));
-
- if (m_pred->predicate_func(key_data, key_size, m_pred->context))
- m_sum += *(const PodType *)key_data * duplicate_count;
- }
-
- // Operates on an array of keys
- virtual void operator()(const void *key_array, size_t key_count) {
- const PodType *p = (const PodType *)key_array;
- const PodType *end = &p[key_count];
- for (; p < end; p++) {
- if (m_pred->predicate_func(p, sizeof(PodType), m_pred->context))
- m_sum += *p;
- }
- }
-
- // Assigns the result to |result|
- virtual void assign_result(hola_result_t *result) {
- memcpy(&result->u.result_u64, &m_sum, sizeof(uint64_t));
- }
-
- // The sum of all keys
- ResultType m_sum;
-
- // The user's predicate function
- hola_bool_predicate_t *m_pred;
-};
-
-ham_status_t HAM_CALLCONV
-hola_sum_if(ham_db_t *hdb, ham_txn_t *txn, hola_bool_predicate_t *pred,
- hola_result_t *result)
-{
- if (!hdb) {
- ham_trace(("parameter 'db' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!pred) {
- ham_trace(("parameter 'pred' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
- if (!result) {
- ham_trace(("parameter 'result' must not be NULL"));
- return (HAM_INV_PARAMETER);
- }
-
- // Remote databases are not yet supported
- LocalDatabase *db = dynamic_cast<LocalDatabase *>((Database *)hdb);
- if (!db) {
- ham_trace(("hola_* functions are not yet supported for remote databases"));
- return (HAM_INV_PARAMETER);
- }
-
- std::auto_ptr<ScanVisitor> visitor;
- result->u.result_u64 = 0;
-
- switch (db->config().key_type) {
- case HAM_TYPE_UINT8:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new SumIfScanVisitor<uint8_t, uint64_t>(pred));
- break;
- case HAM_TYPE_UINT16:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new SumIfScanVisitor<uint16_t, uint64_t>(pred));
- break;
- case HAM_TYPE_UINT32:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new SumIfScanVisitor<uint32_t, uint64_t>(pred));
- break;
- case HAM_TYPE_UINT64:
- result->type = HAM_TYPE_UINT64;
- visitor.reset(new SumIfScanVisitor<uint64_t, uint64_t>(pred));
- break;
- case HAM_TYPE_REAL32:
- result->type = HAM_TYPE_REAL64;
- visitor.reset(new SumIfScanVisitor<float, double>(pred));
- break;
- case HAM_TYPE_REAL64:
- result->type = HAM_TYPE_REAL64;
- visitor.reset(new SumIfScanVisitor<double, double>(pred));
- break;
- default:
- ham_trace(("hola_sum* can only be applied to numerical data"));
- return (HAM_INV_PARAMETER);
- }
-
- ScopedLock lock(db->get_env()->mutex());
- ham_status_t st = db->scan((Transaction *)txn, visitor.get(), false);
- if (st == 0)
- visitor->assign_result(result);
- return (db->set_error(st));
-}
diff --git a/plugins/Dbx_kv/src/init.cpp b/plugins/Dbx_kv/src/init.cpp
deleted file mode 100644
index 520b5f9ec5..0000000000
--- a/plugins/Dbx_kv/src/init.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "commonheaders.h"
-
-#if _MSC_VER >= 1800
- #ifdef _DEBUG
- #pragma comment(lib, "libboost_thread-vc120-mt-gd-1_57.lib")
- #pragma comment(lib, "libboost_system-vc120-mt-gd-1_57.lib")
- #else
- #pragma comment(lib, "libboost_thread-vc120-mt-1_57.lib")
- #pragma comment(lib, "libboost_system-vc120-mt-1_57.lib")
- #endif
-#else
- #ifdef _DEBUG
- #pragma comment(lib, "libboost_thread-vc100-mt-gd-1_57.lib")
- #pragma comment(lib, "libboost_system-vc100-mt-gd-1_57.lib")
- #else
- #pragma comment(lib, "libboost_thread-vc100-mt-1_57.lib")
- #pragma comment(lib, "libboost_system-vc100-mt-1_57.lib")
- #endif
-#endif
-
-int hLangpack;
-
-static PLUGININFOEX pluginInfo =
-{
- sizeof(PLUGININFOEX),
- __PLUGIN_NAME,
- PLUGIN_MAKE_VERSION(__MAJOR_VERSION, __MINOR_VERSION, __RELEASE_NUM, __BUILD_NUM),
- __DESCRIPTION,
- __AUTHOR,
- __AUTHOREMAIL,
- __COPYRIGHT,
- __AUTHORWEB,
- UNICODE_AWARE | STATIC_PLUGIN,
- // {7C3D0A33-2646-4001-9107-F35EA299D292}
- { 0x7c3d0a33, 0x2646, 0x4001, { 0x91, 0x7, 0xf3, 0x5e, 0xa2, 0x99, 0xd2, 0x92 } }
-};
-
-HINSTANCE g_hInst = NULL;
-
-LIST<CDbxKV> g_Dbs(1, HandleKeySortT);
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-// returns 0 if the profile is created, EMKPRF*
-static int makeDatabase(const TCHAR *profile)
-{
- std::auto_ptr<CDbxKV> db(new CDbxKV(profile, 0));
- return db->Create();
-}
-
-// returns 0 if the given profile has a valid header
-static int grokHeader(const TCHAR *profile)
-{
- std::auto_ptr<CDbxKV> db(new CDbxKV(profile, DBMODE_SHARED | DBMODE_READONLY));
- return db->Check();
-}
-
-// returns 0 if all the APIs are injected otherwise, 1
-static MIDatabase* LoadDatabase(const TCHAR *profile, BOOL bReadOnly)
-{
- // set the memory, lists & UTF8 manager
- mir_getLP(&pluginInfo);
-
- std::auto_ptr<CDbxKV> db(new CDbxKV(profile, (bReadOnly) ? DBMODE_READONLY : 0));
- if (db->Load(false) != ERROR_SUCCESS)
- return NULL;
-
- g_Dbs.insert(db.get());
- return db.release();
-}
-
-static int UnloadDatabase(MIDatabase *db)
-{
- g_Dbs.remove((CDbxKV*)db);
- delete (CDbxKV*)db;
- return 0;
-}
-
-MIDatabaseChecker* CheckDb(const TCHAR *profile, int *error)
-{
- std::auto_ptr<CDbxKV> db(new CDbxKV(profile, DBMODE_READONLY));
- if (db->Load(true) != ERROR_SUCCESS) {
- *error = ERROR_ACCESS_DENIED;
- return NULL;
- }
-
- if (db->PrepareCheck(error))
- return NULL;
-
- return db.release();
-}
-
-static DATABASELINK dblink =
-{
- sizeof(DATABASELINK),
- "dbx_kv",
- L"Hamsterdb database driver",
- makeDatabase,
- grokHeader,
- LoadDatabase,
- UnloadDatabase,
- CheckDb
-};
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD)
-{
- return &pluginInfo;
-}
-
-extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_DATABASE, MIID_LAST };
-
-extern "C" __declspec(dllexport) int Load(void)
-{
- RegisterDatabasePlugin(&dblink);
- return 0;
-}
-
-extern "C" __declspec(dllexport) int Unload(void)
-{
- return 0;
-}
-
-BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD, LPVOID)
-{
- g_hInst = hInstDLL;
- return TRUE;
-}
diff --git a/plugins/Dbx_kv/src/resource.h b/plugins/Dbx_kv/src/resource.h
deleted file mode 100644
index be74c3e5e8..0000000000
--- a/plugins/Dbx_kv/src/resource.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by D:\Myranda\plugins\Db3x_mmap\res\db3x_mmap.rc
-//
-
-#define IDREMOVE 3
-
-#define IDI_ICONPASS 100
-#define IDI_LOGO 101
-#define IDD_LOGIN 102
-#define IDD_NEWPASS 103
-#define IDD_CHANGEPASS 104
-#define IDD_OPTIONS 105
-#define IDC_HEADERBAR 1001
-#define IDC_LANG 1002
-#define IDC_USERPASS 1003
-#define IDC_USERPASS1 1004
-#define IDC_USERPASS2 1005
-#define IDC_OLDPASS 1006
-#define IDC_STANDARD 1007
-#define IDC_TOTAL 1008
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 106
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1009
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
diff --git a/plugins/Dbx_kv/src/stdafx.cpp b/plugins/Dbx_kv/src/stdafx.cpp
deleted file mode 100644
index dd87776a41..0000000000
--- a/plugins/Dbx_kv/src/stdafx.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-Copyright (C) 2012-17 Miranda NG project (https://miranda-ng.org)
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation version 2
-of the License.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "commonheaders.h" \ No newline at end of file
diff --git a/plugins/Dbx_kv/src/ui.cpp b/plugins/Dbx_kv/src/ui.cpp
deleted file mode 100644
index 7f758137e2..0000000000
--- a/plugins/Dbx_kv/src/ui.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
-
-Miranda NG: the free IM client for Microsoft* Windows*
-
-Copyright (ñ) 2012-17 Miranda NG project (https://miranda-ng.org)
-all portions of this codebase are copyrighted to the people
-listed in contributors.txt.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "commonheaders.h"
-
-struct DlgChangePassParam
-{
- CDbxKV *db;
- TCHAR newPass[100];
- int wrongPass;
-};
-
-#define MS_DB_CHANGEPASSWORD "DB/UI/ChangePassword"
-
-static IconItem iconList[] =
-{
- { LPGEN("Logo"), "logo", IDI_LOGO },
- { LPGEN("Password"), "password", IDI_ICONPASS }
-};
-
-static HGENMENU hSetPwdMenu;
-
-static UINT oldLangID;
-void LanguageChanged(HWND hwndDlg)
-{
- UINT LangID = (UINT)GetKeyboardLayout(0);
- char Lang[3] = { 0 };
- if (LangID != oldLangID) {
- oldLangID = LangID;
- GetLocaleInfoA(MAKELCID((LangID & 0xffffffff), SORT_DEFAULT), LOCALE_SABBREVLANGNAME, Lang, 2);
- Lang[0] = toupper(Lang[0]);
- Lang[1] = tolower(Lang[1]);
- SetDlgItemTextA(hwndDlg, IDC_LANG, Lang);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static INT_PTR CALLBACK sttEnterPassword(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- DlgChangePassParam *param = (DlgChangePassParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (uMsg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- SendDlgItemMessage(hwndDlg, IDC_HEADERBAR, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(g_hInst, MAKEINTRESOURCE(iconList[0].defIconID)));
-
- param = (DlgChangePassParam*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
-
- if (param->wrongPass) {
- if (param->wrongPass > 2) {
- HWND hwndCtrl = GetDlgItem(hwndDlg, IDC_USERPASS);
- EnableWindow(hwndCtrl, FALSE);
- hwndCtrl = GetDlgItem(hwndDlg, IDOK);
- EnableWindow(hwndCtrl, FALSE);
- SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Too many errors!"));
- }
- else SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Password is not correct!"));
- }
- else SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Please type in your password"));
-
- oldLangID = 0;
- SetTimer(hwndDlg, 1, 200, NULL);
- LanguageChanged(hwndDlg);
- return TRUE;
-
- case WM_CTLCOLORSTATIC:
- if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_LANG)) {
- SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT));
- SetBkMode((HDC)wParam, TRANSPARENT);
- return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT);
- }
- return FALSE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDCANCEL:
- EndDialog(hwndDlg, IDCANCEL);
- break;
-
- case IDOK:
- GetDlgItemText(hwndDlg, IDC_USERPASS, param->newPass, SIZEOF(param->newPass));
- EndDialog(hwndDlg, IDOK);
- }
- break;
-
- case WM_TIMER:
- LanguageChanged(hwndDlg);
- return FALSE;
-
- case WM_DESTROY:
- KillTimer(hwndDlg, 1);
- DestroyIcon((HICON)SendMessage(hwndDlg, WM_GETICON, ICON_SMALL, 0));
- }
-
- return FALSE;
-}
-
-bool CDbxKV::EnterPassword(const BYTE *pKey, const size_t keyLen)
-{
- DlgChangePassParam param = { this };
- while (true) {
- // Esc pressed
- if (IDOK != DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_LOGIN), 0, sttEnterPassword, (LPARAM)&param))
- return false;
-
- m_crypto->setPassword(ptrA(mir_utf8encodeT(param.newPass)));
- if (m_crypto->setKey(pKey, keyLen)) {
- m_bUsesPassword = true;
- SecureZeroMemory(&param, sizeof(param));
- return true;
- }
-
- param.wrongPass++;
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-static bool CheckOldPassword(HWND hwndDlg, CDbxKV *db)
-{
- if (db->usesPassword()) {
- TCHAR buf[100];
- GetDlgItemText(hwndDlg, IDC_OLDPASS, buf, SIZEOF(buf));
- ptrA oldPass(mir_utf8encodeT(buf));
- if (!db->m_crypto->checkPassword(oldPass)) {
- SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Wrong old password entered!"));
- return false;
- }
- }
- return true;
-}
-
-static INT_PTR CALLBACK sttChangePassword(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- DlgChangePassParam *param = (DlgChangePassParam*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
- TCHAR buf[100];
-
- switch (uMsg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- SendDlgItemMessage(hwndDlg, IDC_HEADERBAR, WM_SETICON, ICON_SMALL, (LPARAM)Skin_GetIconByHandle(iconList[0].hIcolib, true));
-
- param = (DlgChangePassParam*)lParam;
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
-
- oldLangID = 0;
- SetTimer(hwndDlg, 1, 200, NULL);
- LanguageChanged(hwndDlg);
- return TRUE;
-
- case WM_CTLCOLORSTATIC:
- if ((HWND)lParam == GetDlgItem(hwndDlg, IDC_LANG)) {
- SetTextColor((HDC)wParam, GetSysColor(COLOR_HIGHLIGHTTEXT));
- SetBkMode((HDC)wParam, TRANSPARENT);
- return (BOOL)GetSysColorBrush(COLOR_HIGHLIGHT);
- }
- return FALSE;
-
- case WM_COMMAND:
- switch (LOWORD(wParam)) {
- case IDCANCEL:
- EndDialog(hwndDlg, IDCANCEL);
- break;
-
- case IDREMOVE:
- if (!CheckOldPassword(hwndDlg, param->db)) {
- LBL_Error:
- SendDlgItemMessage(hwndDlg, IDC_HEADERBAR, WM_NCPAINT, 0, 0);
- SetDlgItemTextA(hwndDlg, IDC_USERPASS1, "");
- SetDlgItemTextA(hwndDlg, IDC_USERPASS2, "");
- }
- else {
- // param->db->WriteSignature(dbSignatureU);
- param->db->SetPassword(NULL);
- param->db->StoreKey();
- EndDialog(hwndDlg, IDREMOVE);
- }
- break;
-
- case IDOK:
- TCHAR buf2[100];
- GetDlgItemText(hwndDlg, IDC_USERPASS1, buf2, SIZEOF(buf2));
- if (_tcslen(buf2) < 3) {
- SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Password is too short!"));
- goto LBL_Error;
- }
-
- GetDlgItemText(hwndDlg, IDC_USERPASS2, buf, SIZEOF(buf));
- if (_tcscmp(buf2, buf)) {
- SetDlgItemText(hwndDlg, IDC_HEADERBAR, TranslateT("Passwords do not match!"));
- goto LBL_Error;
- }
-
- if (!CheckOldPassword(hwndDlg, param->db))
- goto LBL_Error;
-
- // param->db->WriteSignature(dbSignatureE);
- param->db->SetPassword(buf2);
- param->db->StoreKey();
- SecureZeroMemory(buf2, sizeof(buf2));
- EndDialog(hwndDlg, IDOK);
- }
- break;
-
- case WM_TIMER:
- LanguageChanged(hwndDlg);
- return FALSE;
-
- case WM_DESTROY:
- KillTimer(hwndDlg, 1);
- Skin_ReleaseIcon((HICON)SendMessage(hwndDlg, WM_GETICON, ICON_SMALL, 0));
- }
-
- return FALSE;
-}
-
-static INT_PTR ChangePassword(void* obj, WPARAM, LPARAM)
-{
- CDbxKV *db = (CDbxKV*)obj;
- DlgChangePassParam param = { db };
- DialogBoxParam(g_hInst, MAKEINTRESOURCE(db->usesPassword() ? IDD_CHANGEPASS : IDD_NEWPASS), 0, sttChangePassword, (LPARAM)&param);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-INT_PTR CALLBACK DlgProcOptions(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- CDbxKV *db = (CDbxKV *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
-
- switch (msg) {
- case WM_INITDIALOG:
- TranslateDialogDefault(hwndDlg);
- SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
-
- db = (CDbxKV*)lParam;
- CheckRadioButton(hwndDlg, IDC_STANDARD, IDC_TOTAL, IDC_STANDARD + db->isEncrypted());
- return TRUE;
-
- case WM_COMMAND:
- if (HIWORD(wParam) == BN_CLICKED && (HWND)lParam == GetFocus()) {
- if (LOWORD(wParam) == IDC_USERPASS)
- CallService(MS_DB_CHANGEPASSWORD, 0, 0);
- else
- SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
- }
- break;
-
- case WM_NOTIFY:
- if (((LPNMHDR)lParam)->code == PSN_APPLY) {
- if (IsDlgButtonChecked(hwndDlg, IDC_TOTAL) != (UINT)db->isEncrypted()) {
- db->ToggleEncryption();
- CheckRadioButton(hwndDlg, IDC_STANDARD, IDC_TOTAL, IDC_STANDARD + db->isEncrypted());
- }
- break;
- }
- break;
- }
-
- return FALSE;
-}
-
-static int OnOptionsInit(PVOID obj, WPARAM wParam, LPARAM)
-{
- OPTIONSDIALOGPAGE odp = { sizeof(odp) };
- odp.position = -790000000;
- odp.hInstance = g_hInst;
- odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
- odp.flags = ODPF_BOLDGROUPS;
- odp.pszTitle = LPGEN("Database");
- odp.pfnDlgProc = DlgProcOptions;
- odp.dwInitParam = (LPARAM)obj;
- Options_AddPage(wParam, &odp);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CDbxKV::UpdateMenuItem()
-{
- CLISTMENUITEM mi = { sizeof(mi) };
- mi.flags = CMIM_NAME;
- mi.icolibItem = iconList[1].hIcolib;
- mi.pszName = GetMenuTitle();
- Menu_ModifyItem(hSetPwdMenu, &mi);
-}
-
-static int OnModulesLoaded(PVOID obj, WPARAM, LPARAM)
-{
- CDbxKV *db = (CDbxKV*)obj;
-
- Icon_Register(g_hInst, LPGEN("Database"), iconList, SIZEOF(iconList), "mmap");
-
- HookEventObj(ME_OPT_INITIALISE, OnOptionsInit, db);
-
- // main menu item
- CLISTMENUITEM mi = { sizeof(mi) };
- mi.pszName = LPGEN("Database");
- mi.position = 500000000;
- mi.flags = CMIF_ROOTHANDLE;
- mi.icolibItem = iconList[0].hIcolib;
- HGENMENU hMenuRoot = Menu_AddMainMenuItem(&mi);
-
- mi.icolibItem = iconList[1].hIcolib;
- mi.pszName = db->GetMenuTitle();
- mi.hParentMenu = hMenuRoot;
- mi.pszService = MS_DB_CHANGEPASSWORD;
- hSetPwdMenu = Menu_AddMainMenuItem(&mi);
- return 0;
-}
-
-/////////////////////////////////////////////////////////////////////////////////////////
-
-void CDbxKV::InitDialogs()
-{
- hService = CreateServiceFunctionObj(MS_DB_CHANGEPASSWORD, ChangePassword, this);
- hHook = HookEventObj(ME_SYSTEM_MODULESLOADED, OnModulesLoaded, this);
-}
diff --git a/plugins/Dbx_kv/src/version.h b/plugins/Dbx_kv/src/version.h
deleted file mode 100644
index cde18f0ce8..0000000000
--- a/plugins/Dbx_kv/src/version.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#define __MAJOR_VERSION 0
-#define __MINOR_VERSION 95
-#define __RELEASE_NUM 4
-#define __BUILD_NUM 1
-
-#include <stdver.h>
-
-#define __PLUGIN_NAME "Miranda NG Hamsterdb database driver"
-#define __FILENAME "Dbx_kv.dll"
-#define __DESCRIPTION "Provides Miranda database support: global settings, contacts, history, settings per contact."
-#define __AUTHOR "Miranda-NG project"
-#define __AUTHOREMAIL "ghazan@miranda.im"
-#define __AUTHORWEB "https://miranda-ng.org/p/Dbx_kv/"
-#define __COPYRIGHT "© 2015-17 Miranda NG project"