@@ -59,17 +59,20 @@ def get_set(self):
59
59
class OpBuilderInputType (Enum ):
60
60
SET = 1
61
61
STREAM_BUILDER = 2
62
+ UNION = 3
62
63
63
64
64
65
class OpBuilder (object ):
65
66
66
67
_BUILDERS = {
67
68
OpBuilderInputType .SET : lib .fst_set_make_opbuilder ,
68
69
OpBuilderInputType .STREAM_BUILDER : lib .fst_set_make_opbuilder_streambuilder ,
70
+ OpBuilderInputType .UNION : lib .fst_set_make_opbuilder_union ,
69
71
}
70
72
_PUSHERS = {
71
73
OpBuilderInputType .SET : lib .fst_set_opbuilder_push ,
72
74
OpBuilderInputType .STREAM_BUILDER : lib .fst_set_opbuilder_push_streambuilder ,
75
+ OpBuilderInputType .UNION : lib .fst_set_opbuilder_push_union ,
73
76
}
74
77
75
78
@classmethod
@@ -452,3 +455,66 @@ def __iter__(self):
452
455
for fst in self .sets [1 :]:
453
456
opbuilder .push (fst ._ptr )
454
457
return opbuilder .union ()
458
+
459
+ def _make_opbuilder (self , * others ):
460
+ others = list (others )
461
+ if len (self .sets ) <= 1 :
462
+ raise ValueError (
463
+ "Must have more than one set to operate on." )
464
+ if not others :
465
+ raise ValueError (
466
+ "Must have at least one set to compare against." )
467
+ our_opbuilder = OpBuilder (self .sets [0 ]._ptr ,
468
+ input_type = OpBuilderInputType .SET )
469
+ for fst in self .sets [1 :]:
470
+ our_opbuilder .push (fst ._ptr )
471
+ our_stream = lib .fst_set_opbuilder_union (our_opbuilder ._ptr )
472
+
473
+ their_opbuilder = OpBuilder (others .pop ()._ptr ,
474
+ input_type = OpBuilderInputType .SET )
475
+ for fst in others :
476
+ their_opbuilder .push (fst ._ptr )
477
+ their_stream = lib .fst_set_opbuilder_union (their_opbuilder ._ptr )
478
+
479
+ opbuilder = OpBuilder (our_stream , input_type = OpBuilderInputType .UNION )
480
+ opbuilder .push (their_stream )
481
+ return opbuilder
482
+
483
+ def difference (self , * others ):
484
+ """ Get an iterator over the keys in the difference of this set and
485
+ others.
486
+
487
+ :param others: List of :py:class:`Set` objects
488
+ :returns: Iterator over all keys that exists in this set, but in
489
+ none of the other sets, in lexicographical order
490
+ """
491
+ return self ._make_opbuilder (* others ).difference ()
492
+
493
+ def intersection (self , * others ):
494
+ """ Get an iterator over the keys in the intersection of this set and
495
+ others.
496
+
497
+ :param others: List of :py:class:`Set` objects
498
+ :returns: Iterator over all keys that exists in all of the passed
499
+ sets in lexicographical order
500
+ """
501
+ return self ._make_opbuilder (* others ).intersection ()
502
+
503
+ def symmetric_difference (self , * others ):
504
+ """ Get an iterator over the keys in the symmetric difference of this
505
+ set and others.
506
+
507
+ :param others: List of :py:class:`Set` objects
508
+ :returns: Iterator over all keys that exists in only one of the
509
+ sets in lexicographical order
510
+ """
511
+ return self ._make_opbuilder (* others ).symmetric_difference ()
512
+
513
+ def union (self , * others ):
514
+ """ Get an iterator over the keys in the union of this set and others.
515
+
516
+ :param others: List of :py:class:`Set` objects
517
+ :returns: Iterator over all keys in all sets in lexicographical
518
+ order
519
+ """
520
+ return self ._make_opbuilder (* others ).union ()
0 commit comments