* Changed "lookup" to "get" just because
* Added copyright notices to files * Added Apache 2.0 License file with permission from Kresten/Trifork * Changed the handle from "Db" to "Tree" because... it made me feel better * Other minor changes here and there
This commit is contained in:
parent
e6e3b55d23
commit
b325f3e792
22 changed files with 595 additions and 128 deletions
178
LICENSE
Normal file
178
LICENSE
Normal file
|
@ -0,0 +1,178 @@
|
|||
|
||||
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
|
||||
|
10
Makefile
10
Makefile
|
@ -5,6 +5,8 @@ DIALYZER = dialyzer
|
|||
|
||||
all: compile
|
||||
|
||||
deps: get-deps
|
||||
|
||||
get-deps:
|
||||
@$(REBAR) get-deps
|
||||
|
||||
|
@ -14,6 +16,8 @@ compile:
|
|||
clean:
|
||||
@$(REBAR) clean
|
||||
|
||||
test: eunit
|
||||
|
||||
eunit: compile clean-test-btrees
|
||||
@$(REBAR) eunit skip_deps=true
|
||||
|
||||
|
@ -24,7 +28,7 @@ clean-test-btrees:
|
|||
rm -fr .eunit/Btree_* .eunit/simple
|
||||
|
||||
plt: compile
|
||||
$(DIALYZER) --build_plt --output_plt .fractal_btree.plt \
|
||||
$(DIALYZER) --build_plt --output_plt .lsm_btree.plt \
|
||||
-pa deps/plain_fsm/ebin \
|
||||
-pa deps/ebloom/ebin \
|
||||
deps/plain_fsm/ebin \
|
||||
|
@ -32,8 +36,10 @@ plt: compile
|
|||
--apps kernel stdlib
|
||||
|
||||
analyze: compile
|
||||
$(DIALYZER) --plt .fractal_btree.plt \
|
||||
$(DIALYZER) --plt .lsm_btree.plt \
|
||||
-pa deps/plain_fsm/ebin \
|
||||
-pa deps/ebloom/ebin \
|
||||
ebin
|
||||
|
||||
repl:
|
||||
elr -pz deps/*/ebin -pa ebin
|
||||
|
|
18
README.md
18
README.md
|
@ -1,5 +1,3 @@
|
|||
> **NOTE** I erroneously called this engine `fractal_btree` when first released, but I have since learned that what we have implemented is indeed much less sophisticated than Tokutek's Fractal Tree®. Hence, the name change to `lsm_btree`.
|
||||
|
||||
# LSM B-Tree Storage
|
||||
|
||||
This erlang-based storage engine implements a structure somewhat like LSM-trees (Log-Structured Merge Trees). The notes below describe how this storage engine work; I have not done extensive studies as how it differs from other storage mechanisms, but a brief brows through available online resources on LSM-trees and Fractal Trees indicates that this storage engine is quite different in several respects.
|
||||
|
@ -57,10 +55,16 @@ A further trouble is that merging does in fact not have completely linear I/O co
|
|||
Merging can be going on concurrently at each level (in preparation for an injection to the next level), which lets you utilize available multi-core capacity to merge.
|
||||
|
||||
|
||||
### LSM B-Trees vs. Fractal Trees
|
||||
LSM B-Trees bear some resemblance with so-called "Fractal Trees®", but LSM B-Trees are much simpler. For instance, our LSM B-Tree does not use any in-place updating (in a Fractal Tree, inner nodes have a buffer space which is updated-in place); also we use bloom filters rather than fractional cascading to speed up multiple B-tree lookups. From published online documents, it does indeed look like fractal trees can be *much* faster (I have not run any performance tests myself).
|
||||
|
||||
You can read more about Fractal Trees in this slide deck from [Tokutek](http://www.tokutek.com/2011/11/how-fractal-trees-work-at-mit-today/), a company providing a MySQL backend based on Fractal Trees. They also own some patents related to fractal trees. I have not tried their TokuDB, but it looks truly amazing; I recommend that you try it out if you're hitting the limits of your current MySQL setup.
|
||||
|
||||
### Deploying the lsm_btree for testing with Riak/KV
|
||||
|
||||
You can deploy `lsm_btree` into a Riak devrel cluster using the
|
||||
`enable-lsm_btree` script. Clone the `riak` repo, change your working directory
|
||||
to it, and then execute the `enable-lsm_btree` script. It adds `lsm_btree` as a
|
||||
dependency, runs `make all devrel`, and then modifies the configuration
|
||||
settings of the resulting dev nodes to use the lsm_btree storage backend.
|
||||
|
||||
1. `git clone git://github.com/basho/riak.git`
|
||||
1. `cd riak/deps`
|
||||
1. `git clone git://github.com/basho/lsm_btree.git`
|
||||
1. `cd ..`
|
||||
1. `./deps/lsm_btree/enable-lsm_btree` # which does `make all devrel`
|
||||
|
|
|
@ -48,6 +48,6 @@ make all devrel
|
|||
|
||||
echo
|
||||
echo 'Modifying all dev/dev*/etc/app.config files, saving originals with .orig suffix...'
|
||||
perl -i.orig -ne 'if (/\bstorage_backend,/) { s/(storage_backend, )[^\}]+/\1riak_kv_lsmbtree_backend/; print } elsif (/\{eleveldb,/) { $eleveldb++; print } elsif ($eleveldb && /^\s+\]\},/) { $eleveldb = 0; print; print qq(\n {lsm_btree, [\n {data_root, "./data/lb"}\n ]},\n\n) } else { print }' dev/dev*/etc/app.config
|
||||
perl -i.orig -ne 'if (/\bstorage_backend,/) { s/(storage_backend, )[^\}]+/\1riak_kv_lsm_btree_backend/; print } elsif (/\{eleveldb,/) { $eleveldb++; print } elsif ($eleveldb && /^\s+\]\},/) { $eleveldb = 0; print; print qq(\n {lsm_btree, [\n {data_root, "./data/lsm_btree"}\n ]},\n\n) } else { print }' dev/dev*/etc/app.config
|
||||
|
||||
exit 0
|
||||
|
|
|
@ -28,7 +28,7 @@ new(_Id) ->
|
|||
|
||||
%% Get the target directory
|
||||
Dir = basho_bench_config:get(lsm_btree_dir, "."),
|
||||
Filename = filename:join(Dir, "test.frac"),
|
||||
Filename = filename:join(Dir, "test.lsm_btree"),
|
||||
|
||||
%% Look for sync interval config
|
||||
case basho_bench_config:get(lsm_btree_sync_interval, infinity) of
|
||||
|
@ -72,4 +72,3 @@ run(delete, KeyGen, _ValueGen, State) ->
|
|||
{error, Reason} ->
|
||||
{error, Reason}
|
||||
end.
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{application, lsm_btree,
|
||||
[
|
||||
{description, ""},
|
||||
{vsn, "1"},
|
||||
{vsn, "1.0.0"},
|
||||
{registered, []},
|
||||
{applications, [
|
||||
kernel,
|
||||
stdlib
|
||||
]},
|
||||
{mod, { lsm_btree_app, []}},
|
||||
{mod, {lsm_btree_app, []}},
|
||||
{env, []}
|
||||
]}.
|
||||
|
|
|
@ -1,11 +1,43 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
|
||||
-behavior(gen_server).
|
||||
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-export([open/1, close/1, lookup/2, delete/2, put/3, async_range/3, async_fold_range/5, sync_range/3, sync_fold_range/5]).
|
||||
-export([open/1, open/2,
|
||||
close/1,
|
||||
get/2,
|
||||
put/3,
|
||||
delete/2,
|
||||
async_range/3, async_fold_range/5,
|
||||
sync_range/3, sync_fold_range/5]).
|
||||
|
||||
-include("lsm_btree.hrl").
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
|
@ -17,6 +49,9 @@
|
|||
%% PUBLIC API
|
||||
|
||||
open(Dir) ->
|
||||
open(Dir, []).
|
||||
|
||||
open(Dir, Config) -> %TODO Config is currently ignored.
|
||||
gen_server:start(?MODULE, [Dir], []).
|
||||
|
||||
close(Ref) ->
|
||||
|
@ -29,9 +64,8 @@ close(Ref) ->
|
|||
exit:{normal, _} -> ok
|
||||
end.
|
||||
|
||||
|
||||
lookup(Ref,Key) when is_binary(Key) ->
|
||||
gen_server:call(Ref, {lookup, Key}).
|
||||
get(Ref,Key) when is_binary(Key) ->
|
||||
gen_server:call(Ref, {get, Key}).
|
||||
|
||||
delete(Ref,Key) when is_binary(Key) ->
|
||||
gen_server:call(Ref, {delete, Key}).
|
||||
|
@ -180,10 +214,10 @@ handle_call({delete, Key}, _From, State) when is_binary(Key) ->
|
|||
{ok, State2} = do_put(Key, ?TOMBSTONE, State),
|
||||
{reply, ok, State2};
|
||||
|
||||
handle_call({lookup, Key}, _From, State=#state{ top=Top, nursery=Nursery } ) when is_binary(Key) ->
|
||||
handle_call({get, Key}, _From, State=#state{ top=Top, nursery=Nursery } ) when is_binary(Key) ->
|
||||
case lsm_btree_nursery:lookup(Key, Nursery) of
|
||||
{value, ?TOMBSTONE} ->
|
||||
{reply, notfound, State};
|
||||
{reply, not_found, State};
|
||||
{value, Value} when is_binary(Value) ->
|
||||
{reply, {ok, Value}, State};
|
||||
none ->
|
||||
|
|
|
@ -1,3 +1,28 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
|
||||
%% smallest levels are 32 entries
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_app).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
-behaviour(application).
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
|
||||
{operations, [{get, 1}, {put, 1}]}.
|
||||
|
||||
%% the second element in the list below (e.g., "../../public/bitcask") must point to
|
||||
%% the relevant directory of a lsm_btree installation
|
||||
%% the second element in the list below (e.g., "../../public/bitcask") must point to
|
||||
%% the relevant directory of a lsm_btree installation
|
||||
{code_paths, ["deps/stats",
|
||||
"/Users/krab/Projects/lsm_btree/ebin",
|
||||
"/Users/krab/Projects/lsm_btree/deps/plain_fsm/ebin",
|
||||
"/Users/krab/Projects/lsm_btree/deps/ebloom/ebin"
|
||||
"../lsm_btree/ebin",
|
||||
"../lsm_btree/deps/plain_fsm/ebin",
|
||||
"../lsm_btree/deps/ebloom/ebin"
|
||||
]}.
|
||||
|
||||
{bitcask_dir, "/tmp/lsm_btree.bench"}.
|
||||
|
|
|
@ -1,4 +1,30 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_fold_worker).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
|
||||
%%
|
||||
%% This worker is used to merge fold results from individual
|
||||
|
@ -99,7 +125,6 @@ emit_next(State, []) ->
|
|||
ok;
|
||||
|
||||
emit_next(State, [{FirstPID,FirstKV}|Rest]=Values) ->
|
||||
|
||||
{{FoundKey, FoundValue}, FillFrom} =
|
||||
lists:foldl(fun({P,{K1,_}=KV}, {{K2,_},_}) when K1 < K2 ->
|
||||
{KV,[P]};
|
||||
|
@ -110,7 +135,6 @@ emit_next(State, [{FirstPID,FirstKV}|Rest]=Values) ->
|
|||
end,
|
||||
{FirstKV,[FirstPID]},
|
||||
Rest),
|
||||
|
||||
case FoundValue of
|
||||
?TOMBSTONE ->
|
||||
ok;
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_level).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
-include("lsm_btree.hrl").
|
||||
|
||||
|
@ -84,8 +109,8 @@ receive_reply(MRef) ->
|
|||
?REPLY(MRef, Reply) ->
|
||||
erlang:demonitor(MRef, [flush]),
|
||||
Reply;
|
||||
{'DOWN', MRef, _, _, Reason} ->
|
||||
exit(Reason)
|
||||
{'DOWN', MRef, _, _, Reason} ->
|
||||
exit(Reason)
|
||||
end.
|
||||
|
||||
call(PID,Request) ->
|
||||
|
@ -306,8 +331,8 @@ main_loop(State = #state{ next=Next }) ->
|
|||
%%
|
||||
%% Our successor died!
|
||||
%%
|
||||
{'DOWN', MRef, _, _, Reason} when MRef =:= State#state.inject_done_ref ->
|
||||
exit(Reason);
|
||||
{'DOWN', MRef, _, _, Reason} when MRef =:= State#state.inject_done_ref ->
|
||||
exit(Reason);
|
||||
|
||||
%% gen_fsm handling
|
||||
{system, From, Req} ->
|
||||
|
@ -337,9 +362,9 @@ do_lookup(Key, [undefined|Rest]) ->
|
|||
do_lookup(Key, Rest);
|
||||
do_lookup(Key, [BT|Rest]) ->
|
||||
case lsm_btree_reader:lookup(BT, Key) of
|
||||
{ok, ?TOMBSTONE} -> notfound;
|
||||
{ok, Result} -> {found, Result};
|
||||
notfound -> do_lookup(Key, Rest)
|
||||
{ok, ?TOMBSTONE} -> notfound;
|
||||
{ok, Result} -> {found, Result};
|
||||
notfound -> do_lookup(Key, Rest)
|
||||
end.
|
||||
|
||||
close_if_defined(undefined) -> ok;
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_merger).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
%%
|
||||
%% Merging two BTrees
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_nursery).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
-export([new/1, recover/2, add/3, finish/2, lookup/2, add_maybe_flush/4]).
|
||||
-export([do_level_fold/3]).
|
||||
|
@ -133,7 +158,7 @@ finish(#nursery{ dir=Dir, cache=Cache, log_file=LogFile, total_size=_TotalSize,
|
|||
end,
|
||||
|
||||
% {ok, FileInfo} = file:read_file_info(BTreeFileName),
|
||||
% error_logger:info_msg("dumping log (count=~p, size=~p, outsize=~p)~n",
|
||||
% error_logger:info_msg("dumping log (count=~p, size=~p, outsize=~p)~n",
|
||||
% [ gb_trees:size(Cache), TotalSize, FileInfo#file_info.size ]),
|
||||
|
||||
%% inject the B-Tree (blocking RPC)
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_reader).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
-include_lib("kernel/include/file.hrl").
|
||||
-include("include/lsm_btree.hrl").
|
||||
|
|
|
@ -1,5 +1,29 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_sup).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
-behaviour(supervisor).
|
||||
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_util).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
-compile(export_all).
|
||||
|
||||
|
|
|
@ -1,4 +1,29 @@
|
|||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright 2011-2012 (c) Trifork A/S. All Rights Reserved.
|
||||
%% http://trifork.com/ info@trifork.com
|
||||
%%
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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.
|
||||
%%
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(lsm_btree_writer).
|
||||
-author('Kresten Krab Thorup <krab@trifork.com>').
|
||||
|
||||
-include("lsm_btree.hrl").
|
||||
|
||||
|
@ -12,7 +37,7 @@
|
|||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-export([open/1, open/2, add/3,close/1]).
|
||||
|
||||
|
@ -122,7 +147,7 @@ flush_nodes(State) ->
|
|||
flush_nodes(State2).
|
||||
|
||||
add_record(Level, Key, Value,
|
||||
#state{ nodes=[ #node{level=Level, members=List, size=NodeSize}=CurrNode |RestNodes] }=State) ->
|
||||
#state{ nodes=[ #node{level=Level, members=List, size=NodeSize}=CurrNode |RestNodes] }=State) ->
|
||||
%% The top-of-stack node is at the level we wish to insert at.
|
||||
|
||||
%% Assert that keys are increasing:
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
%% -------------------------------------------------------------------
|
||||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% riak_kv_lsmbtree_backend: LSM-Btree Driver for Riak
|
||||
%% lsm_btree: LSM-trees (Log-Structured Merge Trees) Indexed Storage
|
||||
%%
|
||||
%% Copyright (c) 2012 Basho Technologies, Inc. All Rights Reserved.
|
||||
%% Copyright 2012 (c) Basho Technologies, Inc. All Rights Reserved.
|
||||
%% http://basho.com/ info@basho.com
|
||||
%%
|
||||
%% This file is provided to you 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
|
||||
%% This file is provided to you 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
|
||||
%% 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.
|
||||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
-module(riak_kv_lsmbtree_backend).
|
||||
-behavior(lsmbtree_riak_kv_backend).
|
||||
-module(riak_kv_lsm_btree_backend).
|
||||
-behavior(temp_riak_kv_backend).
|
||||
-author('Steve Vinoski <steve@basho.com>').
|
||||
-author('Greg Burd <greg@basho.com>').
|
||||
|
||||
%% KV Backend API
|
||||
-export([api_version/0,
|
||||
|
@ -50,7 +50,7 @@
|
|||
%%-define(CAPABILITIES, [async_fold, indexes]).
|
||||
-define(CAPABILITIES, [async_fold]).
|
||||
|
||||
-record(state, {db,
|
||||
-record(state, {tree,
|
||||
partition :: integer()}).
|
||||
|
||||
-type state() :: #state{}.
|
||||
|
@ -91,19 +91,19 @@ start(Partition, Config) ->
|
|||
{error, {already_started, _}} ->
|
||||
ok;
|
||||
{error, Reason} ->
|
||||
lager:error("Failed to start lsm_btree: ~p", [Reason]),
|
||||
lager:error("Failed to init the lsm_btree backend: ~p", [Reason]),
|
||||
{error, Reason}
|
||||
end,
|
||||
case AppStart of
|
||||
ok ->
|
||||
ok = filelib:ensure_dir(filename:join(DataRoot, "x")),
|
||||
DbName = filename:join(DataRoot, "lb" ++ integer_to_list(Partition)),
|
||||
DbName = filename:join(DataRoot, "lsm_btree" ++ integer_to_list(Partition)),
|
||||
case lsm_btree:open(DbName) of
|
||||
{ok, Db} ->
|
||||
{ok, #state{db=Db, partition=Partition}};
|
||||
{error, OpenReason}=OpenError ->
|
||||
lager:error("Failed to open lsm_btree: ~p\n", [OpenReason]),
|
||||
OpenError
|
||||
{ok, Tree} ->
|
||||
{ok, #state{tree=Tree, partition=Partition}};
|
||||
{error, OpenReason}=OpenError ->
|
||||
lager:error("Failed to open lsm_btree: ~p\n", [OpenReason]),
|
||||
OpenError
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
|
@ -112,20 +112,20 @@ start(Partition, Config) ->
|
|||
|
||||
%% @doc Stop the lsm_btree backend
|
||||
-spec stop(state()) -> ok.
|
||||
stop(#state{db=Db}) ->
|
||||
ok = lsm_btree:close(Db).
|
||||
stop(#state{tree=Tree}) ->
|
||||
ok = lsm_btree:close(Tree).
|
||||
|
||||
%% @doc Retrieve an object from the lsm_btree backend
|
||||
-spec get(riak_object:bucket(), riak_object:key(), state()) ->
|
||||
{ok, any(), state()} |
|
||||
{ok, not_found, state()} |
|
||||
{error, term(), state()}.
|
||||
get(Bucket, Key, #state{db=Db}=State) ->
|
||||
LBKey = to_object_key(Bucket, Key),
|
||||
case lsm_btree:lookup(Db, LBKey) of
|
||||
get(Bucket, Key, #state{tree=Tree}=State) ->
|
||||
Key = to_object_key(Bucket, Key),
|
||||
case lsm_btree:get(Tree, Key) of
|
||||
{ok, Value} ->
|
||||
{ok, Value, State};
|
||||
notfound ->
|
||||
not_found ->
|
||||
{error, not_found, State};
|
||||
{error, Reason} ->
|
||||
{error, Reason, State}
|
||||
|
@ -136,18 +136,18 @@ get(Bucket, Key, #state{db=Db}=State) ->
|
|||
-spec put(riak_object:bucket(), riak_object:key(), [index_spec()], binary(), state()) ->
|
||||
{ok, state()} |
|
||||
{error, term(), state()}.
|
||||
put(Bucket, PrimaryKey, _IndexSpecs, Val, #state{db=Db}=State) ->
|
||||
LBKey = to_object_key(Bucket, PrimaryKey),
|
||||
ok = lsm_btree:put(Db, LBKey, Val),
|
||||
put(Bucket, PrimaryKey, _IndexSpecs, Val, #state{tree=Tree}=State) ->
|
||||
Key = to_object_key(Bucket, PrimaryKey),
|
||||
ok = lsm_btree:put(Tree, Key, Val),
|
||||
{ok, State}.
|
||||
|
||||
%% @doc Delete an object from the lsm_btree backend
|
||||
-spec delete(riak_object:bucket(), riak_object:key(), [index_spec()], state()) ->
|
||||
{ok, state()} |
|
||||
{error, term(), state()}.
|
||||
delete(Bucket, Key, _IndexSpecs, #state{db=Db}=State) ->
|
||||
LBKey = to_object_key(Bucket, Key),
|
||||
case lsm_btree:delete(Db, LBKey) of
|
||||
delete(Bucket, Key, _IndexSpecs, #state{tree=Tree}=State) ->
|
||||
Key = to_object_key(Bucket, Key),
|
||||
case lsm_btree:delete(Tree, Key) of
|
||||
ok ->
|
||||
{ok, State};
|
||||
{error, Reason} ->
|
||||
|
@ -159,12 +159,12 @@ delete(Bucket, Key, _IndexSpecs, #state{db=Db}=State) ->
|
|||
any(),
|
||||
[],
|
||||
state()) -> {ok, any()} | {async, fun()}.
|
||||
fold_buckets(FoldBucketsFun, Acc, Opts, #state{db=Db}) ->
|
||||
fold_buckets(FoldBucketsFun, Acc, Opts, #state{tree=Tree}) ->
|
||||
FoldFun = fold_buckets_fun(FoldBucketsFun),
|
||||
BucketFolder =
|
||||
fun() ->
|
||||
try
|
||||
lsm_btree:sync_fold_range(Db, FoldFun, {Acc, []}, undefined, undefined)
|
||||
lsm_btree:sync_fold_range(Tree, FoldFun, {Acc, []}, undefined, undefined)
|
||||
catch
|
||||
{break, AccFinal} ->
|
||||
AccFinal
|
||||
|
@ -182,7 +182,7 @@ fold_buckets(FoldBucketsFun, Acc, Opts, #state{db=Db}) ->
|
|||
any(),
|
||||
[{atom(), term()}],
|
||||
state()) -> {ok, term()} | {async, fun()}.
|
||||
fold_keys(FoldKeysFun, Acc, Opts, #state{db=Db}) ->
|
||||
fold_keys(FoldKeysFun, Acc, Opts, #state{tree=Tree}) ->
|
||||
%% Figure out how we should limit the fold: by bucket, by
|
||||
%% secondary index, or neither (fold across everything.)
|
||||
Bucket = lists:keyfind(bucket, 1, Opts),
|
||||
|
@ -200,7 +200,7 @@ fold_keys(FoldKeysFun, Acc, Opts, #state{db=Db}) ->
|
|||
KeyFolder =
|
||||
fun() ->
|
||||
try
|
||||
lsm_btree:sync_fold_range(Db, FoldFun, Acc, undefined, undefined)
|
||||
lsm_btree:sync_fold_range(Tree, FoldFun, Acc, undefined, undefined)
|
||||
catch
|
||||
{break, AccFinal} ->
|
||||
AccFinal
|
||||
|
@ -218,13 +218,13 @@ fold_keys(FoldKeysFun, Acc, Opts, #state{db=Db}) ->
|
|||
any(),
|
||||
[{atom(), term()}],
|
||||
state()) -> {ok, any()} | {async, fun()}.
|
||||
fold_objects(FoldObjectsFun, Acc, Opts, #state{db=Db}) ->
|
||||
fold_objects(FoldObjectsFun, Acc, Opts, #state{tree=Tree}) ->
|
||||
Bucket = proplists:get_value(bucket, Opts),
|
||||
FoldFun = fold_objects_fun(FoldObjectsFun, Bucket),
|
||||
ObjectFolder =
|
||||
fun() ->
|
||||
try
|
||||
lsm_btree:sync_fold_range(Db, FoldFun, Acc, undefined, undefined)
|
||||
lsm_btree:sync_fold_range(Tree, FoldFun, Acc, undefined, undefined)
|
||||
catch
|
||||
{break, AccFinal} ->
|
||||
AccFinal
|
||||
|
@ -246,13 +246,13 @@ drop(#state{}=State) ->
|
|||
%% @doc Returns true if this lsm_btree backend contains any
|
||||
%% non-tombstone values; otherwise returns false.
|
||||
-spec is_empty(state()) -> boolean().
|
||||
is_empty(#state{db=Db}) ->
|
||||
is_empty(#state{tree=Tree}) ->
|
||||
FoldFun = fun(_K, _V, _Acc) -> throw(ok) end,
|
||||
try
|
||||
[] =:= lsm_btree:sync_fold_range(Db, FoldFun, [], undefined, undefined)
|
||||
[] =:= lsm_btree:sync_fold_range(Tree, FoldFun, [], undefined, undefined)
|
||||
catch
|
||||
_:ok ->
|
||||
false
|
||||
_:ok ->
|
||||
false
|
||||
end.
|
||||
|
||||
%% @doc Get the status information for this lsm_btree backend
|
||||
|
@ -340,13 +340,13 @@ from_object_key(LKey) ->
|
|||
-ifdef(TEST).
|
||||
|
||||
simple_test_() ->
|
||||
?assertCmd("rm -rf test/lsmbtree-backend"),
|
||||
application:set_env(lsm_btree, data_root, "test/lsmbtree-backend"),
|
||||
lsmbtree_riak_kv_backend:standard_test(?MODULE, []).
|
||||
?assertCmd("rm -rf test/lsm_btree-backend"),
|
||||
application:set_env(lsm_btree, data_root, "test/lsm_btree-backend"),
|
||||
riak_kv_backend:standard_test(?MODULE, []).
|
||||
|
||||
custom_config_test_() ->
|
||||
?assertCmd("rm -rf test/lsmbtree-backend"),
|
||||
?assertCmd("rm -rf test/lsm_btree-backend"),
|
||||
application:set_env(lsm_btree, data_root, ""),
|
||||
lsmbtree_riak_kv_backend:standard_test(?MODULE, [{data_root, "test/lsmbtree-backend"}]).
|
||||
riak_kv_backend:standard_test(?MODULE, [{data_root, "test/lsm_btree-backend"}]).
|
||||
|
||||
-endif.
|
||||
|
|
|
@ -1,32 +1,30 @@
|
|||
%% -------------------------------------------------------------------
|
||||
%% ----------------------------------------------------------------------------
|
||||
%%
|
||||
%% lsmbtree_riak_kv_backend: temporary Riak backend behaviour
|
||||
%% riak_kv_backend: Riak backend behaviour
|
||||
%%
|
||||
%% Copyright (c) 2007-2010 Basho Technologies, Inc. All Rights Reserved.
|
||||
%% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved.
|
||||
%%
|
||||
%% This file is provided to you 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
|
||||
%% This file is provided to you 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
|
||||
%% 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.
|
||||
%%
|
||||
%% -------------------------------------------------------------------
|
||||
%% ----------------------------------------------------------------------------
|
||||
|
||||
%%% NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
|
||||
%%% NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
|
||||
%%%
|
||||
%%% This is a temporary copy of riak_kv_backend, just here to keep
|
||||
%%% wterl development private for now. When riak_kv_wterl_backend is
|
||||
%%% moved to riak_kv, delete this file.
|
||||
%%% This is a temporary copy of riak_kv_backend, just here to keep lsm_btree
|
||||
%%% development private for now. When riak_kv_lsm_btree_backend is moved to
|
||||
%%% riak_kv, delete this file.
|
||||
%%%
|
||||
%%% NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
|
||||
%%% NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
|
||||
|
||||
|
||||
-module(temp_riak_kv_backend).
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
-export([
|
||||
delete_exist/2,
|
||||
lookup_exist/2,
|
||||
lookup_fail/2,
|
||||
get_exist/2,
|
||||
get_fail/2,
|
||||
open/1, close/1,
|
||||
put/3,
|
||||
sync_range/3,
|
||||
|
@ -20,7 +20,7 @@
|
|||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
-define(SERVER, ?MODULE).
|
||||
|
||||
-record(state, { btrees = dict:new() % Map from a name to its tree
|
||||
}).
|
||||
|
@ -33,11 +33,11 @@ start_link() ->
|
|||
call(X) ->
|
||||
gen_server:call(?SERVER, X, infinity).
|
||||
|
||||
lookup_exist(N, K) ->
|
||||
call({lookup, N, K}).
|
||||
get_exist(N, K) ->
|
||||
call({get, N, K}).
|
||||
|
||||
lookup_fail(N, K) ->
|
||||
call({lookup, N, K}).
|
||||
get_fail(N, K) ->
|
||||
call({get, N, K}).
|
||||
|
||||
delete_exist(N, K) ->
|
||||
call({delete_exist, N, K}).
|
||||
|
@ -104,9 +104,9 @@ handle_call({delete_exist, N, K}, _, #state { btrees = D} = State) ->
|
|||
Tree = dict:fetch(N, D),
|
||||
Reply = lsm_btree:delete(Tree, K),
|
||||
{reply, Reply, State};
|
||||
handle_call({lookup, N, K}, _, #state { btrees = D} = State) ->
|
||||
handle_call({get, N, K}, _, #state { btrees = D} = State) ->
|
||||
Tree = dict:fetch(N, D),
|
||||
Reply = lsm_btree:lookup(Tree, K),
|
||||
Reply = lsm_btree:get(Tree, K),
|
||||
{reply, Reply, State};
|
||||
handle_call(stop, _, #state{ btrees = D } = State ) ->
|
||||
[ lsm_btree:close(Tree) || {_,Tree} <- dict:to_list(D) ],
|
||||
|
|
|
@ -119,9 +119,9 @@ command(#state { open = Open, closed = Closed } = S) ->
|
|||
|| open_dicts(S)]
|
||||
++ [ {2000, {call, ?SERVER, put, cmd_put_args(S)}}
|
||||
|| open_dicts(S)]
|
||||
++ [ {1500, {call, ?SERVER, lookup_fail, cmd_lookup_fail_args(S)}}
|
||||
++ [ {1500, {call, ?SERVER, get_fail, cmd_get_fail_args(S)}}
|
||||
|| open_dicts(S)]
|
||||
++ [ {1500, {call, ?SERVER, lookup_exist, cmd_lookup_args(S)}}
|
||||
++ [ {1500, {call, ?SERVER, get_exist, cmd_get_args(S)}}
|
||||
|| open_dicts(S), open_dicts_with_keys(S)]
|
||||
++ [ {500, {call, ?SERVER, delete_exist, cmd_delete_args(S)}}
|
||||
|| open_dicts(S), open_dicts_with_keys(S)]
|
||||
|
@ -138,9 +138,9 @@ precondition(S, {call, ?SERVER, sync_range, [_Tree, _K1, _K2]}) ->
|
|||
open_dicts(S) andalso open_dicts_with_keys(S);
|
||||
precondition(S, {call, ?SERVER, delete_exist, [_Name, _K]}) ->
|
||||
open_dicts(S) andalso open_dicts_with_keys(S);
|
||||
precondition(S, {call, ?SERVER, lookup_fail, [_Name, _K]}) ->
|
||||
precondition(S, {call, ?SERVER, get_fail, [_Name, _K]}) ->
|
||||
open_dicts(S);
|
||||
precondition(S, {call, ?SERVER, lookup_exist, [_Name, _K]}) ->
|
||||
precondition(S, {call, ?SERVER, get_exist, [_Name, _K]}) ->
|
||||
open_dicts(S) andalso open_dicts_with_keys(S);
|
||||
precondition(#state { open = Open }, {call, ?SERVER, put, [Name, _K, _V]}) ->
|
||||
dict:is_key(Name, Open);
|
||||
|
@ -156,16 +156,16 @@ next_state(S, _Res, {call, ?SERVER, sync_fold_range, [_Tree, _F, _A0, _K1, _K2]}
|
|||
S;
|
||||
next_state(S, _Res, {call, ?SERVER, sync_range, [_Tree, _K1, _K2]}) ->
|
||||
S;
|
||||
next_state(S, _Res, {call, ?SERVER, lookup_fail, [_Name, _Key]}) ->
|
||||
next_state(S, _Res, {call, ?SERVER, get_fail, [_Name, _Key]}) ->
|
||||
S;
|
||||
next_state(S, _Res, {call, ?SERVER, lookup_exist, [_Name, _Key]}) ->
|
||||
next_state(S, _Res, {call, ?SERVER, get_exist, [_Name, _Key]}) ->
|
||||
S;
|
||||
next_state(#state { open = Open} = S, _Res,
|
||||
{call, ?SERVER, delete_exist, [Name, Key]}) ->
|
||||
S#state { open = dict:update(Name,
|
||||
fun(#tree { elements = Dict}) ->
|
||||
#tree { elements =
|
||||
dict:erase(Key, Dict)}
|
||||
dict:erase(Key, Dict)}
|
||||
end,
|
||||
Open)};
|
||||
next_state(#state { open = Open} = S, _Res,
|
||||
|
@ -198,10 +198,10 @@ postcondition(#state { open = Open},
|
|||
lists:sort(dict_range_query(TDict, K1, K2))
|
||||
== lists:sort(Result);
|
||||
postcondition(_S,
|
||||
{call, ?SERVER, lookup_fail, [_Name, _Key]}, notfound) ->
|
||||
{call, ?SERVER, get_fail, [_Name, _Key]}, notfound) ->
|
||||
true;
|
||||
postcondition(#state { open = Open },
|
||||
{call, ?SERVER, lookup_exist, [Name, Key]}, {ok, Value}) ->
|
||||
{call, ?SERVER, get_exist, [Name, Key]}, {ok, Value}) ->
|
||||
#tree { elements = Elems } = dict:fetch(Name, Open),
|
||||
dict:fetch(Key, Elems) == Value;
|
||||
postcondition(_S, {call, ?SERVER, delete_exist, [_Name, _Key]}, ok) ->
|
||||
|
@ -237,7 +237,7 @@ prop_dict_agree() ->
|
|||
test_tree_simple_1() ->
|
||||
{ok, Tree} = lsm_btree:open("simple"),
|
||||
ok = lsm_btree:put(Tree, <<>>, <<"data", 77:128>>),
|
||||
{ok, <<"data", 77:128>>} = lsm_btree:lookup(Tree, <<>>),
|
||||
{ok, <<"data", 77:128>>} = lsm_btree:get(Tree, <<>>),
|
||||
ok = lsm_btree:close(Tree).
|
||||
|
||||
test_tree_simple_2() ->
|
||||
|
@ -264,7 +264,7 @@ test_tree_simple_4() ->
|
|||
Value = <<212,167,12,6,105,152,17,80,243>>,
|
||||
{ok, Tree} = lsm_btree:open("simple"),
|
||||
ok = lsm_btree:put(Tree, Key, Value),
|
||||
?assertEqual({ok, Value}, lsm_btree:lookup(Tree, Key)),
|
||||
?assertEqual({ok, Value}, lsm_btree:get(Tree, Key)),
|
||||
ok = lsm_btree:close(Tree).
|
||||
|
||||
test_tree() ->
|
||||
|
@ -327,12 +327,12 @@ cmd_put_args(#state { open = Open }) ->
|
|||
[Name, Key, Value]).
|
||||
|
||||
|
||||
cmd_lookup_fail_args(#state { open = Open}) ->
|
||||
cmd_get_fail_args(#state { open = Open}) ->
|
||||
?LET(Name, g_open_tree(Open),
|
||||
?LET(Key, g_non_existing_key(Name, Open),
|
||||
[Name, Key])).
|
||||
|
||||
cmd_lookup_args(#state { open = Open}) ->
|
||||
cmd_get_args(#state { open = Open}) ->
|
||||
?LET(Name, g_non_empty_btree(Open),
|
||||
?LET(Key, g_existing_key(Name, Open),
|
||||
[Name, Key])).
|
||||
|
|
Loading…
Reference in a new issue