Skip to content

Commit 64c58f2

Browse files
committed
Use just the process dictionary for keeping history
1 parent 3f86e6d commit 64c58f2

File tree

2 files changed

+42
-70
lines changed

2 files changed

+42
-70
lines changed

lib/iex/lib/iex/history.ex

Lines changed: 40 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,71 @@
11
defmodule IEx.History do
2+
@moduledoc false
23

34
def init do
4-
Process.put :iex_history, :queue.new
5+
Process.put(:iex_history_start_counter, 1)
6+
Process.put(:iex_history_counter, 1)
57
end
68

79
### append ###
810

9-
def append(entry) do
10-
history = Process.get(:iex_history)
11-
len = :queue.len(history)
12-
limit = IEx.Options.get(:history_size)
13-
14-
new_history =
15-
:queue.in(entry, history)
16-
|> limit_history(len + 1, limit)
17-
Process.put(:iex_history, new_history)
18-
end
11+
def append(entry, counter) do
12+
Process.put({:iex_history, counter}, entry)
13+
Process.put(:iex_history_counter, counter+1)
1914

20-
defp limit_history(_, _, 0) do
21-
:queue.new
15+
limit = IEx.Options.get(:history_size)
16+
start_counter = Process.get(:iex_history_start_counter)
17+
should_collect = limit_history(start_counter, counter, limit)
18+
if should_collect do
19+
IO.puts "...collecting garbage"
20+
:erlang.garbage_collect
21+
end
2222
end
2323

24-
defp limit_history(queue, _, limit) when limit < 0 do
25-
queue
24+
defp limit_history(_, _, limit) when limit < 0 do
25+
false
2626
end
2727

28-
defp limit_history(queue, len, limit) when len > limit do
29-
# FIXME: check if the result we're removing had any binaries in it and
30-
# garbage collect them
31-
limit_history(:queue.drop(queue), len-1, limit)
28+
defp limit_history(counter, max_counter, limit) when max_counter - counter < limit do
29+
Process.put(:iex_history_start_counter, counter)
30+
true
3231
end
3332

34-
defp limit_history(queue, _, _) do
35-
queue
33+
defp limit_history(counter, max_counter, limit) do
34+
Process.delete({:iex_history, counter})
35+
limit_history(counter+1, max_counter, limit)
3636
end
3737

3838
### each ###
3939

4040
def each(fun) do
41-
history = Process.get(:iex_history)
42-
each(history, fun)
41+
each(Process.get(:iex_history_start_counter),
42+
Process.get(:iex_history_counter),
43+
fun)
4344
end
4445

45-
defp each(queue, fun) do
46-
case :queue.out(queue) do
47-
{ { :value, val }, tail } ->
48-
fun.(val)
49-
each(tail, fun)
46+
defp each(counter, max_counter, fun) when counter < max_counter do
47+
entry = Process.get({:iex_history, counter})
48+
fun.(entry)
49+
each(counter+1, max_counter, fun)
50+
end
5051

51-
{ :empty, _ } -> :ok
52-
end
52+
defp each(_, _, _) do
53+
:ok
5354
end
5455

5556
### nth ###
5657

5758
def nth(n) do
58-
history = Process.get(:iex_history)
59-
len = :queue.len(history)
60-
case n do
61-
n when n > 0 ->
62-
queue_nth(history, n - 1, len)
59+
entry = case n do
60+
n when n >= 0 ->
61+
Process.get({:iex_history, n})
6362
n when n < 0 ->
64-
queue_nth_r(history, -n - 1, len)
65-
0 ->
66-
raise ArgumentError[]
63+
counter = Process.get(:iex_history_counter)
64+
Process.get({:iex_history, counter + n})
6765
end
68-
end
69-
70-
defp queue_nth(_, _, 0) do
71-
raise_bounds
72-
end
73-
74-
defp queue_nth(queue, 0, _) do
75-
{ :value, value } = :queue.peek(queue)
76-
value
77-
end
78-
79-
defp queue_nth(queue, n, len) when n > 0 do
80-
queue_nth(:queue.drop(queue), n-1, len-1)
81-
end
82-
83-
defp queue_nth_r(_, _, 0) do
84-
raise_bounds
85-
end
86-
87-
defp queue_nth_r(queue, 0, _) do
88-
{ :value, value } = :queue.peek_r(queue)
89-
value
90-
end
91-
92-
defp queue_nth_r(queue, n, len) when n > 0 do
93-
queue_nth_r(:queue.drop_r(queue), n-1, len-1)
94-
end
95-
96-
defp raise_bounds do
97-
raise "Out of bounds"
66+
if nil?(entry) do
67+
raise "Out of bounds"
68+
end
69+
entry
9870
end
9971
end

lib/iex/lib/iex/server.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ defmodule IEx.Server do
8484

8585
config = config.result(result)
8686
update_history(config.cache(code).scope(nil))
87-
config.update_counter(&1+1).cache('').binding(new_binding).scope(scope)
87+
config.update_counter(&1+1).cache('').binding(new_binding).scope(scope).result(nil)
8888

8989
{ :error, { line_no, error, token } } ->
9090
if token == [] do
@@ -136,7 +136,7 @@ defmodule IEx.Server do
136136
end
137137

138138
defp update_history(config) do
139-
IEx.History.append(config)
139+
IEx.History.append(config, config.counter)
140140
end
141141

142142
defp io_get(config) do

0 commit comments

Comments
 (0)