Welcome! Please see the About page for a little more info on how this works.

0 votes
in data.int-map by

`
(iset/union (iset/int-set)

        (iset/dense-int-set))

`

throws java.lang.IllegalArgumentException: Cannot merge int-sets of different density.

Now this might not be a bug per se, but the README on GitHub claims that

bq. dense-int-set behaves the same as int-set, the difference is only in their memory efficiency.

I think it should either be possible to mix dense/normal sets, or state explicitly in the documentation that it isn't and also possibly update the error message since it wasn't obvious to me that this is the cause (I had totally forgotten I had used dense sets in this one place and believed the problem to be caused by transients).

3 Answers

0 votes
by

Comment made by: ztellman

This is slightly non-trivial to implement, so I may just clarify that it can't be done in the documentation to begin, but the expected behavior is that an operation with sets of different density should return a combined set with the lower density.

0 votes
by

Comment made by: jbiserkov

Makes sense.

Looking at the (link: https://github.com/clojure/data.int-map/blob/5442570fafa3eb4bbeec3286d67c9295d484fc4f/src/main/java/clojure/data/int_map/IntSet.java#L371 text: code) I wasn't sure whether the check/exception is part of the "public API" or was intended as a "fail early" signal to yourself that an internal invariant has been violated.

Thanks again for the quick response. A note in the README should be enough. Intersection and difference don't throw exceptions since they don't use the merge operation. From my reading of the (link: https://github.com/clojure/data.int-map/blob/9b34590f56db3e92a39eeb8ea31a8e8afbfa09b3/src/main/java/clojure/data/int_map/IntSet.java#L366 text: code) though the resulting sets have the density (leafSize) of the this argument.

Could this be used instead? Is it worth the trouble?

`
return new IntSet(Math.min(leafSize, s.leafSize),

              Math.min(log2LeafSize, s.log2LeafSize), 
              node);

`

The exception could be made more explicit "Cannot compute the union of an int-set and a dense-int-set."

Using the "constructor" names and the name of the operation that failed (union instead of merge) could make it clearer the end-user where the problem is.

Offtopic: This doesn't really affect my program anymore - only the 1st implementation uses union/difference/intersection. The 2nd and 3rd only use disj. The 1st implementation has served it's purpose - making sure the 2nd is correct. Now the 2nd can be used to verify the correctness of the 3rd, over an even more diverse set of inputs, for some of which a dense-set makes sense.

0 votes
by
Reference: https://clojure.atlassian.net/browse/DIMAP-13 (reported by jbiserkov)
...