Skip to content

Commit 8d065f3

Browse files
author
Nicolas Laurent
committed
move Array#recursively_flatten to ArrayOperations#flatten_helper
1 parent c99bac0 commit 8d065f3

File tree

3 files changed

+53
-42
lines changed

3 files changed

+53
-42
lines changed

src/main/java/org/truffleruby/core/CoreLibrary.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,7 @@ public boolean isTruffleBootMainMethod(SharedMethodInfo info) {
10491049
"/core/truffle/internal.rb",
10501050
"/core/kernel.rb",
10511051
"/core/lazy_rubygems.rb",
1052+
"/core/truffle/array_operations.rb",
10521053
"/core/truffle/boot.rb",
10531054
"/core/truffle/debug.rb",
10541055
"/core/truffle/encoding_operations.rb",

src/main/ruby/truffleruby/core/array.rb

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def flatten(level=-1)
444444
return self.dup if level == 0
445445

446446
out = self.class.allocate # new_reserved size
447-
recursively_flatten(self, out, level)
447+
Truffle::ArrayOperations.flatten_helper(self, out, level)
448448
Primitive.infect(out, self)
449449
out
450450
end
@@ -456,7 +456,7 @@ def flatten!(level=-1)
456456
return nil if level == 0
457457

458458
out = self.class.allocate # new_reserved size
459-
if recursively_flatten(self, out, level)
459+
if Truffle::ArrayOperations.flatten_helper(self, out, level)
460460
Primitive.steal_array_storage(self, out)
461461
return self
462462
end
@@ -1251,46 +1251,6 @@ def zip(*others)
12511251
end
12521252
end
12531253

1254-
# Helper to "recurse" through flattening. Detects recursive structures.
1255-
# Does not actually recurse, but uses a worklist instead.
1256-
def recursively_flatten(array, out, max_levels = -1)
1257-
modified = false
1258-
visited = {}.compare_by_identity
1259-
worklist = [[array, 0]]
1260-
1261-
until worklist.empty?
1262-
array, i = worklist.pop
1263-
1264-
if i == 0
1265-
raise ArgumentError, 'tried to flatten recursive array' if visited.key?(array)
1266-
if max_levels == worklist.size
1267-
out.concat(array)
1268-
next
1269-
end
1270-
visited[array] = true
1271-
end
1272-
1273-
size = array.size
1274-
while i < size
1275-
o = array.at i
1276-
tmp = Truffle::Type.rb_check_convert_type(o, Array, :to_ary)
1277-
if Primitive.nil? tmp
1278-
out << o
1279-
else
1280-
modified = true
1281-
worklist.push([array, i + 1], [tmp, 0])
1282-
break
1283-
end
1284-
i += 1
1285-
end
1286-
1287-
visited.delete array if i == size
1288-
end
1289-
1290-
modified
1291-
end
1292-
private :recursively_flatten
1293-
12941254
private def sort_fallback(&block)
12951255
# Use this instead of #dup as we want an instance of Array
12961256
sorted = Array.new(self)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. This
4+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
5+
# redistribute it and/or modify it under the terms of the:
6+
#
7+
# Eclipse Public License version 2.0, or
8+
# GNU General Public License version 2, or
9+
# GNU Lesser General Public License version 2.1.
10+
#
11+
module Truffle::ArrayOperations
12+
# Helper to "recurse" through flattening. Detects recursive structures.
13+
# Does not actually recurse, but uses a worklist instead.
14+
def self.flatten_helper(array, out, max_levels = -1)
15+
modified = false
16+
visited = {}.compare_by_identity
17+
worklist = [[array, 0]]
18+
19+
until worklist.empty?
20+
array, i = worklist.pop
21+
22+
if i == 0
23+
raise ArgumentError, 'tried to flatten recursive array' if visited.key?(array)
24+
if max_levels == worklist.size
25+
out.concat(array)
26+
next
27+
end
28+
visited[array] = true
29+
end
30+
31+
size = array.size
32+
while i < size
33+
o = array.at i
34+
tmp = Truffle::Type.rb_check_convert_type(o, Array, :to_ary)
35+
if Primitive.nil? tmp
36+
out << o
37+
else
38+
modified = true
39+
worklist.push([array, i + 1], [tmp, 0])
40+
break
41+
end
42+
i += 1
43+
end
44+
45+
visited.delete array if i == size
46+
end
47+
48+
modified
49+
end
50+
end

0 commit comments

Comments
 (0)