this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add mkdir_p and refactor

garrison 29a26887 54af29cf

+100 -10
+95 -9
lib/trinity/sim_file.ex
··· 31 31 end 32 32 end 33 33 34 + @spec mkdir_p(String.t) :: :ok | {:error, term} 35 + def mkdir_p(path) do 36 + case get_sim() do 37 + nil -> raise "not supported" 38 + _sim -> sim_mkdir_p(path) 39 + end 40 + end 41 + 34 42 defp next_fd(file_paths), do: :ets.update_counter(file_paths, :next_fd, 1) 35 43 36 44 defp sim_open(path, _modes) do 37 45 %{file_paths: file_paths} = get_sim() 38 46 node = get_proc_node() 39 47 40 - key = {node, path} 41 - case :ets.lookup(file_paths, key) do 42 - [{_path, fd}] -> 43 - {:ok, fd} 44 - [] -> 45 - # TODO: check directory 46 - fd = next_fd(file_paths) 47 - :ets.insert(file_paths, {key, fd}) 48 - {:ok, fd} 48 + split = split_path(path) 49 + with :ok <- ensure_dir_paths(split, file_paths, node, ""), 50 + {:ok, _fd} = tup <- get_or_create_fd(file_paths, node, path) 51 + do 52 + tup 53 + else 54 + {:error, _err} = error -> error 55 + end 56 + end 57 + 58 + defp get_or_create_fd(file_paths, node, path) do 59 + case get_path(file_paths, node, path) do 60 + fd when is_integer(fd) -> {:ok, fd} 61 + nil -> create_fd(file_paths, node, path) 62 + # TODO: is this the correct error? 63 + :directory -> {:error, :enotdir} 64 + end 65 + end 66 + 67 + defp create_fd(file_paths, node, path) do 68 + fd = next_fd(file_paths) 69 + put_path(file_paths, node, path, fd) 70 + {:ok, fd} 71 + end 72 + 73 + # Note that we ignore the last (basename) component 74 + defp ensure_dir_paths([_base], _file_paths, _node, _acc), do: :ok 75 + defp ensure_dir_paths([p | rest], file_paths, node, acc) do 76 + acc = acc <> "/" <> p 77 + case get_path(file_paths, node, acc) do 78 + :directory -> ensure_dir_paths(rest, file_paths, node, acc) 79 + nil -> {:error, :enotdir} 80 + fd when is_integer(fd) -> {:error, :enotdir} 49 81 end 50 82 end 51 83 ··· 147 179 # TODO: confirm the above 148 180 new_data = <<prefix::binary, bin::binary, suffix::binary>> 149 181 :ets.insert(file_data, {key, new_data}) 182 + end 183 + 184 + defp sim_mkdir_p(path) do 185 + if not String.starts_with?(path, "/"), do: raise "Path #{inspect(path)} is not absolute" 186 + 187 + %{file_paths: file_paths} = get_sim() 188 + node = get_proc_node() 189 + 190 + path = normalize_trailing(path) 191 + split = split_path(path) 192 + 193 + with :ok <- ensure_not_files(split, file_paths, node, "") 194 + do 195 + write_directories(split, file_paths, node, "") 196 + :ok 197 + else 198 + {:error, _err} = error -> error 199 + end 200 + end 201 + 202 + defp write_directories([], _file_paths, _node, _acc), do: :ok 203 + defp write_directories([p | rest], file_paths, node, acc) do 204 + acc = acc <> "/" <> p 205 + case get_path(file_paths, node, acc) do 206 + nil -> put_path(file_paths, node, acc, :directory) 207 + :directory -> :noop 208 + end 209 + write_directories(rest, file_paths, node, acc) 210 + end 211 + 212 + defp ensure_not_files([], _file_paths, _node, _acc), do: :ok 213 + defp ensure_not_files([p | rest], file_paths, node, acc) do 214 + acc = acc <> "/" <> p 215 + case get_path(file_paths, node, acc) do 216 + nil -> :ok 217 + :directory -> ensure_not_files(rest, file_paths, node, acc) 218 + fd when is_integer(fd) -> {:error, :enotdir} 219 + end 220 + end 221 + 222 + defp normalize_trailing(path), do: String.trim_trailing(path, "/") 223 + defp split_path("/" <> path), do: String.split(path, "/") 224 + 225 + defp get_path(file_paths, node, path) do 226 + case :ets.lookup(file_paths, {node, path}) do 227 + [{_key, value}] -> value 228 + [] -> nil 229 + end 230 + end 231 + 232 + defp put_path(file_paths, node, path, value) 233 + when value == :directory or is_integer(value) do 234 + dbg {{node, path}, value} 235 + :ets.insert(file_paths, {{node, path}, value}) 150 236 end 151 237 end
+5 -1
test/trinity_test.exs
··· 17 17 end 18 18 19 19 def init(%{id: id, initial_count: initial_count}) do 20 + :ok = SimFile.mkdir_p("/counters/#{id}/") 21 + {:ok, fd} = SimFile.open("/counters/#{id}/#{id}.count", [:read, :write]) 22 + 20 23 state = %{ 21 - fd: SimFile.open("/counters/#{id}.count", [:read, :write]), 24 + fd: fd, 22 25 size: nil, 23 26 } 24 27 state = write_value(state, initial_count) 28 + 25 29 {:ok, state} 26 30 end 27 31