Mercurial > vim
comparison src/if_py_both.h @ 21319:fb3dcd8ed14d v8.2.1210
patch 8.2.1210: using ht_used when looping through a hashtab is less reliable
Commit: https://github.com/vim/vim/commit/1f22cc5cdb2da867d6bbf54dd371f279c38a2f56
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jul 14 21:08:49 2020 +0200
patch 8.2.1210: using ht_used when looping through a hashtab is less reliable
Problem: Using ht_used when looping through a hashtab is less reliable.
Solution: Use ht_changed in a few more places.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 14 Jul 2020 21:15:04 +0200 |
parents | 8531ddd7dd63 |
children | d1a7088c6efe |
comparison
equal
deleted
inserted
replaced
21318:b1121f5c029a | 21319:fb3dcd8ed14d |
---|---|
1790 return ret; | 1790 return ret; |
1791 } | 1791 } |
1792 | 1792 |
1793 typedef struct | 1793 typedef struct |
1794 { | 1794 { |
1795 hashitem_T *ht_array; | 1795 int dii_changed; |
1796 long_u ht_used; | 1796 hashtab_T *dii_ht; |
1797 hashtab_T *ht; | 1797 hashitem_T *dii_hi; |
1798 hashitem_T *hi; | 1798 long_u dii_todo; |
1799 long_u todo; | |
1800 } dictiterinfo_T; | 1799 } dictiterinfo_T; |
1801 | 1800 |
1802 static PyObject * | 1801 static PyObject * |
1803 DictionaryIterNext(dictiterinfo_T **dii) | 1802 DictionaryIterNext(dictiterinfo_T **dii) |
1804 { | 1803 { |
1805 PyObject *ret; | 1804 PyObject *ret; |
1806 | 1805 |
1807 if (!(*dii)->todo) | 1806 if (!(*dii)->dii_todo) |
1808 return NULL; | 1807 return NULL; |
1809 | 1808 |
1810 if ((*dii)->ht->ht_array != (*dii)->ht_array || | 1809 if ((*dii)->dii_ht->ht_changed != (*dii)->dii_changed) |
1811 (*dii)->ht->ht_used != (*dii)->ht_used) | |
1812 { | 1810 { |
1813 PyErr_SET_STRING(PyExc_RuntimeError, | 1811 PyErr_SET_STRING(PyExc_RuntimeError, |
1814 N_("hashtab changed during iteration")); | 1812 N_("hashtab changed during iteration")); |
1815 return NULL; | 1813 return NULL; |
1816 } | 1814 } |
1817 | 1815 |
1818 while (((*dii)->todo) && HASHITEM_EMPTY((*dii)->hi)) | 1816 while (((*dii)->dii_todo) && HASHITEM_EMPTY((*dii)->dii_hi)) |
1819 ++((*dii)->hi); | 1817 ++((*dii)->dii_hi); |
1820 | 1818 |
1821 --((*dii)->todo); | 1819 --((*dii)->dii_todo); |
1822 | 1820 |
1823 if (!(ret = PyBytes_FromString((char *)(*dii)->hi->hi_key))) | 1821 if (!(ret = PyBytes_FromString((char *)(*dii)->dii_hi->hi_key))) |
1824 return NULL; | 1822 return NULL; |
1825 | 1823 |
1826 return ret; | 1824 return ret; |
1827 } | 1825 } |
1828 | 1826 |
1837 PyErr_NoMemory(); | 1835 PyErr_NoMemory(); |
1838 return NULL; | 1836 return NULL; |
1839 } | 1837 } |
1840 | 1838 |
1841 ht = &self->dict->dv_hashtab; | 1839 ht = &self->dict->dv_hashtab; |
1842 dii->ht_array = ht->ht_array; | 1840 dii->dii_changed = ht->ht_changed; |
1843 dii->ht_used = ht->ht_used; | 1841 dii->dii_ht = ht; |
1844 dii->ht = ht; | 1842 dii->dii_hi = ht->ht_array; |
1845 dii->hi = dii->ht_array; | 1843 dii->dii_todo = ht->ht_used; |
1846 dii->todo = dii->ht_used; | |
1847 | 1844 |
1848 return IterNew(dii, | 1845 return IterNew(dii, |
1849 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext, | 1846 (destructorfun) PyMem_Free, (nextfun) DictionaryIterNext, |
1850 NULL, NULL); | 1847 NULL, NULL); |
1851 } | 1848 } |