Skip to content

Commit 05c6f70

Browse files
committed
added isdijoint builtin to DictViewBuiltins
1 parent f705d68 commit 05c6f70

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

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

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,69 @@ boolean contains(Object self, Object key) {
176176

177177
}
178178

179+
@Builtin(name = ISDISJOINT, minNumOfPositionalArgs = 2)
180+
@GenerateNodeFactory
181+
public abstract static class IsDisjointNode extends PythonBinaryBuiltinNode {
182+
183+
@Specialization(guards = {"self == other"})
184+
boolean disjointSame(PDictView self, @SuppressWarnings("unused") PDictView other) {
185+
return self.getWrappedDict().size() == 0;
186+
}
187+
188+
@Specialization(guards = {"self != other"}, limit = "1")
189+
boolean disjointNotSame(VirtualFrame frame, PDictView self, PDictView other,
190+
@Cached ConditionProfile sizeProfile,
191+
@CachedLibrary("other") PythonObjectLibrary lib,
192+
@Cached("create(false)") ContainedInNode contained) {
193+
return disjointImpl(frame, self, other, sizeProfile, lib, contained);
194+
}
195+
196+
@Specialization(limit = "1")
197+
boolean disjoint(VirtualFrame frame, PDictView self, PBaseSet other,
198+
@Cached ConditionProfile sizeProfile,
199+
@CachedLibrary("other") PythonObjectLibrary lib,
200+
@Cached("create(false)") ContainedInNode contained) {
201+
return disjointImpl(frame, self, other, sizeProfile, lib, contained);
202+
}
203+
204+
private static boolean disjointImpl(VirtualFrame frame, PDictView self, Object other, ConditionProfile sizeProfile, PythonObjectLibrary lib, ContainedInNode contained) {
205+
if (sizeProfile.profile(self.size() <= lib.length(other))) {
206+
return !contained.execute(frame, self, other);
207+
} else {
208+
return !contained.execute(frame, other, self);
209+
}
210+
}
211+
212+
@Specialization(guards = {"lib.isIterable(other)", "!isAnySet(other)", "!isDictView(other)"}, limit = "1")
213+
boolean disjoint(VirtualFrame frame, PDictView self, Object other,
214+
@SuppressWarnings("unused") @CachedLibrary("other") PythonObjectLibrary lib,
215+
@Cached("create(false)") ContainedInNode contained) {
216+
return !contained.execute(frame, other, self);
217+
}
218+
219+
@SuppressWarnings("unused")
220+
@Specialization(guards = "!lib.isIterable(other)", limit = "1")
221+
boolean disjoint(PDictView self, Object other,
222+
@CachedLibrary("other") PythonObjectLibrary lib) {
223+
throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.OBJ_NOT_ITERABLE, other);
224+
}
225+
}
226+
179227
/**
180-
* See CPython's dictobject.c all_contained_in. The semantics of dict view comparisons dictates
181-
* that we need to use iteration to compare them in the general case.
228+
* See CPython's dictobject.c all_contained_in and dictviews_isdisjoint. The semantics of dict
229+
* view comparisons dictates that we need to use iteration to compare them in the general case.
182230
*/
183-
protected static class AllContainedInNode extends PNodeWithContext {
231+
protected static class ContainedInNode extends PNodeWithContext {
184232
@Child GetIteratorNode iter = GetIteratorNode.create();
185233
@Child GetNextNode next;
186234
@Child LookupAndCallBinaryNode contains;
187235
@Child CoerceToBooleanNode cast;
188236
@CompilationFinal IsBuiltinClassProfile stopProfile;
237+
private final boolean checkAll;
238+
239+
public ContainedInNode(boolean checkAll) {
240+
this.checkAll = checkAll;
241+
}
189242

190243
private GetNextNode getNext() {
191244
if (next == null) {
@@ -221,9 +274,9 @@ private IsBuiltinClassProfile getStopProfile() {
221274

222275
public boolean execute(VirtualFrame frame, Object self, Object other) {
223276
Object iterator = iter.executeWith(frame, self);
224-
boolean ok = true;
277+
boolean ok = checkAll;
225278
try {
226-
while (ok) {
279+
while (checkAll && ok || !checkAll && !ok) {
227280
Object item = getNext().execute(frame, iterator);
228281
ok = getCast().executeBoolean(frame, getContains().executeObject(frame, other, item));
229282
}
@@ -233,8 +286,12 @@ public boolean execute(VirtualFrame frame, Object self, Object other) {
233286
return ok;
234287
}
235288

236-
public static AllContainedInNode create() {
237-
return new AllContainedInNode();
289+
static ContainedInNode create() {
290+
return new ContainedInNode(true);
291+
}
292+
293+
static ContainedInNode create(boolean all) {
294+
return new ContainedInNode(all);
238295
}
239296
}
240297

@@ -253,7 +310,7 @@ protected boolean lenCompare(@SuppressWarnings("unused") int lenSelf, @SuppressW
253310
boolean doView(VirtualFrame frame, PDictView self, PBaseSet other,
254311
@CachedLibrary("self.getWrappedDict().getDictStorage()") HashingStorageLibrary selflib,
255312
@CachedLibrary("other.getDictStorage()") HashingStorageLibrary otherlib,
256-
@Cached AllContainedInNode allContained) {
313+
@Cached ContainedInNode allContained) {
257314
int lenSelf = selflib.length(self.getWrappedDict().getDictStorage());
258315
int lenOther = otherlib.length(other.getDictStorage());
259316
return lenCompare(lenSelf, lenOther) && (reverse() ? allContained.execute(frame, other, self) : allContained.execute(frame, self, other));
@@ -263,7 +320,7 @@ boolean doView(VirtualFrame frame, PDictView self, PBaseSet other,
263320
boolean doView(VirtualFrame frame, PDictView self, PDictView other,
264321
@CachedLibrary("self.getWrappedDict().getDictStorage()") HashingStorageLibrary selflib,
265322
@CachedLibrary("other.getWrappedDict().getDictStorage()") HashingStorageLibrary otherlib,
266-
@Cached AllContainedInNode allContained) {
323+
@Cached ContainedInNode allContained) {
267324
int lenSelf = selflib.length(self.getWrappedDict().getDictStorage());
268325
int lenOther = otherlib.length(other.getWrappedDict().getDictStorage());
269326
return lenCompare(lenSelf, lenOther) && (reverse() ? allContained.execute(frame, other, self) : allContained.execute(frame, self, other));

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/SpecialMethodNames.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ public abstract class SpecialMethodNames {
165165
public static final String __SIZEOF__ = "__sizeof__";
166166
public static final String __CLASS_GETITEM__ = "__class_getitem__";
167167
public static final String FILENO = "fileno";
168+
public static final String ISDISJOINT = "isdisjoint";
168169

169170
public static final String RICHCMP = "__truffle_richcompare__";
170171
public static final String TRUFFLE_SOURCE = "__truffle_source__";

0 commit comments

Comments
 (0)