mirror of
				https://github.com/python/cpython.git
				synced 2025-10-26 03:04:41 +00:00 
			
		
		
		
	 e281f7d80c
			
		
	
	
		e281f7d80c
		
			
		
	
	
	
	
		
			
			The accu.h header is no longer part of the Python C API: it has been moved to the "internal" headers which are restricted to Python itself. Replace #include "accu.h" with #include "pycore_accu.h".
		
			
				
	
	
		
			115 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Accumulator struct implementation */
 | |
| 
 | |
| #include "Python.h"
 | |
| #include "pycore_accu.h"
 | |
| 
 | |
| static PyObject *
 | |
| join_list_unicode(PyObject *lst)
 | |
| {
 | |
|     /* return ''.join(lst) */
 | |
|     PyObject *sep, *ret;
 | |
|     sep = PyUnicode_FromStringAndSize("", 0);
 | |
|     ret = PyUnicode_Join(sep, lst);
 | |
|     Py_DECREF(sep);
 | |
|     return ret;
 | |
| }
 | |
| 
 | |
| int
 | |
| _PyAccu_Init(_PyAccu *acc)
 | |
| {
 | |
|     /* Lazily allocated */
 | |
|     acc->large = NULL;
 | |
|     acc->small = PyList_New(0);
 | |
|     if (acc->small == NULL)
 | |
|         return -1;
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static int
 | |
| flush_accumulator(_PyAccu *acc)
 | |
| {
 | |
|     Py_ssize_t nsmall = PyList_GET_SIZE(acc->small);
 | |
|     if (nsmall) {
 | |
|         int ret;
 | |
|         PyObject *joined;
 | |
|         if (acc->large == NULL) {
 | |
|             acc->large = PyList_New(0);
 | |
|             if (acc->large == NULL)
 | |
|                 return -1;
 | |
|         }
 | |
|         joined = join_list_unicode(acc->small);
 | |
|         if (joined == NULL)
 | |
|             return -1;
 | |
|         if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) {
 | |
|             Py_DECREF(joined);
 | |
|             return -1;
 | |
|         }
 | |
|         ret = PyList_Append(acc->large, joined);
 | |
|         Py_DECREF(joined);
 | |
|         return ret;
 | |
|     }
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| int
 | |
| _PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode)
 | |
| {
 | |
|     Py_ssize_t nsmall;
 | |
|     assert(PyUnicode_Check(unicode));
 | |
| 
 | |
|     if (PyList_Append(acc->small, unicode))
 | |
|         return -1;
 | |
|     nsmall = PyList_GET_SIZE(acc->small);
 | |
|     /* Each item in a list of unicode objects has an overhead (in 64-bit
 | |
|      * builds) of:
 | |
|      *   - 8 bytes for the list slot
 | |
|      *   - 56 bytes for the header of the unicode object
 | |
|      * that is, 64 bytes.  100000 such objects waste more than 6 MiB
 | |
|      * compared to a single concatenated string.
 | |
|      */
 | |
|     if (nsmall < 100000)
 | |
|         return 0;
 | |
|     return flush_accumulator(acc);
 | |
| }
 | |
| 
 | |
| PyObject *
 | |
| _PyAccu_FinishAsList(_PyAccu *acc)
 | |
| {
 | |
|     int ret;
 | |
|     PyObject *res;
 | |
| 
 | |
|     ret = flush_accumulator(acc);
 | |
|     Py_CLEAR(acc->small);
 | |
|     if (ret) {
 | |
|         Py_CLEAR(acc->large);
 | |
|         return NULL;
 | |
|     }
 | |
|     res = acc->large;
 | |
|     acc->large = NULL;
 | |
|     return res;
 | |
| }
 | |
| 
 | |
| PyObject *
 | |
| _PyAccu_Finish(_PyAccu *acc)
 | |
| {
 | |
|     PyObject *list, *res;
 | |
|     if (acc->large == NULL) {
 | |
|         list = acc->small;
 | |
|         acc->small = NULL;
 | |
|     }
 | |
|     else {
 | |
|         list = _PyAccu_FinishAsList(acc);
 | |
|         if (!list)
 | |
|             return NULL;
 | |
|     }
 | |
|     res = join_list_unicode(list);
 | |
|     Py_DECREF(list);
 | |
|     return res;
 | |
| }
 | |
| 
 | |
| void
 | |
| _PyAccu_Destroy(_PyAccu *acc)
 | |
| {
 | |
|     Py_CLEAR(acc->small);
 | |
|     Py_CLEAR(acc->large);
 | |
| }
 |