/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/_static_tuple_c.c

  • Committer: Breezy landing bot
  • Author(s): Colin Watson
  • Date: 2020-11-16 21:47:08 UTC
  • mfrom: (7521.1.1 remove-lp-workaround)
  • Revision ID: breezy.the.bot@gmail.com-20201116214708-jos209mgxi41oy15
Remove breezy.git workaround for bazaar.launchpad.net.

Merged from https://code.launchpad.net/~cjwatson/brz/remove-lp-workaround/+merge/393710

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "_static_tuple_c.h"
27
27
#include "_export_c_api.h"
28
28
 
29
 
/* Pyrex 0.9.6.4 exports _simple_set_pyx_api as
30
 
 * import__simple_set_pyx(), while Pyrex 0.9.8.5 and Cython 0.11.3 export them
31
 
 * as import_bzrlib___simple_set_pyx(). As such, we just #define one to be
32
 
 * equivalent to the other in our internal code.
33
 
 */
34
 
#define import__simple_set_pyx import_bzrlib___simple_set_pyx
35
29
#include "_simple_set_pyx_api.h"
36
30
 
37
31
#if defined(__GNUC__)
242
236
                " should not have a NULL entry.");
243
237
            return 0;
244
238
        }
245
 
        if (PyString_CheckExact(obj)
 
239
        if (PyBytes_CheckExact(obj)
246
240
            || StaticTuple_CheckExact(obj)
247
241
            || obj == Py_None
248
242
            || PyBool_Check(obj)
 
243
#if PY_MAJOR_VERSION >= 3
 
244
#else
249
245
            || PyInt_CheckExact(obj)
 
246
#endif
250
247
            || PyLong_CheckExact(obj)
251
248
            || PyFloat_CheckExact(obj)
252
249
            || PyUnicode_CheckExact(obj)
314
311
    if (tuple_repr == NULL) {
315
312
        return NULL;
316
313
    }
 
314
#if PY_MAJOR_VERSION >= 3
 
315
    result = PyUnicode_FromFormat("StaticTuple%U", tuple_repr);
 
316
#else
317
317
    result = PyString_FromFormat("StaticTuple%s",
318
318
                                 PyString_AsString(tuple_repr));
 
319
#endif
319
320
    return result;
320
321
}
321
322
 
 
323
/* adapted from tuplehash(), is the specific hash value considered
 
324
 * 'stable'?
 
325
 */
 
326
 
 
327
#if PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 8)
 
328
/* Hash for tuples. This is a slightly simplified version of the xxHash
 
329
   non-cryptographic hash:
 
330
   - we do not use any parallellism, there is only 1 accumulator.
 
331
   - we drop the final mixing since this is just a permutation of the
 
332
     output space: it does not help against collisions.
 
333
   - at the end, we mangle the length with a single constant.
 
334
   For the xxHash specification, see
 
335
   https://github.com/Cyan4973/xxHash/blob/master/doc/xxhash_spec.md
 
336
 
 
337
   Below are the official constants from the xxHash specification. Optimizing
 
338
   compilers should emit a single "rotate" instruction for the
 
339
   _PyHASH_XXROTATE() expansion. If that doesn't happen for some important
 
340
   platform, the macro could be changed to expand to a platform-specific rotate
 
341
   spelling instead.
 
342
*/
 
343
#if SIZEOF_PY_UHASH_T > 4
 
344
#define _PyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL)
 
345
#define _PyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL)
 
346
#define _PyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL)
 
347
#define _PyHASH_XXROTATE(x) ((x << 31) | (x >> 33))  /* Rotate left 31 bits */
 
348
#else
 
349
#define _PyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL)
 
350
#define _PyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL)
 
351
#define _PyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL)
 
352
#define _PyHASH_XXROTATE(x) ((x << 13) | (x >> 19))  /* Rotate left 13 bits */
 
353
#endif
 
354
 
 
355
/* Tests have shown that it's not worth to cache the hash value, see
 
356
   https://bugs.python.org/issue9685 */
 
357
static Py_hash_t
 
358
StaticTuple_hash(StaticTuple *self)
 
359
{
 
360
    Py_ssize_t i, len = self->size;
 
361
    PyObject **item = self->items;
 
362
 
 
363
#if STATIC_TUPLE_HAS_HASH
 
364
    if (self->hash != -1) {
 
365
        return self->hash;
 
366
    }
 
367
#endif
 
368
 
 
369
    Py_uhash_t acc = _PyHASH_XXPRIME_5;
 
370
    for (i = 0; i < len; i++) {
 
371
        Py_uhash_t lane = PyObject_Hash(item[i]);
 
372
        if (lane == (Py_uhash_t)-1) {
 
373
            return -1;
 
374
        }
 
375
        acc += lane * _PyHASH_XXPRIME_2;
 
376
        acc = _PyHASH_XXROTATE(acc);
 
377
        acc *= _PyHASH_XXPRIME_1;
 
378
    }
 
379
 
 
380
    /* Add input length, mangled to keep the historical value of hash(()). */
 
381
    acc += len ^ (_PyHASH_XXPRIME_5 ^ 3527539UL);
 
382
 
 
383
    if (acc == (Py_uhash_t)-1) {
 
384
        acc = 1546275796;
 
385
    }
 
386
 
 
387
#if STATIC_TUPLE_HAS_HASH
 
388
    self->hash = acc;
 
389
#endif
 
390
    return acc;
 
391
}
 
392
 
 
393
 
 
394
#else
322
395
static long
323
396
StaticTuple_hash(StaticTuple *self)
324
397
{
356
429
#endif
357
430
    return x;
358
431
}
 
432
#endif
359
433
 
360
434
static PyObject *
361
435
StaticTuple_richcompare_to_tuple(StaticTuple *v, PyObject *wt, int op)
362
436
{
363
437
    PyObject *vt;
364
438
    PyObject *result = NULL;
365
 
    
 
439
 
366
440
    vt = StaticTuple_as_tuple((StaticTuple *)v);
367
441
    if (vt == NULL) {
368
442
        goto done;
427
501
    } else if (w == Py_None) {
428
502
        // None is always less than the object
429
503
        switch (op) {
430
 
        case Py_NE:case Py_GT:case Py_GE:
 
504
        case Py_NE:
 
505
#if PY_MAJOR_VERSION >= 3
 
506
#else
 
507
        case Py_GT:case Py_GE:
 
508
#endif
431
509
            Py_INCREF(Py_True);
432
510
            return Py_True;
433
 
        case Py_EQ:case Py_LT:case Py_LE:
 
511
        case Py_EQ:
 
512
#if PY_MAJOR_VERSION >= 3
 
513
#else
 
514
        case Py_LT:case Py_LE:
 
515
#endif
434
516
            Py_INCREF(Py_False);
435
517
            return Py_False;
436
 
    default: // Should never happen
437
 
        return Py_NotImplemented;
 
518
        default: // Should only happen on Python 3
 
519
            return Py_NotImplemented;
438
520
        }
439
521
    } else {
440
522
        /* We don't special case this comparison, we just let python handle
478
560
    vlen = v_st->size;
479
561
    wlen = w_st->size;
480
562
    min_len = (vlen < wlen) ? vlen : wlen;
481
 
    string_richcompare = PyString_Type.tp_richcompare;
 
563
    string_richcompare = PyBytes_Type.tp_richcompare;
482
564
    for (i = 0; i < min_len; i++) {
483
565
        PyObject *result = NULL;
484
566
        v_obj = StaticTuple_GET_ITEM(v_st, i);
487
569
            /* Shortcut case, these must be identical */
488
570
            continue;
489
571
        }
490
 
        if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj)) {
 
572
        if (PyBytes_CheckExact(v_obj) && PyBytes_CheckExact(w_obj)) {
491
573
            result = string_richcompare(v_obj, w_obj, Py_EQ);
492
574
        } else if (StaticTuple_CheckExact(v_obj) &&
493
575
                   StaticTuple_CheckExact(w_obj))
547
629
        return Py_True;
548
630
    }
