#13387: Improve MonoDict and TripleDict data structures
----------------------------------+-----------------------------------------
       Reporter:  nbruin          |         Owner:  Nils Bruin  
           Type:  enhancement     |        Status:  needs_review
       Priority:  major           |     Milestone:  sage-5.8    
      Component:  memleak         |    Resolution:              
       Keywords:                  |   Work issues:              
Report Upstream:  N/A             |     Reviewers:              
        Authors:  Nils Bruin      |     Merged in:              
   Dependencies:  #11521, #12313  |      Stopgaps:              
----------------------------------+-----------------------------------------

Comment (by nbruin):

 Replying to [comment:39 jdemeyer]:
 > Not really, since Python doesn't define a function like
 {{{PyInt_AsIntptr_t}}}.
 > But, like I said, for all current systems, we have `ssize_t ==
 intptr_t`.

 There is something that comes close, though:
 Python's `id` is implemented via `PyLong_FromVoidPtr`. This routine only
 compiles if `sizeof(void *) <= sizeof(long)` or if `sizeof(void *) <=
 sizeof(long long)` (if that type is available).

 So CPython itself is taking reasonable but not extreme measures to support
 odd pointer sizes (I guess `sizeof(void *) !=sizeof(long)` is quite
 possible)

 The definition is available:
 {{{
 cdef extern from "stdint.h":
     ctypedef long intptr_t #doesn't need to match exactly
 }}}

 In order to find conversion routines in Python that are guaranteed of the
 right length, we'd have to go with `PyLong_FromVoidPtr` and
 `PyLong_AsVoidPtr`. So basically we'd be working with `void *` and convert
 to `intptr_t` if we need to do arithmetic.

 In fact, at that time we can afford to lose bits, so we wouldn't
 particularly need `intptr_t` as a type at all. We can just cast to
 `<long>` once we do arithmetic to compute the hash value or the bucket
 number.

 So the question really is: Do we want to let our keys be `<void *>` rather
 than `Py_Ssize_t`?
 We do need to pack and unpack those keys into the bucket `PyList` objects.

 There is a slight problem there: `PyLong_FromVoidPtr` goes through extra
 trouble to interpret `void *` as an unsigned quantity (if only it didn't
 do that! what's wrong with a negative pointer?). Thus even on systems
 where a PyInt and a `void *` have the same number of bits available, half
 of the possible values will be stored in a `PyLong` anyway (because of
 sign). [Note that `PyLong_FromVoidPtr` is happy to produce a `PyInt` if it
 thinks it fits.

 So yes, we could do that and guard against future platforms where
 `sizeof(void *) > sizeof(size_t)`, but we'd do so at a storage and
 performance penalty on our platforms now.
 (probably very rare on 64bit, because pointer tend to have their top bits
 zero there, but on 32-bit it's very common to have pointers with their top
 bit set)

 I'm not sure it's worth it.

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/13387#comment:40>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to