@@ -59,6 +59,63 @@ NIFinishBuild(IspellDict *Conf)
59
59
/* Just for cleanliness, zero the now-dangling pointers */
60
60
Conf -> buildCxt = NULL ;
61
61
Conf -> Spell = NULL ;
62
+ Conf -> firstfree = NULL ;
63
+ }
64
+
65
+
66
+ /*
67
+ * "Compact" palloc: allocate without extra palloc overhead.
68
+ *
69
+ * Since we have no need to free the ispell data items individually, there's
70
+ * not much value in the per-chunk overhead normally consumed by palloc.
71
+ * Getting rid of it is helpful since ispell can allocate a lot of small nodes.
72
+ *
73
+ * We currently pre-zero all data allocated this way, even though some of it
74
+ * doesn't need that. The cpalloc and cpalloc0 macros are just documentation
75
+ * to indicate which allocations actually require zeroing.
76
+ */
77
+ #define COMPACT_ALLOC_CHUNK 8192/* must be > aset.c's allocChunkLimit */
78
+ #define COMPACT_MAX_REQ 1024/* must be < COMPACT_ALLOC_CHUNK */
79
+
80
+ static void *
81
+ compact_palloc0 (IspellDict * Conf ,size_t size )
82
+ {
83
+ void * result ;
84
+
85
+ /* Should only be called during init */
86
+ Assert (Conf -> buildCxt != NULL );
87
+
88
+ /* No point in this for large chunks */
89
+ if (size > COMPACT_MAX_REQ )
90
+ return palloc0 (size );
91
+
92
+ /* Keep everything maxaligned */
93
+ size = MAXALIGN (size );
94
+
95
+ /* Need more space? */
96
+ if (size > Conf -> avail )
97
+ {
98
+ Conf -> firstfree = palloc0 (COMPACT_ALLOC_CHUNK );
99
+ Conf -> avail = COMPACT_ALLOC_CHUNK ;
100
+ }
101
+
102
+ result = (void * )Conf -> firstfree ;
103
+ Conf -> firstfree += size ;
104
+ Conf -> avail -= size ;
105
+
106
+ return result ;
107
+ }
108
+
109
+ #define cpalloc (size ) compact_palloc0(Conf, size)
110
+ #define cpalloc0 (size ) compact_palloc0(Conf, size)
111
+
112
+ static char *
113
+ cpstrdup (IspellDict * Conf ,const char * str )
114
+ {
115
+ char * res = cpalloc (strlen (str )+ 1 );
116
+
117
+ strcpy (res ,str );
118
+ return res ;
62
119
}
63
120
64
121
@@ -186,7 +243,7 @@ NIAddSpell(IspellDict *Conf, const char *word, const char *flag)
186
243
{
187
244
if (Conf -> mspell )
188
245
{
189
- Conf -> mspell += 1024 * 20 ;
246
+ Conf -> mspell *= 2 ;
190
247
Conf -> Spell = (SPELL * * )repalloc (Conf -> Spell ,Conf -> mspell * sizeof (SPELL * ));
191
248
}
192
249
else
@@ -324,7 +381,7 @@ NIAddAffix(IspellDict *Conf, int flag, char flagflags, const char *mask, const c
324
381
{
325
382
if (Conf -> maffixes )
326
383
{
327
- Conf -> maffixes += 16 ;
384
+ Conf -> maffixes *= 2 ;
328
385
Conf -> Affix = (AFFIX * )repalloc ((void * )Conf -> Affix ,Conf -> maffixes * sizeof (AFFIX ));
329
386
}
330
387
else
@@ -389,9 +446,9 @@ NIAddAffix(IspellDict *Conf, int flag, char flagflags, const char *mask, const c
389
446
Affix -> flag = flag ;
390
447
Affix -> type = type ;
391
448
392
- Affix -> find = (find && * find ) ?pstrdup ( find ) :VoidString ;
449
+ Affix -> find = (find && * find ) ?cpstrdup ( Conf , find ) :VoidString ;
393
450
if ((Affix -> replen = strlen (repl ))> 0 )
394
- Affix -> repl = pstrdup ( repl );
451
+ Affix -> repl = cpstrdup ( Conf , repl );
395
452
else
396
453
Affix -> repl = VoidString ;
397
454
Conf -> naffixes ++ ;
@@ -843,8 +900,9 @@ MergeAffix(IspellDict *Conf, int a1, int a2)
843
900
}
844
901
845
902
ptr = Conf -> AffixData + Conf -> nAffixData ;
846
- * ptr = palloc (strlen (Conf -> AffixData [a1 ])+ strlen (Conf -> AffixData [a2 ])+
847
- 1 /* space */ + 1 /* \0 */ );
903
+ * ptr = cpalloc (strlen (Conf -> AffixData [a1 ])+
904
+ strlen (Conf -> AffixData [a2 ])+
905
+ 1 /* space */ + 1 /* \0 */ );
848
906
sprintf (* ptr ,"%s %s" ,Conf -> AffixData [a1 ],Conf -> AffixData [a2 ]);
849
907
ptr ++ ;
850
908
* ptr = NULL ;
@@ -888,7 +946,7 @@ mkSPNode(IspellDict *Conf, int low, int high, int level)
888
946
if (!nchar )
889
947
return NULL ;
890
948
891
- rs = (SPNode * )palloc0 (SPNHDRSZ + nchar * sizeof (SPNodeData ));
949
+ rs = (SPNode * )cpalloc0 (SPNHDRSZ + nchar * sizeof (SPNodeData ));
892
950
rs -> length = nchar ;
893
951
data = rs -> data ;
894
952
@@ -982,7 +1040,7 @@ NISortDictionary(IspellDict *Conf)
982
1040
{
983
1041
curaffix ++ ;
984
1042
Assert (curaffix < naffix );
985
- Conf -> AffixData [curaffix ]= pstrdup ( Conf -> Spell [i ]-> p .flag );
1043
+ Conf -> AffixData [curaffix ]= cpstrdup ( Conf , Conf -> Spell [i ]-> p .flag );
986
1044
}
987
1045
988
1046
Conf -> Spell [i ]-> p .d .affix = curaffix ;
@@ -1020,7 +1078,7 @@ mkANode(IspellDict *Conf, int low, int high, int level, int type)
1020
1078
aff = (AFFIX * * )tmpalloc (sizeof (AFFIX * )* (high - low + 1 ));
1021
1079
naff = 0 ;
1022
1080
1023
- rs = (AffixNode * )palloc0 (ANHRDSZ + nchar * sizeof (AffixNodeData ));
1081
+ rs = (AffixNode * )cpalloc0 (ANHRDSZ + nchar * sizeof (AffixNodeData ));
1024
1082
rs -> length = nchar ;
1025
1083
data = rs -> data ;
1026
1084
@@ -1036,7 +1094,7 @@ mkANode(IspellDict *Conf, int low, int high, int level, int type)
1036
1094
if (naff )
1037
1095
{
1038
1096
data -> naff = naff ;
1039
- data -> aff = (AFFIX * * )palloc (sizeof (AFFIX * )* naff );
1097
+ data -> aff = (AFFIX * * )cpalloc (sizeof (AFFIX * )* naff );
1040
1098
memcpy (data -> aff ,aff ,sizeof (AFFIX * )* naff );
1041
1099
naff = 0 ;
1042
1100
}
@@ -1056,7 +1114,7 @@ mkANode(IspellDict *Conf, int low, int high, int level, int type)
1056
1114
if (naff )
1057
1115
{
1058
1116
data -> naff = naff ;
1059
- data -> aff = (AFFIX * * )palloc (sizeof (AFFIX * )* naff );
1117
+ data -> aff = (AFFIX * * )cpalloc (sizeof (AFFIX * )* naff );
1060
1118
memcpy (data -> aff ,aff ,sizeof (AFFIX * )* naff );
1061
1119
naff = 0 ;
1062
1120
}
@@ -1097,7 +1155,7 @@ mkVoidAffix(IspellDict *Conf, bool issuffix, int startsuffix)
1097
1155
if (cnt == 0 )
1098
1156
return ;
1099
1157
1100
- Affix -> data -> aff = (AFFIX * * )palloc (sizeof (AFFIX * )* cnt );
1158
+ Affix -> data -> aff = (AFFIX * * )cpalloc (sizeof (AFFIX * )* cnt );
1101
1159
Affix -> data -> naff = (uint32 )cnt ;
1102
1160
1103
1161
cnt = 0 ;