549
631
    /* It is some other comparison, go ahead and do the real check. */
550
 
    if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj))
 
632
    if (PyBytes_CheckExact(v_obj) && PyBytes_CheckExact(w_obj))
551
633
    {
552
634
        return string_richcompare(v_obj, w_obj, op);
553
635
    } else if (StaticTuple_CheckExact(v_obj) &&
679
761
    return obj;
680
762
}
681
763
 
 
764
#if PY_MAJOR_VERSION >= 3
 
765
#else
682
766
static PyObject *
683
767
StaticTuple_slice(StaticTuple *self, Py_ssize_t ilow, Py_ssize_t ihigh)
684
768
{
692
776
    Py_DECREF(as_tuple);
693
777
    return result;
694
778
}
 
779
#endif
 
780
 
 
781
static PyObject *
 
782
StaticTuple_subscript(StaticTuple *self, PyObject *key)
 
783
{
 
784
    PyObject *as_tuple, *result;
 
785
 
 
786
    as_tuple = StaticTuple_as_tuple(self);
 
787
    if (as_tuple == NULL) {
 
788
        return NULL;
 
789
    }
 
790
    result = PyTuple_Type.tp_as_mapping->mp_subscript(as_tuple, key);
 
791
    Py_DECREF(as_tuple);
 
792
    return result;
 
793
}
695
794
 
