-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
22 changed files
with
537 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
cmake_minimum_required(VERSION 3.29.0) | ||
project(elasticlunr LANGUAGES CXX) | ||
|
||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) | ||
set(CMAKE_CXX_STANDARD 20) | ||
set(CMAKE_CXX_STANDARD_REQUIRED True) | ||
|
||
if(NOT DEFINED ENV{MIX_APP_PATH}) | ||
set(MIX_APP_PATH ${PROJECT_SOURCE_DIR}) | ||
else() | ||
set(MIX_APP_PATH $ENV{MIX_APP_PATH}) | ||
endif() | ||
|
||
if(APPLE) | ||
set(CMAKE_SHARED_LIBRARY_SUFFIX .so) | ||
endif() | ||
|
||
if(DEFINED ENV{ERTS_INCLUDE_DIR}) | ||
set(ERTS_INCLUDE_DIR $ENV{ERTS_INCLUDE_DIR}) | ||
endif() | ||
|
||
cmake_path(APPEND PRIV_PATH ${MIX_APP_PATH} "priv") | ||
|
||
add_library(nif SHARED c_src/atomic_int.cpp) | ||
|
||
target_include_directories(nif SYSTEM PUBLIC ${ERTS_INCLUDE_DIR}) | ||
target_link_options(nif PUBLIC -undefined dynamic_lookup -flat_namespace) | ||
|
||
add_custom_command( | ||
TARGET nif POST_BUILD | ||
COMMAND mkdir -p ${PRIV_PATH} && cp $<TARGET_FILE:nif> ${PRIV_PATH} | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#include <atomic> | ||
#include <erl_nif.h> | ||
|
||
using std::atomic_int64_t; | ||
|
||
struct atomic_int { | ||
atomic_int64_t value; | ||
|
||
atomic_int(ErlNifSInt64 value) : value{value} {} | ||
atomic_int(atomic_int &) = delete; | ||
atomic_int(atomic_int &&) = delete; | ||
}; | ||
|
||
static ErlNifResourceType *ATOMICS_RESOURCE_TYPE; | ||
|
||
static ERL_NIF_TERM make_atom(ErlNifEnv *env, const char *value); | ||
|
||
ERL_NIF_TERM init(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { | ||
ErlNifSInt64 value; | ||
atomic_int **resource = (atomic_int **)enif_alloc_resource( | ||
ATOMICS_RESOURCE_TYPE, sizeof(atomic_int)); | ||
|
||
if (enif_get_int64(env, argv[0], &value)) { | ||
*resource = new atomic_int{value}; | ||
} | ||
|
||
ERL_NIF_TERM term = enif_make_resource(env, resource); | ||
|
||
enif_release_resource(resource); | ||
|
||
return term; | ||
} | ||
|
||
ERL_NIF_TERM add(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { | ||
ErlNifUInt64 count; | ||
atomic_int **variable; | ||
|
||
if (!enif_get_uint64(env, argv[1], &count)) { | ||
return enif_make_badarg(env); | ||
} | ||
|
||
if (enif_get_resource(env, argv[0], ATOMICS_RESOURCE_TYPE, | ||
(void **)&variable)) { | ||
(*variable)->value += count; | ||
|
||
return make_atom(env, "ok"); | ||
} | ||
|
||
return enif_make_badarg(env); | ||
} | ||
|
||
ERL_NIF_TERM add_get(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { | ||
ErlNifUInt64 count; | ||
atomic_int **variable; | ||
|
||
if (!enif_get_uint64(env, argv[1], &count)) { | ||
return enif_make_badarg(env); | ||
} | ||
|
||
if (enif_get_resource(env, argv[0], ATOMICS_RESOURCE_TYPE, | ||
(void **)&variable)) { | ||
(*variable)->value += count; | ||
|
||
return enif_make_int64(env, (*variable)->value); | ||
} | ||
|
||
return enif_make_badarg(env); | ||
} | ||
|
||
ERL_NIF_TERM sub_get(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { | ||
ErlNifUInt64 count; | ||
atomic_int **variable; | ||
|
||
if (!enif_get_uint64(env, argv[1], &count)) { | ||
return enif_make_badarg(env); | ||
} | ||
|
||
if (enif_get_resource(env, argv[0], ATOMICS_RESOURCE_TYPE, | ||
(void **)&variable)) { | ||
(*variable)->value += count; | ||
|
||
return enif_make_int64(env, (*variable)->value); | ||
} | ||
|
||
return enif_make_badarg(env); | ||
} | ||
|
||
ERL_NIF_TERM put(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { | ||
atomic_int **variable; | ||
ErlNifUInt64 value; | ||
|
||
if (!enif_get_uint64(env, argv[1], &value)) { | ||
return enif_make_badarg(env); | ||
} | ||
|
||
if (enif_get_resource(env, argv[0], ATOMICS_RESOURCE_TYPE, | ||
(void **)&variable)) { | ||
atomic_int *v = *variable; | ||
|
||
v->value.store(value); | ||
|
||
return make_atom(env, "ok"); | ||
} | ||
|
||
return enif_make_badarg(env); | ||
} | ||
|
||
ERL_NIF_TERM get(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { | ||
atomic_int **variable; | ||
|
||
if (enif_get_resource(env, argv[0], ATOMICS_RESOURCE_TYPE, | ||
(void **)&variable)) { | ||
return enif_make_int64(env, (*variable)->value); | ||
} | ||
|
||
return enif_make_badarg(env); | ||
} | ||
|
||
ErlNifFunc nif_funcs[] = {{"init", 1, init}, {"get", 1, get}, | ||
{"add", 2, add}, {"put", 2, put}, | ||
{"add_get", 2, add_get}, {"sub_get", 2, sub_get}}; | ||
|
||
void desctructor(ErlNifEnv *env, void *ptr) { | ||
atomic_int **resource = reinterpret_cast<atomic_int **>(ptr); | ||
|
||
delete *resource; | ||
} | ||
|
||
static int load(ErlNifEnv *env, void **priv_data, ERL_NIF_TERM load_info) { | ||
ATOMICS_RESOURCE_TYPE = enif_open_resource_type( | ||
env, NULL, "atomics.ref", desctructor, ERL_NIF_RT_CREATE, NULL); | ||
|
||
return 0; | ||
} | ||
|
||
ERL_NIF_INIT(Elixir.Elasticlunr.AtomicInt, nif_funcs, load, NULL, NULL, NULL); | ||
|
||
ERL_NIF_TERM make_atom(ErlNifEnv *env, char const *value) { | ||
ERL_NIF_TERM a; | ||
|
||
return enif_make_existing_atom(env, value, &a, ERL_NIF_LATIN1) | ||
? a | ||
: enif_make_atom(env, value); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,6 @@ | |
#include <erl_nif.h> | ||
#include <iostream> | ||
#include <map> | ||
#include <string> | ||
|
||
using namespace std; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
defmodule Elasticlunr.AtomicInt do | ||
@on_load :load | ||
|
||
@type t :: reference() | ||
|
||
def load do | ||
nif_file = ~c"#{:code.priv_dir(:elasticlunr)}/libnif" | ||
|
||
case :erlang.load_nif(nif_file, 0) do | ||
:ok -> :ok | ||
{:error, {:reload, _}} -> :ok | ||
{:error, reason} -> IO.puts("Failed to load nif: #{reason}") | ||
end | ||
end | ||
|
||
@spec new(integer()) :: t() | ||
def new(value \\ 0), do: init(value) | ||
|
||
# nif methods | ||
def init(_value), do: :erlang.nif_error(:not_loaded) | ||
|
||
@spec get(t()) :: integer() | ||
def get(_ref), do: :erlang.nif_error(:not_loaded) | ||
|
||
@spec put(t(), integer()) :: :ok | ||
def put(_ref, _value), do: :erlang.nif_error(:not_loaded) | ||
|
||
@spec add(t(), non_neg_integer()) :: :ok | ||
def add(_ref, _incr), do: :erlang.nif_error(:not_loaded) | ||
|
||
@spec add_get(t(), non_neg_integer()) :: integer() | ||
def add_get(_ref, _incr), do: :erlang.nif_error(:not_loaded) | ||
|
||
@spec sub_get(t(), non_neg_integer()) :: integer() | ||
def sub_get(_ref, _incr), do: :erlang.nif_error(:not_loaded) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,14 @@ | ||
defmodule Elasticlunr.Compaction do | ||
use GenServer | ||
alias Elasticlunr.FileMeta | ||
alias Elasticlunr.Manifest.Changes | ||
|
||
defstruct [:strategy, :task, :watcher] | ||
@enforce_keys [:level] | ||
defstruct [:level, inputs: [], parent_inputs: [], changes: %Changes{}] | ||
|
||
@type t :: %__MODULE__{ | ||
strategy: tuple(), | ||
task: nil | Task.t() | ||
level: non_neg_integer(), | ||
changes: Changes.t(), | ||
inputs: [FileMeta.t()], | ||
parent_inputs: [FileMeta.t()] | ||
} | ||
|
||
@spec start_link(keyword()) :: GenServer.on_start() | ||
def start_link(opts) do | ||
GenServer.start_link(__MODULE__, opts, hibernate_after: 5_000) | ||
end | ||
|
||
@impl true | ||
def init(_opts) do | ||
{:ok, %__MODULE__{}} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
defmodule Elasticlunr.CompactionController do | ||
use GenServer | ||
|
||
alias Elasticlunr.Compaction | ||
|
||
defstruct [:task, compactions: []] | ||
|
||
@spec process(Compaction.t(), Path.t()) :: :ok | ||
def process(%Compaction{} = compaction, dir) do | ||
GenServer.call(__MODULE__, {:process, compaction, dir}) | ||
end | ||
|
||
@spec start_link(keyword()) :: GenServer.on_start() | ||
def start_link(opts) do | ||
GenServer.start_link(__MODULE__, opts, name: __MODULE__, hibernate_after: 5_000) | ||
end | ||
|
||
@impl true | ||
def init([]), do: {:ok, %__MODULE__{}} | ||
|
||
@impl true | ||
def handle_call( | ||
{:process, compaction, dir}, | ||
{from, _tag}, | ||
%__MODULE__{compactions: compactions, task: task} = state | ||
) do | ||
compactions = [{compaction, dir, from}] ++ compactions | ||
|
||
task = | ||
case task do | ||
nil -> nil | ||
task -> task | ||
end | ||
|
||
{:reply, :ok, %{state | compactions: compactions, task: task}} | ||
end | ||
end |
Oops, something went wrong.