/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 bzrlib/_static_tuple_c.c

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-10-20 23:25:36 UTC
  • mfrom: (4759.1.2 2.1-chk-inv)
  • Revision ID: pqm@pqm.ubuntu.com-20091020232536-4azg7ofe3varsq2b
(jam) Some small tweaks for memory consumption of CHKInventory and
        CHKMap.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2009, 2010 Canonical Ltd
 
1
/* Copyright (C) 2009 Canonical Ltd
2
2
 * 
3
3
 * This program is free software; you can redistribute it and/or modify
4
4
 * it under the terms of the GNU General Public License as published by
140
140
StaticTuple_New(Py_ssize_t size)
141
141
{
142
142
    StaticTuple *stuple;
143
 
 
144
 
    if (size < 0 || size > 255) {
145
 
        /* Too big or too small */
146
 
        PyErr_SetString(PyExc_ValueError, "StaticTuple(...)"
147
 
            " takes from 0 to 255 items");
 
143
    if (size < 0) {
 
144
        PyErr_BadInternalCall();
148
145
        return NULL;
149
146
    }
 
147
 
150
148
    if (size == 0 && _empty_tuple != NULL) {
151
149
        Py_INCREF(_empty_tuple);
152
150
        return _empty_tuple;
179
177
static StaticTuple *
180
178
StaticTuple_FromSequence(PyObject *sequence)
181
179
{
182
 
    StaticTuple *new = NULL;
183
 
    PyObject *as_tuple = NULL;
 
180
    StaticTuple *new;
184
181
    PyObject *item;
185
182
    Py_ssize_t i, size;
186
183
 
189
186
        return (StaticTuple *)sequence;
190
187
    }
191
188
    if (!PySequence_Check(sequence)) {
192
 
        as_tuple = PySequence_Tuple(sequence);
193
 
        if (as_tuple == NULL)
194
 
            goto done;
195
 
        sequence = as_tuple;
 
189
        PyErr_Format(PyExc_TypeError, "Type %s is not a sequence type",
 
190
                     Py_TYPE(sequence)->tp_name);
 
191
        return NULL;
196
192
    }
197
193
    size = PySequence_Size(sequence);
198
 
    if (size == -1) {
199
 
        goto done;
200
 
    }
 
194
    if (size == -1)
 
195
        return NULL;
201
196
    new = StaticTuple_New(size);
202
197
    if (new == NULL) {
203
 
        goto done;
 
198
        return NULL;
204
199
    }
205
200
    for (i = 0; i < size; ++i) {
206
201
        // This returns a new reference, which we then 'steal' with 
208
203
        item = PySequence_GetItem(sequence, i);
209
204
        if (item == NULL) {
210
205
            Py_DECREF(new);
211
 
            new = NULL;
212
 
            goto done;
 
206
            return NULL;
213
207
        }
214
208
        StaticTuple_SET_ITEM(new, i, item);
215
209
    }
216
 
done:
217
 
    Py_XDECREF(as_tuple);
218
210
    return (StaticTuple *)new;
219
211
}
220
212
 
228
220
}
229
221
 
230
222
 
231
 
/* Check that all items we point to are 'valid' */
232
 
static int
233
 
StaticTuple_check_items(StaticTuple *self)
234
 
{
235
 
    int i;
236
 
    PyObject *obj;
237
 
 
238
 
    for (i = 0; i < self->size; ++i) {
239
 
        obj = self->items[i];
240
 
        if (obj == NULL) {
241
 
            PyErr_SetString(PyExc_RuntimeError, "StaticTuple(...)"
242
 
                " should not have a NULL entry.");
243
 
            return 0;
244
 
        }
245
 
        if (PyString_CheckExact(obj)
246
 
            || StaticTuple_CheckExact(obj)
247
 
            || obj == Py_None
248
 
            || PyBool_Check(obj)
249
 
            || PyInt_CheckExact(obj)
250
 
            || PyLong_CheckExact(obj)
251
 
            || PyFloat_CheckExact(obj)
252
 
            || PyUnicode_CheckExact(obj)
253
 
            ) continue;
254
 
        PyErr_Format(PyExc_TypeError, "StaticTuple(...)"
255
 
            " requires that all items are one of"
256
 
            " str, StaticTuple, None, bool, int, long, float, or unicode"
257
 
            " not %s.", Py_TYPE(obj)->tp_name);
258
 
        return 0;
259
 
    }
260
 
    return 1;
261
 
}
262
 
 
263
223
static PyObject *
264
224
StaticTuple_new_constructor(PyTypeObject *type, PyObject *args, PyObject *kwds)
265
225
{
277
237
    }
