6

キーを保存および取得するための単純なメモリ内永続レイヤーとして、また異なる値を持つ多くの重複キーを減らすことを含む時折のfoldlのために、エリクサー経由でetsを使用しています。バッグオプションを使用しています。

より複雑なテーブル トラバーサル、マッチ、またはフォールドを実行することなく、現在のキーだけのリストを取得する簡単な、おそらく O(1) 方法はありますか?

Erlang または Elixir 構文の応答を歓迎します。

:ets.new(:cache, [:bag, :named_table, :protected])

挿入を支援するために使用している整数でインデックス付けされたアトム キーの静的マップがあります。しかし、すべてのキーが使用されるわけではありません..

chunk_key_map = %{2 => :chunk_key_2, ..... 28 => :chunk_key_28}

簡単な方法がない場合は、ets:lookup を実行して静的アトム キー値をそれぞれ試し、!= [] をテストして独自のリストを生成できることは承知していますが、ets がそのような機能をサポートしているかどうかを確認したかったのです。

ありがとう

4

3 に答える 3

2

したがって、ets テクニックは見つかりませんでしたが、キー マップが静的であるため、キー リストの取得コードを一定時間でエリクサーに実装しました。

    list = Enum.reduce(2..28, [], fn head, acc -> 
            case :ets.lookup(:cache, Map.get(chunk_key_map, head)) do
                [] -> acc
                _ -> [acc, head]
            end
        end)

    List.flatten(list)

更新: 返信に基づいて、私は Hamidreza のトラバーサル ロジックを採用し、それをを使用ets して Elixir にラップしました。StreamStream.resource/3

defp get_ets_keys_lazy(table_name) when is_atom(table_name) do
    eot = :"$end_of_table"

    Stream.resource(
        fn -> [] end,

        fn acc ->
            case acc do
                [] -> 
                    case :ets.first(table_name) do
                        ^eot -> {:halt, acc}
                        first_key -> {[first_key], first_key}                       
                    end

                acc -> 
                    case :ets.next(table_name, acc) do  
                        ^eot -> {:halt, acc}
                        next_key -> {[next_key], next_key}
                    end
            end
        end,

        fn _acc -> :ok end
    )
end

次に、パイプラインを介してストリームを実行しました

get_ets_keys_lazy(table_name) 
    |> Stream.map(lambda1) 
    |> Stream.each(lambda2)
    |> Stream.run
于 2016-02-01T05:50:09.943 に答える