Skip to content

Commit bf00ab3

Browse files
committed
GR-10787 / GR-10789 add support for dict keys view / items set oprations
1 parent c60a95a commit bf00ab3

File tree

3 files changed

+71
-19
lines changed

3 files changed

+71
-19
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/HashingStorageNodes.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ public boolean equals(Object left, Object right) {
162162
return callEqNode.executeBool(left, right);
163163
}
164164

165+
public static PythonEquivalence create() {
166+
return new PythonEquivalence();
167+
}
165168
}
166169

167170
@ImportStatic(PGuards.class)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictViewBuiltins.java

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictItemsView;
6060
import com.oracle.graal.python.builtins.objects.dict.PDictView.PDictKeysView;
6161
import com.oracle.graal.python.builtins.objects.set.PBaseSet;
62+
import com.oracle.graal.python.builtins.objects.set.PSet;
63+
import com.oracle.graal.python.builtins.objects.set.SetNodes;
64+
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
6265
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
6366
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
6467
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -68,6 +71,7 @@
6871
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
6972
import com.oracle.truffle.api.dsl.NodeFactory;
7073
import com.oracle.truffle.api.dsl.Specialization;
74+
import com.oracle.truffle.api.profiles.ConditionProfile;
7175

7276
@CoreFunctions(extendClasses = {PDictKeysView.class, PDictItemsView.class})
7377
public final class DictViewBuiltins extends PythonBuiltins {
@@ -116,10 +120,23 @@ boolean containsEmpty(PDictView self, Object key) {
116120
}
117121

118122
@Specialization
119-
boolean contains(PDictView self, Object key,
123+
boolean contains(PDictKeysView self, Object key,
120124
@Cached("create()") HashingStorageNodes.ContainsKeyNode containsKeyNode) {
121125
return containsKeyNode.execute(self.getDict().getDictStorage(), key);
122126
}
127+
128+
@Specialization
129+
boolean contains(PDictItemsView self, PTuple key,
130+
@Cached("create()") HashingStorageNodes.GetItemNode getItemNode,
131+
@Cached("create()") HashingStorageNodes.PythonEquivalence equivalenceNode,
132+
@Cached("createBinaryProfile()") ConditionProfile tupleLenProfile) {
133+
if (tupleLenProfile.profile(key.len() != 2)) {
134+
return false;
135+
}
136+
HashingStorage dictStorage = self.getDict().getDictStorage();
137+
Object value = getItemNode.execute(dictStorage, key.getItem(0));
138+
return value != null && equivalenceNode.equals(value, key.getItem(1));
139+
}
123140
}
124141

125142
@Builtin(name = __EQ__, fixedNumOfArguments = 2)
@@ -133,11 +150,27 @@ boolean doKeysView(PDictKeysView self, PDictKeysView other,
133150
}
134151

135152
@Specialization
136-
boolean doItemsView(PDictKeysView self, PBaseSet other,
153+
boolean doKeysView(PDictKeysView self, PBaseSet other,
137154
@Cached("create()") HashingStorageNodes.KeysEqualsNode equalsNode) {
138155
return equalsNode.execute(self.getDict().getDictStorage(), other.getDictStorage());
139156
}
140157

158+
@Specialization
159+
boolean doItemsView(PDictItemsView self, PDictItemsView other,
160+
@Cached("create()") HashingStorageNodes.EqualsNode equalsNode) {
161+
// the items view stores the original dict with K:V pairs so full K:V equality needs to
162+
// be tested in this case
163+
return equalsNode.execute(self.getDict().getDictStorage(), other.getDict().getDictStorage());
164+
}
165+
166+
@Specialization
167+
boolean doItemsView(PDictItemsView self, PBaseSet other,
168+
@Cached("create()") SetNodes.ConstructSetNode constructSetNode,
169+
@Cached("create()") HashingStorageNodes.KeysEqualsNode equalsNode) {
170+
PSet selfSet = constructSetNode.executeWith(self);
171+
return equalsNode.execute(selfSet.getDictStorage(), other.getDictStorage());
172+
}
173+
141174
@Fallback
142175
@SuppressWarnings("unused")
143176
Object doGeneric(Object self, Object other) {
@@ -149,16 +182,19 @@ Object doGeneric(Object self, Object other) {
149182
@GenerateNodeFactory
150183
abstract static class SubNode extends PythonBinaryBuiltinNode {
151184
@Specialization
152-
PBaseSet doItemsView(PDictItemsView left, PDictItemsView right,
185+
PBaseSet doKeysView(PDictKeysView left, PDictKeysView right,
153186
@Cached("create()") HashingStorageNodes.DiffNode diffNode) {
154187
HashingStorage storage = diffNode.execute(left.getDict().getDictStorage(), right.getDict().getDictStorage());
155188
return factory().createSet(storage);
156189
}
157190

158191
@Specialization
159-
PBaseSet doKeysView(PDictKeysView left, PDictKeysView right,
160-
@Cached("create()") HashingStorageNodes.DiffNode diffNode) {
161-
HashingStorage storage = diffNode.execute(left.getDict().getDictStorage(), right.getDict().getDictStorage());
192+
PBaseSet doItemsView(PDictItemsView self, PDictItemsView other,
193+
@Cached("create()") HashingStorageNodes.DiffNode diffNode,
194+
@Cached("create()") SetNodes.ConstructSetNode constructSetNode) {
195+
PSet selfSet = constructSetNode.executeWith(self);
196+
PSet otherSet = constructSetNode.executeWith(other);
197+
HashingStorage storage = diffNode.execute(selfSet.getDictStorage(), otherSet.getDictStorage());
162198
return factory().createSet(storage);
163199
}
164200
}
@@ -167,16 +203,19 @@ PBaseSet doKeysView(PDictKeysView left, PDictKeysView right,
167203
@GenerateNodeFactory
168204
abstract static class AndNode extends PythonBinaryBuiltinNode {
169205
@Specialization
170-
PBaseSet doItemsView(PDictItemsView left, PDictItemsView right,
206+
PBaseSet doKeysView(PDictKeysView self, PDictKeysView other,
171207
@Cached("create()") HashingStorageNodes.IntersectNode intersectNode) {
172-
HashingStorage intersectedStorage = intersectNode.execute(left.getDict().getDictStorage(), right.getDict().getDictStorage());
208+
HashingStorage intersectedStorage = intersectNode.execute(self.getDict().getDictStorage(), other.getDict().getDictStorage());
173209
return factory().createSet(intersectedStorage);
174210
}
175211

176212
@Specialization
177-
PBaseSet doKeysView(PDictKeysView left, PDictKeysView right,
178-
@Cached("create()") HashingStorageNodes.IntersectNode intersectNode) {
179-
HashingStorage intersectedStorage = intersectNode.execute(left.getDict().getDictStorage(), right.getDict().getDictStorage());
213+
PBaseSet doItemsView(PDictItemsView self, PDictItemsView other,
214+
@Cached("create()") HashingStorageNodes.IntersectNode intersectNode,
215+
@Cached("create()") SetNodes.ConstructSetNode constructSetNode) {
216+
PSet selfSet = constructSetNode.executeWith(self);
217+
PSet otherSet = constructSetNode.executeWith(other);
218+
HashingStorage intersectedStorage = intersectNode.execute(selfSet.getDictStorage(), otherSet.getDictStorage());
180219
return factory().createSet(intersectedStorage);
181220
}
182221
}
@@ -185,31 +224,37 @@ PBaseSet doKeysView(PDictKeysView left, PDictKeysView right,
185224
@GenerateNodeFactory
186225
public abstract static class OrNode extends PythonBuiltinNode {
187226
@Specialization
188-
PBaseSet doItemsView(PDictItemsView self, PDictItemsView other,
227+
PBaseSet doKeysView(PDictKeysView self, PDictKeysView other,
189228
@Cached("create()") HashingStorageNodes.UnionNode unionNode) {
190229
return factory().createSet(unionNode.execute(self.getDict().getDictStorage(), other.getDict().getDictStorage()));
191230
}
192231

193232
@Specialization
194-
PBaseSet doKeysView(PDictKeysView self, PDictKeysView other,
195-
@Cached("create()") HashingStorageNodes.UnionNode unionNode) {
196-
return factory().createSet(unionNode.execute(self.getDict().getDictStorage(), other.getDict().getDictStorage()));
233+
PBaseSet doItemsView(PDictItemsView self, PDictItemsView other,
234+
@Cached("create()") HashingStorageNodes.UnionNode unionNode,
235+
@Cached("create()") SetNodes.ConstructSetNode constructSetNode) {
236+
PSet selfSet = constructSetNode.executeWith(self);
237+
PSet otherSet = constructSetNode.executeWith(other);
238+
return factory().createSet(unionNode.execute(selfSet.getDictStorage(), otherSet.getDictStorage()));
197239
}
198240
}
199241

200242
@Builtin(name = __XOR__, fixedNumOfArguments = 2)
201243
@GenerateNodeFactory
202244
public abstract static class XorNode extends PythonBuiltinNode {
203245
@Specialization
204-
PBaseSet doItemsView(PDictItemsView self, PDictItemsView other,
246+
PBaseSet doKeysView(PDictKeysView self, PDictKeysView other,
205247
@Cached("create()") HashingStorageNodes.ExclusiveOrNode xorNode) {
206248
return factory().createSet(xorNode.execute(self.getDict().getDictStorage(), other.getDict().getDictStorage()));
207249
}
208250

209251
@Specialization
210-
PBaseSet doKeysView(PDictKeysView self, PDictKeysView other,
211-
@Cached("create()") HashingStorageNodes.ExclusiveOrNode xorNode) {
212-
return factory().createSet(xorNode.execute(self.getDict().getDictStorage(), other.getDict().getDictStorage()));
252+
PBaseSet doItemsView(PDictItemsView self, PDictItemsView other,
253+
@Cached("create()") HashingStorageNodes.ExclusiveOrNode xorNode,
254+
@Cached("create()") SetNodes.ConstructSetNode constructSetNode) {
255+
PSet selfSet = constructSetNode.executeWith(self);
256+
PSet otherSet = constructSetNode.executeWith(other);
257+
return factory().createSet(xorNode.execute(selfSet.getDictStorage(), otherSet.getDictStorage()));
213258
}
214259
}
215260
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/PDictView.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ public final PDict getDict() {
5757
return dict;
5858
}
5959

60+
public int size() {
61+
return dict.size();
62+
}
63+
6064
// -----------------------------------------------------------------------------------------------------------------
6165
//
6266
// the keys

0 commit comments

Comments
 (0)