278
238
    len = PyTuple_GET_SIZE(args);
279
239
    if (len < 0 || len > 255) {
280
 
        /* Check the length here so we can raise a TypeError instead of
281
 
         * StaticTuple_New's ValueError.
282
 
         */
283
 
        PyErr_SetString(PyExc_TypeError, "StaticTuple(...)"
 
240
        /* Too big or too small */
 
241
        PyErr_SetString(PyExc_ValueError, "StaticTuple.__init__(...)"
284
242
            " takes from 0 to 255 items");
285
243
        return NULL;
286
244
    }
290
248
    }
291
249
    for (i = 0; i < len; ++i) {
292
250
        obj = PyTuple_GET_ITEM(args, i);
 
251
        if (!PyString_CheckExact(obj)) {
 
252
            if (!StaticTuple_CheckExact(obj)) {
 
253
                PyErr_SetString(PyExc_TypeError, "StaticTuple.__init__(...)"
 
254
                    " requires that all items are strings or StaticTuple.");
 
255
                type->tp_dealloc((PyObject *)self);
 
256
                return NULL;
 
257
            }
 
258
        }
293
259
        Py_INCREF(obj);
294
260
        self->items[i] = obj;
295
261
    }
296
 
    if (!StaticTuple_check_items(self)) {
297
 
        type->tp_dealloc((PyObject *)self);
298
 
        return NULL;
299
 
    }
300
262
    return (PyObject *)self;
301
263
}
302
264
 
314
276
    if (tuple_repr == NULL) {
315
277
        return NULL;
316
278
    }
317
 
    result = PyString_FromFormat("StaticTuple%s",
318
 
                                 PyString_AsString(tuple_repr));
 
279
    result = PyString_FromFormat("%s%s", Py_TYPE(self)->tp_name,
 
280
                                         PyString_AsString(tuple_repr));
319
281
    return result;
320
282
}
321
283
 
495
457
            /* Both are StaticTuple types, so recurse */
496
458
            result = StaticTuple_richcompare(v_obj, w_obj, Py_EQ);
497
459
        } else {
498
 
            /* Fall back to generic richcompare */
499
 
            result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
 
460
            /* Not the same type, obviously they won't compare equal */
 
461
            break;
500
462
        }
501
463
        if (result == NULL) {
502
464
            return NULL; /* There seems to be an error */
503
465
        }
 
466
        if (result == Py_NotImplemented) {
 
467
            Py_DECREF(result);
 
468
            /* One side must have had a string and the other a StaticTuple.
 
469
             * This clearly means that they are not equal.
 
470
             */
 
471
            if (op == Py_EQ) {
 
472
                Py_INCREF(Py_False);
 
473
                return Py_False;
 
474
            }
 
475
            result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
 
476
        }
504
477
        if (result == Py_False) {
505
 
            // This entry is not identical, Shortcut for Py_EQ
 
478
            /* This entry is not identical
 
479
             * Shortcut for Py_EQ
 
480
             */
506
481
            if (op == Py_EQ) {
507
482
                return result;
508
483
            }
556
531
        /* Both are StaticTuple types, so recurse */
557
532
        return StaticTuple_richcompare(v_obj, w_obj, op);
558
533
    } else {
559
 
        return PyObject_RichCompare(v_obj, w_obj, op);
 
534
        Py_INCREF(Py_NotImplemented);
 
535
        return Py_NotImplemented;
560
536
    }
