@@ -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+
222228SharedIspellDict * shdict ;
223229SharedStopList * shstop ;
224230
@@ -249,23 +255,43 @@ void init_shared_dict(DictInfo * info, char * dictFile, char * affFile, char * s
249255NISortAffixes (dict );
250256
251257NIFinishBuild (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 */
253267shdict = 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+
255272shdict -> next = segment_info -> dict ;
256273segment_info -> dict = shdict ;
257274
258- elog (LOG ,"shared ispell init done, remaining %ld B" ,segment_info -> available );
259-
260275}
261276
262277/* stop words */
263278shstop = get_shared_stop_list (stopFile );
264279if ((shstop == NULL )&& (stopFile != NULL )) {
265280
266281readstoplist (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 */
267290shstop = 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+
269295shstop -> next = segment_info -> stop ;
270296segment_info -> stop = shstop ;
271297
@@ -517,6 +543,25 @@ SPNode * copySPNode(SPNode * node) {
517543return 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 ) {
522567char * tmp = shalloc (strlen (str )+ 1 );
@@ -538,6 +583,18 @@ RegisNode * copyRegisNode(RegisNode * node) {
538583return 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
572648copy = (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
575651for (i = 0 ;i < node -> length ;i ++ ) {
576652
@@ -579,7 +655,6 @@ AffixNode * copyAffixNode(AffixNode * node) {
579655copy -> data [i ].val = node -> data [i ].val ;
580656copy -> data [i ].naff = node -> data [i ].naff ;
581657copy -> 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
584659for (j = 0 ;j < node -> data [i ].naff ;j ++ ) {
585660copy -> data [i ].aff [j ]= copyAffix (node -> data [i ].aff [j ]);
@@ -589,6 +664,31 @@ AffixNode * copyAffixNode(AffixNode * node) {
589664return 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) {
608708return 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
652768copy -> nAffixData = dict -> nAffixData ;
653769copy -> AffixData = (char * * )shalloc (sizeof (char * )* dict -> nAffixData );
654770for (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
667782return 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+ }