Exemplo n.º 1
0
Datum
dispell_init(PG_FUNCTION_ARGS)
{
	List	   *dictoptions = (List *) PG_GETARG_POINTER(0);
	DictISpell *d;
	bool		affloaded = false,
				dictloaded = false,
				stoploaded = false;
	ListCell   *l;

	d = (DictISpell *) palloc0(sizeof(DictISpell));

	NIStartBuild(&(d->obj));

	foreach(l, dictoptions)
	{
		DefElem    *defel = (DefElem *) lfirst(l);

		if (pg_strcasecmp(defel->defname, "DictFile") == 0)
		{
			if (dictloaded)
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						 errmsg("multiple DictFile parameters")));
			NIImportDictionary(&(d->obj),
							 get_tsearch_config_filename(defGetString(defel),
														 "dict"));
			dictloaded = true;
		}
		else if (pg_strcasecmp(defel->defname, "AffFile") == 0)
		{
			if (affloaded)
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						 errmsg("multiple AffFile parameters")));
			NIImportAffixes(&(d->obj),
							get_tsearch_config_filename(defGetString(defel),
														"affix"));
			affloaded = true;
		}
		else if (pg_strcasecmp(defel->defname, "StopWords") == 0)
		{
			if (stoploaded)
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						 errmsg("multiple StopWords parameters")));
			readstoplist(defGetString(defel), &(d->stoplist), lowerstr);
			stoploaded = true;
		}
		else
		{
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("unrecognized Ispell parameter: \"%s\"",
							defel->defname)));
		}
	}
Exemplo n.º 2
0
/*
 * Initializes the dictionary for use in backends - checks whether such dictionary 
 * and list of stopwords is already used, and if not then parses it and loads it into
 * the shared segment.
 * 
 * This is called through dispell_init() which is responsible for proper locking
 * of the shared memory (using SegmentInfo->lock).
 */
static
void init_shared_dict(DictInfo * info, char * dictFile, char * affFile, char * stopFile) {

    int size;

    SharedIspellDict * shdict = NULL;
    SharedStopList * shstop   = NULL;

    IspellDict * dict;
    StopList    stoplist;
    
    /* DICTIONARY + AFFIXES */
    
    /* TODO This should probably check that the filenames are not NULL, and maybe that
     * it exists. Or maybe that's handled by the NIImport* functions. */

    /* lookup if the dictionary (words and affixes) is already loaded in the shared segment */
    shdict = get_shared_dict(dictFile, affFile);

    /* load the dictionary / affixes if not yet defined */
    if (shdict == NULL) {

        dict = (IspellDict *)palloc0(sizeof(IspellDict));

        NIStartBuild(dict);

        NIImportDictionary(dict,
                           get_tsearch_config_filename(dictFile, "dict"));

        NIImportAffixes(dict,
                        get_tsearch_config_filename(affFile, "affix"));

        NISortDictionary(dict);
        NISortAffixes(dict);

        NIFinishBuild(dict);

        /* check available space in shared segment */
        size = sizeIspellDict(dict, dictFile, affFile);
        if (size > segment_info->available)
            elog(ERROR, "shared dictionary %s.dict / %s.affix needs %d B, only %ld B available",
                 dictFile, affFile, size, segment_info->available);

        /* fine, there's enough space - copy the dictionary */
        shdict = copyIspellDict(dict, dictFile, affFile, size, dict->nspell);

        elog(INFO, "shared dictionary %s.dict / %s.affix loaded, used %d B, %ld B remaining",
             dictFile, affFile, size, segment_info->available);

        /* add the new dictionary to the linked list (of SharedIspellDict structures) */
        shdict->next = segment_info->dict;
        segment_info->dict = shdict;

    }
    
    /* STOP WORDS */

    /* lookup if the stop words are already loaded in the shared segment, but only if there
     * actually is a list */
    if (stopFile != NULL) {

        shstop = get_shared_stop_list(stopFile);

        /* load the stopwords if not yet defined */
        if (shstop == NULL) {

            readstoplist(stopFile, &stoplist, lowerstr);

            size = sizeStopList(&stoplist, stopFile);
            if (size > segment_info->available) {
                elog(ERROR, "shared stoplist %s.stop needs %d B, only %ld B available",
                     stopFile, size, segment_info->available);
            }

            /* fine, there's enough space - copy the stoplist */
            shstop = copyStopList(&stoplist, stopFile, size);

            elog(INFO, "shared stoplist %s.stop loaded, used %d B, %ld B remaining",
                 affFile, size, segment_info->available);

            /* add the new stopword list to the linked list (of SharedStopList structures) */
            shstop->next = segment_info->stop;
            segment_info->stop = shstop;

        }
    }

    /* Now, fill the DictInfo structure for the backend (references to dictionary,
     * stopwords and the filenames). */

    info->dict = shdict;
    info->stop = shstop;
    info->lookup = GetCurrentTimestamp();

    memcpy(info->dictFile, dictFile, strlen(dictFile) + 1);
    memcpy(info->affixFile, dictFile, strlen(affFile)+ 1);
    memcpy(info->stopFile, dictFile, strlen(stopFile) + 1);

}