Add note about migrating to the main repo
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 3164eee..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-.rebar
-ebin/
-*~
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 6a3648b..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-language: erlang
-
-otp_release:
-   - 21.2
-   - 20.3
-   - 19.3
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index f6cd2bc..0000000
--- a/LICENSE
+++ /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/Makefile b/Makefile
deleted file mode 100644
index 058a7ec..0000000
--- a/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-REBAR?=rebar
-
-
-.PHONY: all
-# target: all - Makes everything
-all: build
-
-
-.PHONY: build
-# target: build - Builds the project
-build:
-	$(REBAR) compile
-
-
-.PHONY: check
-# target: check - Checks if project builds and passes all the tests
-check: build eunit
-
-
-.PHONY: clean
-# target: clean - Removes build artifacts
-clean:
-	$(REBAR) clean
-
-
-.PHONY: distclean
-# target: distclean - Removes all unversioned files
-distclean: clean
-	git clean -fxd
-
-
-.PHONY: eunit
-# target: eunit - Runs eunit test suite
-eunit:
-	$(REBAR) eunit
-
-
-.PHONY: help
-# target: help - Prints this help
-help:
-	@egrep "^# target:" Makefile | sed -e 's/^# target: //g' | sort
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c75fbcd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+## NOTE ##
+
+Application was moved to the [main repository](https://github.com/apache/couchdb.git)
diff --git a/src/ets_lru.app.src b/src/ets_lru.app.src
deleted file mode 100644
index c81ce11..0000000
--- a/src/ets_lru.app.src
+++ /dev/null
@@ -1,21 +0,0 @@
-% 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.
-
-{application, ets_lru, [
-    {description, "ETS Base LRU Cache"},
-    {vsn, git},
-    {registered, []},
-    {applications, [
-        kernel,
-        stdlib
-    ]}
-]}.
diff --git a/src/ets_lru.erl b/src/ets_lru.erl
deleted file mode 100644
index 0f6fdb2..0000000
--- a/src/ets_lru.erl
+++ /dev/null
@@ -1,364 +0,0 @@
-% 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.
-
--module(ets_lru).
--behaviour(gen_server).
--vsn(2).
-
-
--export([
-    start_link/2,
-    stop/1,
-
-    insert/3,
-    lookup/2,
-    match/3,
-    match_object/3,
-    remove/2,
-    clear/1,
-
-    % Dirty functions read straight from
-    % the ETS tables which means there are
-    % race conditions with concurrent access.
-    lookup_d/2
-]).
-
--export([
-    init/1,
-    terminate/2,
-
-    handle_call/3,
-    handle_cast/2,
-    handle_info/2,
-
-    code_change/3
-]).
-
-
--define(DEFAULT_TIME_UNIT, millisecond).
-
--type time_value() :: integer().
--type strict_monotonic_time() :: {time_value(), integer()}.
-
--record(entry, {
-    key :: term(),
-    val :: term(),
-    atime :: strict_monotonic_time(),
-    ctime :: strict_monotonic_time()
-}).
-
--record(st, {
-    objects,
-    atimes,
-    ctimes,
-
-    max_objs :: non_neg_integer() | undefined,
-    max_size :: non_neg_integer() | undefined,
-    max_lifetime :: non_neg_integer() | undefined,
-    time_unit = ?DEFAULT_TIME_UNIT :: atom()
-}).
-
-
-start_link(Name, Options) when is_atom(Name) ->
-    gen_server:start_link({local, Name}, ?MODULE, {Name, Options}, []).
-
-
-stop(LRU) ->
-    gen_server:cast(LRU, stop).
-
-
-lookup(LRU, Key) ->
-    gen_server:call(LRU, {lookup, Key}).
-
-
-insert(LRU, Key, Val) ->
-    gen_server:call(LRU, {insert, Key, Val}).
-
-
-remove(LRU, Key) ->
-    gen_server:call(LRU, {remove, Key}).
-
-%% @doc match/3 provides an efficient way to retrieve parts of the
-%% keys and values without copying or requiring circumvention of the
-%% ets_lru API. The KeySpec and ValueSpec parameters are used as part
-%% of one larger match spec so keep in mind that all capturing
-%% placeholders will be aliased between the key and value parts.
--spec match(atom() | pid(), term(), term()) -> [[any()]].
-match(LRU, KeySpec, ValueSpec) ->
-    gen_server:call(LRU, {match, KeySpec, ValueSpec}).
-
-%% @doc match_object/3 provides an efficient way to retrieve multiple
-%% values using match conditions. The KeySpec and ValueSpec parameters
-%% are used as part of one larger match spec so keep in mind that all
-%% capturing placeholders will be aliased between the key and value
-%% parts.
--spec match_object(atom() | pid(), term(), term()) -> [any()].
-match_object(Name, KeySpec, ValueSpec) when is_atom(Name) ->
-    Pattern = #entry{key=KeySpec, val=ValueSpec, _='_'},
-    Entries = ets:match_object(obj_table(Name), Pattern),
-    lists:map(fun(#entry{key=Key,val=Val}) ->
-        gen_server:cast(Name, {accessed, Key}),
-        Val
-    end, Entries);
-match_object(LRU, KeySpec, ValueSpec) ->
-    gen_server:call(LRU, {match_object, KeySpec, ValueSpec}).
-
-clear(LRU) ->
-    gen_server:call(LRU, clear).
-
-
-lookup_d(Name, Key) when is_atom(Name) ->
-    case ets:lookup(obj_table(Name), Key) of
-        [#entry{val=Val}] ->
-            gen_server:cast(Name, {accessed, Key}),
-            {ok, Val};
-        [] ->
-            not_found
-    end.
-
-
-init({Name, Options}) ->
-    St = set_options(#st{}, Options),
-    ObjOpts = [set, named_table, protected, {keypos, #entry.key}],
-    TimeOpts = [ordered_set, named_table, protected],
-
-    {ok, St#st{
-        objects = ets:new(obj_table(Name), ObjOpts),
-        atimes = ets:new(at_table(Name), TimeOpts),
-        ctimes = ets:new(ct_table(Name), TimeOpts)
-    }}.
-
-
-terminate(_Reason, St) ->
-    true = ets:delete(St#st.objects),
-    true = ets:delete(St#st.atimes),
-    true = ets:delete(St#st.ctimes),
-    ok.
-
-
-handle_call({lookup, Key}, _From, St) ->
-    Reply = case ets:lookup(St#st.objects, Key) of
-        [#entry{val=Val} | _] ->
-            accessed(Key, St),
-            {ok, Val};
-        [] ->
-            not_found
-    end,
-    {reply, Reply, St, 0};
-
-handle_call({match_object, KeySpec, ValueSpec}, _From, St) ->
-    Pattern = #entry{key=KeySpec, val=ValueSpec, _='_'},
-    Entries = ets:match_object(St#st.objects, Pattern),
-    Values = lists:map(fun(#entry{key=Key,val=Val}) ->
-        accessed(Key, St),
-        Val
-    end, Entries),
-    {reply, Values, St, 0};
-
-handle_call({match, KeySpec, ValueSpec}, _From, St) ->
-    Pattern = #entry{key=KeySpec, val=ValueSpec, _='_'},
-    Values = ets:match(St#st.objects, Pattern),
-    {reply, Values, St, 0};
-
-handle_call({insert, Key, Val}, _From, St) ->
-    NewATime = strict_monotonic_time(St#st.time_unit),
-    Pattern = #entry{key=Key, atime='$1', _='_'},
-    case ets:match(St#st.objects, Pattern) of
-        [[ATime]] ->
-            Update = {#entry.val, Val},
-            true = ets:update_element(St#st.objects, Key, Update),
-            true = ets:delete(St#st.atimes, ATime),
-            true = ets:insert(St#st.atimes, {NewATime, Key});
-        [] ->
-            Entry = #entry{key=Key, val=Val, atime=NewATime, ctime=NewATime},
-            true = ets:insert(St#st.objects, Entry),
-            true = ets:insert(St#st.atimes, {NewATime, Key}),
-            true = ets:insert(St#st.ctimes, {NewATime, Key})
-    end,
-    {reply, ok, St, 0};
-
-handle_call({remove, Key}, _From, St) ->
-    Pattern = #entry{key=Key, atime='$1', ctime='$2', _='_'},
-    Reply = case ets:match(St#st.objects, Pattern) of
-        [[ATime, CTime]] ->
-            true = ets:delete(St#st.objects, Key),
-            true = ets:delete(St#st.atimes, ATime),
-            true = ets:delete(St#st.ctimes, CTime),
-            ok;
-        [] ->
-            not_found
-    end,
-    {reply, Reply, St, 0};
-
-handle_call(clear, _From, St) ->
-    true = ets:delete_all_objects(St#st.objects),
-    true = ets:delete_all_objects(St#st.atimes),
-    true = ets:delete_all_objects(St#st.ctimes),
-    % No need to timeout here and evict cache
-    % entries because its now empty.
-    {reply, ok, St};
-
-
-handle_call(Msg, _From, St) ->
-    {stop, {invalid_call, Msg}, {invalid_call, Msg}, St}.
-
-
-handle_cast({accessed, Key}, St) ->
-    accessed(Key, St),
-    {noreply, St, 0};
-
-handle_cast(stop, St) ->
-    {stop, normal, St};
-
-handle_cast(Msg, St) ->
-    {stop, {invalid_cast, Msg}, St}.
-
-
-handle_info(timeout, St) ->
-    trim(St),
-    {noreply, St, next_timeout(St)};
-
-handle_info(Msg, St) ->
-    {stop, {invalid_info, Msg}, St}.
-
-
-code_change(_OldVsn, St, _Extra) ->
-    {ok, St}.
-
-
-accessed(Key, St) ->
-    Pattern = #entry{key=Key, atime='$1', _='_'},
-    case ets:match(St#st.objects, Pattern) of
-        [[ATime]] ->
-            NewATime = strict_monotonic_time(St#st.time_unit),
-            Update = {#entry.atime, NewATime},
-            true = ets:update_element(St#st.objects, Key, Update),
-            true = ets:delete(St#st.atimes, ATime),
-            true = ets:insert(St#st.atimes, {NewATime, Key}),
-            ok;
-        [] ->
-            ok
-    end.
-
-
-trim(St) ->
-    trim_count(St),
-    trim_size(St),
-    trim_lifetime(St).
-
-
-trim_count(#st{max_objs=undefined}) ->
-    ok;
-trim_count(#st{max_objs=Max}=St) ->
-    case ets:info(St#st.objects, size) > Max of
-        true ->
-            drop_lru(St, fun trim_count/1);
-        false ->
-            ok
-    end.
-
-
-trim_size(#st{max_size=undefined}) ->
-    ok;
-trim_size(#st{max_size=Max}=St) ->
-    case ets:info(St#st.objects, memory) > Max of
-        true ->
-            drop_lru(St, fun trim_size/1);
-        false ->
-            ok
-    end.
-
-
-trim_lifetime(#st{max_lifetime=undefined}) ->
-    ok;
-trim_lifetime(#st{max_lifetime=Max}=St) ->
-    Now = erlang:monotonic_time(St#st.time_unit),
-    case ets:first(St#st.ctimes) of
-        '$end_of_table' ->
-            ok;
-        CTime = {Time, _} ->
-            case Now - Time > Max of
-                true ->
-                    [{CTime, Key}] = ets:lookup(St#st.ctimes, CTime),
-                    Pattern = #entry{key=Key, atime='$1', _='_'},
-                    [[ATime]] = ets:match(St#st.objects, Pattern),
-                    true = ets:delete(St#st.objects, Key),
-                    true = ets:delete(St#st.atimes, ATime),
-                    true = ets:delete(St#st.ctimes, CTime),
-                    trim_lifetime(St);
-                false ->
-                    ok
-            end
-    end.
-
-
-drop_lru(St, Continue) ->
-    case ets:first(St#st.atimes) of
-        '$end_of_table' ->
-            empty;
-        ATime ->
-            [{ATime, Key}] = ets:lookup(St#st.atimes, ATime),
-            Pattern = #entry{key=Key, ctime='$1', _='_'},
-            [[CTime]] = ets:match(St#st.objects, Pattern),
-            true = ets:delete(St#st.objects, Key),
-            true = ets:delete(St#st.atimes, ATime),
-            true = ets:delete(St#st.ctimes, CTime),
-            Continue(St)
-    end.
-
-
-next_timeout(#st{max_lifetime=undefined}) ->
-    infinity;
-next_timeout(St) ->
-    case ets:first(St#st.ctimes) of
-        '$end_of_table' ->
-            infinity;
-        {Time, _} ->
-            Now = erlang:monotonic_time(St#st.time_unit),
-            TimeDiff = Now - Time,
-            erlang:max(St#st.max_lifetime - TimeDiff, 0)
-    end.
-
-
-set_options(St, []) ->
-    St;
-set_options(St, [{max_objects, N} | Rest]) when is_integer(N), N >= 0 ->
-    set_options(St#st{max_objs=N}, Rest);
-set_options(St, [{max_size, N} | Rest]) when is_integer(N), N >= 0 ->
-    set_options(St#st{max_size=N}, Rest);
-set_options(St, [{max_lifetime, N} | Rest]) when is_integer(N), N >= 0 ->
-    set_options(St#st{max_lifetime=N}, Rest);
-set_options(St, [{time_unit, T} | Rest]) when is_atom(T) ->
-    set_options(St#st{time_unit=T}, Rest);
-set_options(_, [Opt | _]) ->
-    throw({invalid_option, Opt}).
-
-
-obj_table(Name) ->
-    table_name(Name, "_objects").
-
-
-at_table(Name) ->
-    table_name(Name, "_atimes").
-
-
-ct_table(Name) ->
-    table_name(Name, "_ctimes").
-
-
-table_name(Name, Ext) ->
-    list_to_atom(atom_to_list(Name) ++ Ext).
-
-
--spec strict_monotonic_time(atom()) -> strict_monotonic_time().
-strict_monotonic_time(TimeUnit) ->
-    {erlang:monotonic_time(TimeUnit), erlang:unique_integer([monotonic])}.
diff --git a/test/ets_lru_test.erl b/test/ets_lru_test.erl
deleted file mode 100644
index f54299a..0000000
--- a/test/ets_lru_test.erl
+++ /dev/null
@@ -1,340 +0,0 @@
--module(ets_lru_test).
-
-
--include_lib("eunit/include/eunit.hrl").
-
-lifecyle_test_() ->
-    {
-        "Test LRU lifecycle",
-        {setup,
-            fun() -> ets_lru:start_link(?MODULE, []) end,
-            fun({ok, LRU}) -> is_process_alive(LRU) == false end,
-            fun({ok, LRU}) ->
-                [
-                    {
-                        "ets_lru:start_link/2 returned an LRU",
-                        ?_assert(is_pid(LRU))
-                    },
-                    {
-                        "Destroyed the LRU ok",
-                        ?_assertEqual(ok, ets_lru:stop(LRU))
-                    }
-                ]
-            end
-        }
-    }.
-
-table_names_test_() ->
-    {
-        "Test tables names",
-        {setup,
-            fun() -> ets_lru:start_link(foo, []) end,
-            fun({ok, LRU}) ->
-                [
-                    {
-                        "foo_objects exists",
-                        ?_assertEqual(0, ets:info(foo_objects, size))
-                    },
-                    {
-                        "foo_atimes exists",
-                        ?_assertEqual(0, ets:info(foo_atimes, size))
-                    },
-                    {
-                        "foo_ctimes exists",
-                        ?_assertEqual(0, ets:info(foo_ctimes, size))
-                    },
-                    {
-                        "LRU stopped normally",
-                        ?_test(begin
-                            Reason = stop_lru({ok, LRU}),
-                            ?assertEqual(normal, Reason)
-                        end)
-                    },
-                    {
-                        "foo_objects doesn't exists",
-                        ?_assertEqual(undefined, ets:info(foo_objects, size))
-                    },
-                    {
-                        "foo_atimes doesn't exists",
-                        ?_assertEqual(undefined, ets:info(foo_atimes, size))
-                    },
-                    {
-                        "foo_ctimes doesn't exists",
-                        ?_assertEqual(undefined, ets:info(foo_ctimes, size))
-                    }
-                ]
-            end
-        }
-    }.
-
-basic_behavior_test_() ->
-    {
-        "Test basic behavior",
-        {foreach,
-            fun() ->
-                {ok, LRU} = ets_lru:start_link(test_lru, []),
-                ok = ets_lru:insert(LRU, foo, bar),
-                {ok, LRU}
-            end,
-            fun stop_lru/1,
-            [
-                fun({ok, LRU}) ->
-                    {
-                        "Lookup returned the inserted value",
-                        ?_assertEqual({ok, bar}, ets_lru:lookup(LRU, foo))
-                    }
-                end,
-                fun({ok, _LRU}) ->
-                    {
-                        "Dirty lookup returned the inserted value",
-                        ?_assertEqual({ok, bar},
-                            ets_lru:lookup_d(test_lru, foo))
-                    }
-                end,
-                fun({ok, LRU}) ->
-                    [{
-                        "Lookup returned the inserted value",
-                        ?_assertEqual({ok, bar}, ets_lru:lookup(LRU, foo))
-                    },
-                    {
-                        "Insert new value",
-                        ?_assertEqual(ok, ets_lru:insert(LRU, foo, bam))
-                    },
-                    {
-                        "Lookup returned the newly inserted value",
-                        ?_assertEqual({ok, bam}, ets_lru:lookup(LRU, foo))
-                    }]
-                end,
-                fun({ok, LRU}) ->
-                    [{
-                        "Lookup returned the inserted value",
-                        ?_assertEqual({ok, bar}, ets_lru:lookup(LRU, foo))
-                    },
-                    {
-                        "Remove value",
-                        ?_assertEqual(ok, ets_lru:remove(LRU, foo))
-                    },
-                    {
-                        "Lookup returned not_found for removed value",
-                        ?_assertEqual(not_found, ets_lru:lookup(LRU, foo))
-                    }]
-                end,
-                fun({ok, LRU}) ->
-                    [{
-                        "Lookup returned the inserted value",
-                        ?_assertEqual({ok, bar}, ets_lru:lookup(LRU, foo))
-                    },
-                    {
-                        "Clear LRU",
-                        ?_assertEqual(ok, ets_lru:clear(LRU))
-                    },
-                    {
-                        "Lookup returned not_found after a clear",
-                        ?_assertEqual(not_found, ets_lru:lookup(LRU, foo))
-                    }]
-                end
-            ]
-        }
-    }.
-
-lru_good_options_test_() ->
-    {
-        "Test good LRU options",
-        {foreachx,
-            fun(Opts) ->
-                process_flag(trap_exit,true),
-                ets_lru:start_link(?MODULE, Opts)
-            end,
-            fun(_, Cfg) -> stop_lru(Cfg) end,
-            [
-                {[{max_objects, 1}], fun test_good_opts/2},
-                {[{max_objects, 5}], fun test_good_opts/2},
-                {[{max_objects, 923928342098203942}], fun test_good_opts/2},
-                {[{max_size, 1}], fun test_good_opts/2},
-                {[{max_size, 5}], fun test_good_opts/2},
-                {[{max_size, 2342923423942309423094}], fun test_good_opts/2},
-                {[{max_lifetime, 1}], fun test_good_opts/2},
-                {[{max_lifetime, 5}], fun test_good_opts/2},
-                {[{max_lifetime, 1244209909180928348}], fun test_good_opts/2}
-            ]
-        }
-    }.
-
-lru_bad_options_test_() ->
-    {
-        "Test bad LRU options",
-        {foreachx,
-            fun(Opts) ->
-                process_flag(trap_exit,true),
-                ets_lru:start_link(?MODULE, Opts)
-            end,
-            fun(_, _) ->
-                case whereis(?MODULE) of
-                    Pid when is_pid(Pid) ->
-                        stop_lru({ok, Pid});
-                    undefined ->
-                        ok
-                end
-            end,
-            [
-                {[{bingo, bango}], fun test_bad_opts/2},
-                {[12], fun test_bad_opts/2},
-                {[true], fun test_bad_opts/2}
-            ]
-        }
-    }.
-
-lru_limits_test_() ->
-    {
-        "Test LRU limits",
-        {foreachx,
-            fun(Opts) -> ets_lru:start_link(lru, Opts) end,
-            fun(_, Cfg) -> stop_lru(Cfg) end,
-            [
-                {[{max_objects, 25}], fun test_limits/2},
-                {[{max_size, 1024}], fun test_limits/2},
-                {[{max_lifetime, 100}], fun test_limits/2}
-            ]
-        }
-    }.
-
-lru_match_test_() ->
-    {
-        "Test match functions",
-        {foreach,
-            fun() -> ets_lru:start_link(test_lru, []) end,
-            fun stop_lru/1,
-            [
-                fun({ok, LRU}) ->
-                    {
-                        "Empty match",
-                        ?_assertEqual([], ets_lru:match(LRU, a, '$1'))
-                    }
-                end,
-                fun({ok, LRU}) ->
-                    ets_lru:insert(LRU, b, {x, y}),
-                    {
-                        "Single match",
-                        ?_assertEqual([[x, y]],
-                            ets_lru:match(LRU, b, {'$1', '$2'}))
-                    }
-                end,
-                fun({ok, LRU}) ->
-                    ets_lru:insert(LRU, boston, {state, "MA"}),
-                    ets_lru:insert(LRU, new_york, {state, "NY"}),
-                    Values = ets_lru:match(LRU, '_', {state, '$1'}),
-                    {
-                        "Multiple match",
-                        ?_assertEqual([["MA"],["NY"]], lists:sort(Values))
-                    }
-                end,
-                fun({ok, LRU}) ->
-                    {
-                        "Empty match_object",
-                        ?_assertEqual([], ets_lru:match_object(LRU, a, '$1'))
-                    }
-                end,
-                fun({ok, LRU}) ->
-                    ets_lru:insert(LRU, ans, 42),
-                    [{
-                        "Single match_object (registered)",
-                        ?_assertEqual([42],
-                            ets_lru:match_object(test_lru, ans, '$1'))
-                    },
-                    {
-                        "Single match_object (pid)",
-                        ?_assertEqual([42],
-                            ets_lru:match_object(LRU, ans, '$1'))
-                    }]
-                end,
-                fun({ok, LRU}) ->
-                    ets_lru:insert(LRU, {color, blue}, a),
-                    ets_lru:insert(LRU, {color, red}, b),
-                    Values = ets_lru:match_object(LRU, {color, '_'}, '_'),
-                    {
-                        "Multiple match_object",
-                        ?_assertEqual(lists:sort(Values), [a, b])
-                    }
-                end
-            ]
-        }
-    }.
-
-
-test_good_opts(Opts, {ok, LRU}) ->
-    Msg = io_lib:format("LRU created ok with options: ~w", [Opts]),
-    {lists:flatten(Msg), ?_assert(is_pid(LRU))};
-test_good_opts(Opts, ErrorMsg) ->
-    Msg = io_lib:format("LRU created ok with options: ~w", [Opts]),
-    {lists:flatten(Msg), ?_assertEqual(ok, ErrorMsg)}.
-
-test_bad_opts([Opts], {error,{bad_return_value,{invalid_option,Opts2}}}) ->
-    Msg = io_lib:format("LRU failed with bad options: ~w", [Opts]),
-    {lists:flatten(Msg), ?_assertEqual(Opts, Opts2)}.
-
-test_limits([{max_objects, N}], {ok, LRU}) ->
-    {
-        "Max object count ok",
-        ?_assert(insert_kvs(size, LRU, 100 * N, N))
-    };
-test_limits([{max_size, N}], {ok, LRU}) ->
-    {
-        "Max size ok",
-        ?_assert(insert_kvs(memory, LRU, 10 * N, N))
-    };
-test_limits([{max_lifetime, N}], {ok, LRU}) ->
-    [
-        {
-            "Expire leaves new entries",
-            ?_test(begin
-                ets_lru:insert(LRU, foo, bar),
-                ?assertEqual({ok, bar}, ets_lru:lookup(LRU, foo))
-            end)
-        },
-        {
-            "Entry was expired",
-            ?_test(begin
-                timer:sleep(round(N * 1.5)),
-                ?assertEqual(not_found, ets_lru:lookup(LRU, foo))
-            end)
-        }
-    ].
-
-
-insert_kvs(_, _, 0, _) ->
-    true;
-insert_kvs(Info, LRU, Count, Limit) ->
-    ets_lru:insert(LRU, Count, 1.5234),
-    case ets:info(lru_objects, Info) > Limit of
-        true ->
-            % Retry again as eviction statistics
-            % returned by ets:info() can be delayed.
-            timer:sleep(1),
-            case ets:info(lru_objects, Info) > Limit of
-                true ->
-                    erlang:error(exceeded_limit);
-                false -> true
-            end;
-        false -> true
-    end,
-    insert_kvs(Info, LRU, Count - 1, Limit).
-
-stop_lru({ok, LRU}) ->
-    Ref = erlang:monitor(process, LRU),
-    ets_lru:stop(LRU),
-    receive {'DOWN', Ref, process, LRU, Reason} -> Reason end;
-stop_lru({error, _}) ->
-    ok.
-
-valid_parameterized_time_unit_test() ->
-    Opts = [{time_unit, microsecond}],
-    {ok, LRU} = ets_lru:start_link(lru_test, Opts),
-    ?assert(is_process_alive(LRU)),
-    ok = ets_lru:insert(LRU, foo, bar),
-    ?assertEqual({ok, bar}, ets_lru:lookup(LRU, foo)),
-    ?assertEqual(ok, ets_lru:stop(LRU)).
-
-invalid_parameterized_time_unit_test() ->
-    Opts = [{time_unit, invalid}],
-    {ok, LRU} = ets_lru:start_link(lru_test, Opts),
-    ?assertExit(_, ets_lru:insert(LRU, foo, bar)).