561
537
}
562
538
 
584
560
 
585
561
 
586
562
static PyObject *
587
 
StaticTuple_reduce(StaticTuple *self)
588
 
{
589
 
    PyObject *result = NULL, *as_tuple = NULL;
590
 
 
591
 
    result = PyTuple_New(2);
592
 
    if (!result) {
593
 
        return NULL;
594
 
    }
595
 
    as_tuple = StaticTuple_as_tuple(self);
596
 
    if (as_tuple == NULL) {
597
 
        Py_DECREF(result);
598
 
        return NULL;
599
 
    }
600
 
    Py_INCREF(&StaticTuple_Type);
601
 
    PyTuple_SET_ITEM(result, 0, (PyObject *)&StaticTuple_Type);
602
 
    PyTuple_SET_ITEM(result, 1, as_tuple);
603
 
    return result;
604
 
}
605
 
 
606
 
static char StaticTuple_reduce_doc[] = "__reduce__() => tuple\n";
607
 
 
608
 
 
609
 
static PyObject *
610
 
StaticTuple_add(PyObject *v, PyObject *w)
611
 
{
612
 
    Py_ssize_t i, len_v, len_w;
613
 
    PyObject *item;
614
 
    StaticTuple *result;
615
 
     /* StaticTuples and plain tuples may be added (concatenated) to
616
 
      * StaticTuples.
617
 
      */
618
 
    if (StaticTuple_CheckExact(v)) {
619
 
        len_v = ((StaticTuple*)v)->size;
620
 
    } else if (PyTuple_Check(v)) {
621
 
        len_v = PyTuple_GET_SIZE(v);
622
 
    } else {
623
 
        Py_INCREF(Py_NotImplemented);
624
 
        return Py_NotImplemented;
625
 
    }
626
 
    if (StaticTuple_CheckExact(w)) {
627
 
        len_w = ((StaticTuple*)w)->size;
628
 
    } else if (PyTuple_Check(w)) {
629
 
        len_w = PyTuple_GET_SIZE(w);
630
 
    } else {
631
 
        Py_INCREF(Py_NotImplemented);
632
 
        return Py_NotImplemented;
633
 
    }
634
 
    result = StaticTuple_New(len_v + len_w);
635
 
    if (result == NULL)
636
 
        return NULL;
637
 
    for (i = 0; i < len_v; ++i) {
638
 
        // This returns a new reference, which we then 'steal' with 
639
 
        // StaticTuple_SET_ITEM
640
 
        item = PySequence_GetItem(v, i);
641
 
        if (item == NULL) {
642
 
            Py_DECREF(result);
643
 
            return NULL;
644
 
        }
645
 
        StaticTuple_SET_ITEM(result, i, item);
646
 
    }
647
 
    for (i = 0; i < len_w; ++i) {
648
 
        item = PySequence_GetItem(w, i);
649
 
        if (item == NULL) {
650
 
            Py_DECREF(result);
651
 
            return NULL;
652
 
        }
653
 
        StaticTuple_SET_ITEM(result, i+len_v, item);
654
 
    }
655
 
    if (!StaticTuple_check_items(result)) {
656
 
        Py_DECREF(result);
657
 
        return NULL;
658
 
    }
659
 
    return (PyObject *)result;
660
 
}
661
 
 
662
 
static PyObject *
663
563
StaticTuple_item(StaticTuple *self, Py_ssize_t offset)
664
564
{
665
565
    PyObject *obj;
721
621
     METH_STATIC | METH_VARARGS,
722
622
     "Create a StaticTuple from a given sequence. This functions"
723
623
     " the same as the tuple() constructor."},
724
 
    {"__reduce__", (PyCFunction)StaticTuple_reduce, METH_NOARGS, StaticTuple_reduce_doc},
725
624
    {NULL, NULL} /* sentinel */
726
625
};
727
626
 
728
 
 
729
 