696
795
static int
697
796
StaticTuple_traverse(StaticTuple *self, visitproc visit, void *arg)
707
806
static PyObject *
708
807
StaticTuple_sizeof(StaticTuple *self)
709
808
{
710
 
        Py_ssize_t res;
 
809
    Py_ssize_t res;
711
810
 
712
 
        res = _PyObject_SIZE(&StaticTuple_Type) + (int)self->size * sizeof(void*);
713
 
        return PyInt_FromSsize_t(res);
 
811
    res = _PyObject_SIZE(&StaticTuple_Type) + (int)self->size * sizeof(void*);
 
812
    return PyInt_FromSsize_t(res);
714
813
}
715
814
 
716
815
 
759
858
    0,                              /* nb_or */
760
859
    0,                              /* nb_coerce */
761
860
};
762
 
    
 
861
 
763
862
 
764
863
static PySequenceMethods StaticTuple_as_sequence = {
765
864
    (lenfunc)StaticTuple_length,            /* sq_length */
766
865
    0,                              /* sq_concat */
767
866
    0,                              /* sq_repeat */
768
867
    (ssizeargfunc)StaticTuple_item,         /* sq_item */
 
868
#if PY_MAJOR_VERSION >= 3
 
869
#else
769
870
    (ssizessizeargfunc)StaticTuple_slice,   /* sq_slice */
 
871
#endif
770
872
    0,                              /* sq_ass_item */
771
873
    0,                              /* sq_ass_slice */
772
874
    0,                              /* sq_contains */
773
 
};
774
 
 
775
 
/* TODO: Implement StaticTuple_as_mapping.
776
 
 *       The only thing we really want to support from there is mp_subscript,
777
 
 *       so that we could support extended slicing (foo[::2]). Not worth it
778
 
 *       yet, though.
779
 
 */
 
875
#if PY_MAJOR_VERSION >= 3
 
876
    0,                              /* sq_inplace_concat */
 
877
    0,                              /* sq_inplace_repeat */
 
878
#endif
 
879
};
 
880
 
 
881
 
 
882
static PyMappingMethods StaticTuple_as_mapping = {
 
883
    (lenfunc)StaticTuple_length,            /* mp_length */
 
884
    (binaryfunc)StaticTuple_subscript,      /* mp_subscript */
 
885
    0,                                      /* mp_ass_subscript */
 
886
};
780
887
 
781
888
 
782
889
PyTypeObject StaticTuple_Type = {
783
 
    PyObject_HEAD_INIT(NULL)
784
 
    0,                                           /* ob_size */
785
 
    "bzrlib._static_tuple_c.StaticTuple",        /* tp_name */
 
890
    PyVarObject_HEAD_INIT(NULL, 0)
 
891
    "breezy._static_tuple_c.StaticTuple",        /* tp_name */
786
892
    sizeof(StaticTuple),                         /* tp_basicsize */
787
893
    sizeof(PyObject *),                          /* tp_itemsize */
788
894
    (destructor)StaticTuple_dealloc,             /* tp_dealloc */
793
899
    (reprfunc)StaticTuple_repr,                  /* tp_repr */
794
900
    &StaticTuple_as_number,                      /* tp_as_number */
795
901
    &StaticTuple_as_sequence,                    /* tp_as_sequence */
796
 
    0,                                           /* tp_as_mapping */
 
902
    &StaticTuple_as_mapping,                     /* tp_as_mapping */
797
903
    (hashfunc)StaticTuple_hash,                  /* tp_hash */
798
904
    0,                                           /* tp_call */
799
905
    0,                                           /* tp_str */
887
993
}
888
994
 
