@@ -84,9 +84,13 @@ typedef struct DictInfo {
8484static SegmentInfo * segment_info = NULL ;
8585
8686static char * shalloc (int bytes );
87+
8788static SharedIspellDict * copyIspellDict (IspellDict * dict , char * dictFile , char * affixFile );
8889static SharedStopList * copyStopList (StopList * list , char * stopFile );
8990
91+ static int sizeIspellDict (IspellDict * dict , char * dictFile , char * affixFile );
92+ static int sizeStopList (StopList * list , char * stopFile );
93+
9094/*
9195 * Module load callback
9296 */
@@ -219,6 +223,8 @@ SharedStopList * get_shared_stop_list(char * stop) {
219223static
220224void init_shared_dict (DictInfo * info , char * dictFile , char * affFile , char * stopFile ) {
221225
226+ int size ;
227+
222228 SharedIspellDict * shdict ;
223229 SharedStopList * shstop ;
224230
@@ -249,23 +255,43 @@ void init_shared_dict(DictInfo * info, char * dictFile, char * affFile, char * s
249255 NISortAffixes (dict );
250256
251257 NIFinishBuild (dict );
252-
258+
259+ /* check available space in shared segment */
260+ size = sizeIspellDict (dict , dictFile , affFile );
261+ if (size > segment_info -> available ) {
262+ elog (ERROR , "shared dictionary %s.dict / %s.affix needs %d B, only %ld B available" ,
263+ dictFile , affFile , size , segment_info -> available );
264+ }
265+
266+ /* fine, there's enough space - copy the dictionary */
253267 shdict = copyIspellDict (dict , dictFile , affFile );
254268
269+ elog (INFO , "shared dictionary %s.dict / %s.affix loaded, used %d B, %ld B remaining" ,
270+ dictFile , affFile , size , segment_info -> available );
271+
255272 shdict -> next = segment_info -> dict ;
256273 segment_info -> dict = shdict ;
257274
258- elog (LOG , "shared ispell init done, remaining %ld B" , segment_info -> available );
259-
260275 }
261276
262277 /* stop words */
263278 shstop = get_shared_stop_list (stopFile );
264279 if ((shstop == NULL ) && (stopFile != NULL )) {
265280
266281 readstoplist (stopFile , & stoplist , lowerstr );
282+
283+ size = sizeStopList (& stoplist , stopFile );
284+ if (size > segment_info -> available ) {
285+ elog (ERROR , "shared stoplist %s.stop needs %d B, only %ld B available" ,
286+ stopFile , size , segment_info -> available );
287+ }
288+
289+ /* fine, there's enough space - copy the stoplist */
267290 shstop = copyStopList (& stoplist , stopFile );
268291
292+ elog (INFO , "shared stoplist %s.stop loaded, used %d B, %ld B remaining" ,
293+ affFile , size , segment_info -> available );
294+
269295 shstop -> next = segment_info -> stop ;
270296 segment_info -> stop = shstop ;
271297
@@ -517,6 +543,25 @@ SPNode * copySPNode(SPNode * node) {
517543 return copy ;
518544}
519545
546+ static
547+ int sizeSPNode (SPNode * node ) {
548+
549+ int i ;
550+ int size = 0 ;
551+
552+ if (node == NULL ) {
553+ return 0 ;
554+ }
555+
556+ size = MAXALIGN (offsetof(SPNode ,data ) + sizeof (SPNodeData ) * node -> length );
557+
558+ for (i = 0 ; i < node -> length ; i ++ ) {
559+ size += sizeSPNode (node -> data [i ].node );
560+ }
561+
562+ return size ;
563+ }
564+
520565static
521566char * shstrcpy (char * str ) {
522567 char * tmp = shalloc (strlen (str )+ 1 );
@@ -538,6 +583,18 @@ RegisNode * copyRegisNode(RegisNode * node) {
538583 return copy ;
539584}
540585
586+ static
587+ int sizeRegisNode (RegisNode * node ) {
588+
589+ int size = MAXALIGN (offsetof(RegisNode , data ) + node -> len );
590+
591+ if (node -> next != NULL ) {
592+ size += sizeRegisNode (node -> next );
593+ }
594+
595+ return size ;
596+ }
597+
541598static
542599AFFIX * copyAffix (AFFIX * affix ) {
543600
@@ -559,6 +616,25 @@ AFFIX * copyAffix(AFFIX * affix) {
559616
560617}
561618
619+ static
620+ int sizeAffix (AFFIX * affix ) {
621+
622+ int size = MAXALIGN (sizeof (AFFIX ));
623+
624+ size += MAXALIGN (strlen (affix -> find )+ 1 );
625+ size += MAXALIGN (strlen (affix -> repl )+ 1 );
626+
627+ if (affix -> isregis ) {
628+ size += sizeRegisNode (affix -> reg .regis .node );
629+ } else if (! affix -> issimple ) {
630+ // FIXME handle the regex_t properly (copy the strings etc)
631+ elog (WARNING , "skipping regex_t" );
632+ }
633+
634+ return size ;
635+
636+ }
637+
562638static
563639AffixNode * copyAffixNode (AffixNode * node ) {
564640
@@ -570,7 +646,7 @@ AffixNode * copyAffixNode(AffixNode * node) {
570646 }
571647
572648 copy = (AffixNode * )shalloc (offsetof(AffixNode ,data ) + sizeof (AffixNodeData ) * node -> length );
573- memcpy (copy , node , offsetof(SPNode ,data ) + sizeof (SPNodeData ) * node -> length );
649+ memcpy (copy , node , offsetof(AffixNode ,data ) + sizeof (AffixNodeData ) * node -> length );
574650
575651 for (i = 0 ; i < node -> length ; i ++ ) {
576652
@@ -579,7 +655,6 @@ AffixNode * copyAffixNode(AffixNode * node) {
579655 copy -> data [i ].val = node -> data [i ].val ;
580656 copy -> data [i ].naff = node -> data [i ].naff ;
581657 copy -> data [i ].aff = (AFFIX * * )shalloc (sizeof (AFFIX * ) * node -> data [i ].naff );
582- memset (copy -> data [i ].aff , 0 , sizeof (AFFIX * ) * node -> data [i ].naff );
583658
584659 for (j = 0 ; j < node -> data [i ].naff ; j ++ ) {
585660 copy -> data [i ].aff [j ] = copyAffix (node -> data [i ].aff [j ]);
@@ -589,6 +664,31 @@ AffixNode * copyAffixNode(AffixNode * node) {
589664 return copy ;
590665}
591666
667+ static
668+ int sizeAffixNode (AffixNode * node ) {
669+
670+ int i , j ;
671+ int size = 0 ;
672+
673+ if (node == NULL ) {
674+ return 0 ;
675+ }
676+
677+ size = MAXALIGN (offsetof(AffixNode ,data ) + sizeof (AffixNodeData ) * node -> length );
678+
679+ for (i = 0 ; i < node -> length ; i ++ ) {
680+
681+ size += sizeAffixNode (node -> data [i ].node );
682+ size += MAXALIGN (sizeof (AFFIX * ) * node -> data [i ].naff );
683+
684+ for (j = 0 ; j < node -> data [i ].naff ; j ++ ) {
685+ size += sizeAffix (node -> data [i ].aff [j ]);
686+ }
687+ }
688+
689+ return size ;
690+ }
691+
592692static
593693SharedStopList * copyStopList (StopList * list , char * stopFile ) {
594694
@@ -608,6 +708,22 @@ SharedStopList * copyStopList(StopList * list, char * stopFile) {
608708 return copy ;
609709}
610710
711+ static
712+ int sizeStopList (StopList * list , char * stopFile ) {
713+
714+ int i ;
715+ int size = MAXALIGN (sizeof (SharedStopList ));
716+
717+ size += MAXALIGN (sizeof (char * ) * list -> len );
718+ size += MAXALIGN (strlen (stopFile ) + 1 );
719+
720+ for (i = 0 ; i < list -> len ; i ++ ) {
721+ size += MAXALIGN (strlen (list -> stop [i ]) + 1 );
722+ }
723+
724+ return size ;
725+ }
726+
611727static
612728int countCMPDAffixes (CMPDAffix * affixes ) {
613729
@@ -652,8 +768,7 @@ SharedIspellDict * copyIspellDict(IspellDict * dict, char * dictFile, char * aff
652768 copy -> nAffixData = dict -> nAffixData ;
653769 copy -> AffixData = (char * * )shalloc (sizeof (char * ) * dict -> nAffixData );
654770 for (i = 0 ; i < copy -> nAffixData ; i ++ ) {
655- copy -> AffixData [i ] = (char * )shalloc (sizeof (char ) * strlen (dict -> AffixData [i ]) + 1 );
656- strcpy (copy -> AffixData [i ], dict -> AffixData [i ]);
771+ copy -> AffixData [i ] = shstrcpy (dict -> AffixData [i ]);
657772 }
658773
659774 /* copy compound affixes (there's at least one) */
@@ -667,3 +782,32 @@ SharedIspellDict * copyIspellDict(IspellDict * dict, char * dictFile, char * aff
667782 return copy ;
668783
669784}
785+
786+ static
787+ int sizeIspellDict (IspellDict * dict , char * dictFile , char * affixFile ) {
788+
789+ int i ;
790+ int size = MAXALIGN (sizeof (SharedIspellDict ));
791+
792+ size += MAXALIGN (strlen (dictFile )+ 1 );
793+ size += MAXALIGN (strlen (affixFile )+ 1 );
794+
795+ size += MAXALIGN (sizeof (AFFIX ) * dict -> naffixes );
796+
797+ size += MAXALIGN (sizeAffixNode (dict -> Suffix ));
798+ size += MAXALIGN (sizeAffixNode (dict -> Prefix ));
799+
800+ size += sizeSPNode (dict -> Dictionary );
801+
802+ /* copy affix data */
803+ size += MAXALIGN (sizeof (char * ) * dict -> nAffixData );
804+ for (i = 0 ; i < dict -> nAffixData ; i ++ ) {
805+ size += MAXALIGN (sizeof (char ) * strlen (dict -> AffixData [i ]) + 1 );
806+ }
807+
808+ /* copy compound affixes (there's at least one) */
809+ size += MAXALIGN (sizeof (CMPDAffix ) * countCMPDAffixes (dict -> CompoundAffix ));
810+
811+ return size ;
812+
813+ }
0 commit comments