static PyNumberMethods StaticTuple_as_number = {
730
 
    (binaryfunc) StaticTuple_add,   /* nb_add */
731
 
    0,                              /* nb_subtract */
732
 
    0,                              /* nb_multiply */
733
 
    0,                              /* nb_divide */
734
 
    0,                              /* nb_remainder */
735
 
    0,                              /* nb_divmod */
736
 
    0,                              /* nb_power */
737
 
    0,                              /* nb_negative */
738
 
    0,                              /* nb_positive */
739
 
    0,                              /* nb_absolute */
740
 
    0,                              /* nb_nonzero */
741
 
    0,                              /* nb_invert */
742
 
    0,                              /* nb_lshift */
743
 
    0,                              /* nb_rshift */
744
 
    0,                              /* nb_and */
745
 
    0,                              /* nb_xor */
746
 
    0,                              /* nb_or */
747
 
    0,                              /* nb_coerce */
748
 
};
749
 
    
750
 
 
751
627
static PySequenceMethods StaticTuple_as_sequence = {
752
628
    (lenfunc)StaticTuple_length,            /* sq_length */
753
629
    0,                              /* sq_concat */
769
645
PyTypeObject StaticTuple_Type = {
770
646
    PyObject_HEAD_INIT(NULL)
771
647
    0,                                           /* ob_size */
772
 
    "bzrlib._static_tuple_c.StaticTuple",        /* tp_name */
 
648
    "StaticTuple",                               /* tp_name */
773
649
    sizeof(StaticTuple),                         /* tp_basicsize */
774
650
    sizeof(PyObject *),                          /* tp_itemsize */
775
651
    (destructor)StaticTuple_dealloc,             /* tp_dealloc */
778
654
    0,                                           /* tp_setattr */
779
655
    0,                                           /* tp_compare */
780
656
    (reprfunc)StaticTuple_repr,                  /* tp_repr */
781
 
    &StaticTuple_as_number,                      /* tp_as_number */
 
657
    0,                                           /* tp_as_number */
782
658
    &StaticTuple_as_sequence,                    /* tp_as_sequence */
783
659
    0,                                           /* tp_as_mapping */
784
660
    (hashfunc)StaticTuple_hash,                  /* tp_hash */
787
663
    0,                                           /* tp_getattro */
788
664
    0,                                           /* tp_setattro */
789
665
    0,                                           /* tp_as_buffer */
790
 
    /* Py_TPFLAGS_CHECKTYPES tells the number operations that they shouldn't
791
 
     * try to 'coerce' but instead stuff like 'add' will check it arguments.
792
 
     */
793
 
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES,  /* tp_flags*/
 
666
    Py_TPFLAGS_DEFAULT,                          /* tp_flags*/
794
667
    StaticTuple_doc,                             /* tp_doc */
795
668
    /* gc.get_referents checks the IS_GC flag before it calls tp_traverse
796
669
     * And we don't include this object in the garbage collector because we
894
767
     */
895
768
    set_module = PyImport_ImportModule("bzrlib._simple_set_pyx");
896
769
    if (set_module == NULL) {
 
770
        // fprintf(stderr, "Failed to import bzrlib._simple_set_pyx\n");
897
771
        goto end;
898
772
    }
899
773
    /* Add the _simple_set_pyx into sys.modules at the appropriate location. */
900
774
    sys_module = PyImport_ImportModule("sys");
901
775
    if (sys_module == NULL) {
 
776
        // fprintf(stderr, "Failed to import sys\n");
902
777
        goto end;
903
778
    }
904
779
    modules = PyObject_GetAttrString(sys_module, "modules");
905
780
    if (modules == NULL || !PyDict_Check(modules)) {
 
781
        // fprintf(stderr, "Failed to find sys.modules\n");
906
782
        goto end;
907
783
    }
908
784
    PyDict_SetItemString(modules, "_simple_set_pyx", set_module);
941
817
    setup_empty_tuple(m);
942
818
    setup_c_api(m);
943
819
}
944
 
 
945
 
// vim: tabstop=4 sw=4 expandtab