889
995
 
890
 
static int
891
 
_workaround_pyrex_096(void)
892
 
{
893
 
    /* Work around an incompatibility in how pyrex 0.9.6 exports a module,
894
 
     * versus how pyrex 0.9.8 and cython 0.11 export it.
895
 
     * Namely 0.9.6 exports import__simple_set_pyx and tries to
896
 
     * "import _simple_set_pyx" but it is available only as
897
 
     * "import bzrlib._simple_set_pyx"
898
 
     * It is a shame to hack up sys.modules, but that is what we've got to do.
899
 
     */
900
 
    PyObject *sys_module = NULL, *modules = NULL, *set_module = NULL;
901
 
    int retval = -1;
902
 
 
903
 
    /* Clear out the current ImportError exception, and try again. */
904
 
    PyErr_Clear();
905
 
    /* Note that this only seems to work if somewhere else imports
906
 
     * bzrlib._simple_set_pyx before importing bzrlib._static_tuple_c
907
 
     */
908
 
    set_module = PyImport_ImportModule("bzrlib._simple_set_pyx");
909
 
    if (set_module == NULL) {
910
 
        goto end;
911
 
    }
912
 
    /* Add the _simple_set_pyx into sys.modules at the appropriate location. */
913
 
    sys_module = PyImport_ImportModule("sys");
914
 
    if (sys_module == NULL) {
915
 
        goto end;
916
 
    }
917
 
    modules = PyObject_GetAttrString(sys_module, "modules");
918
 
    if (modules == NULL || !PyDict_Check(modules)) {
919
 
        goto end;
920
 
    }
921
 
    PyDict_SetItemString(modules, "_simple_set_pyx", set_module);
922
 
    /* Now that we have hacked it in, try the import again. */
923
 
    retval = import_bzrlib___simple_set_pyx();
924
 
end:
925
 
    Py_XDECREF(set_module);
926
 
    Py_XDECREF(sys_module);
927
 
    Py_XDECREF(modules);
928
 
    return retval;
929
 
}
930
 
 
931
 
 
932
 
PyMODINIT_FUNC
933
 
init_static_tuple_c(void)
 
996
PYMOD_INIT_FUNC(_static_tuple_c)
934
997
{
935
998
    PyObject* m;
936
999
 
937
1000
    StaticTuple_Type.tp_getattro = PyObject_GenericGetAttr;
938
 
    if (PyType_Ready(&StaticTuple_Type) < 0)
939
 
        return;
 
1001
    if (PyType_Ready(&StaticTuple_Type) < 0) {
 
1002
        return PYMOD_ERROR;
 
1003
    }
940
1004
 
941
 
    m = Py_InitModule3("_static_tuple_c", static_tuple_c_methods,
942
 
                       "C implementation of a StaticTuple structure");
943
 
    if (m == NULL)
944
 
      return;
 
1005
    PYMOD_CREATE(m, "_static_tuple_c",
 
1006
                 "C implementation of a StaticTuple structure",
 
1007
                 static_tuple_c_methods);
 
1008
    if (m == NULL) {
 
1009
      return PYMOD_ERROR;
 
1010
    }
945
1011
 
946
1012
    Py_INCREF(&StaticTuple_Type);
947
1013
    PyModule_AddObject(m, "StaticTuple", (PyObject *)&StaticTuple_Type);
948
 
    if (import_bzrlib___simple_set_pyx() == -1
949
 
        && _workaround_pyrex_096() == -1)
950
 
    {
951
 
        return;
 
1014
    if (import_breezy___simple_set_pyx() == -1) {
 
1015
        return PYMOD_ERROR;
952
1016
    }
953
1017
    setup_interned_tuples(m);
954
1018
    setup_empty_tuple(m);
955
1019
    setup_c_api(m);
 
1020
 
 
1021
    return PYMOD_SUCCESS(m);
956
1022
}
957
1023
 
958
1024
// vim: tabstop=4 sw=4 expandtab