## F.50. shared_ispell

The `shared_ispell` module provides a shared ispell dictionary, i.e. a dictionary that's stored in shared segment. The traditional ispell implementation means that each session initializes and stores the dictionary on it's own, which means a lot of CPU/RAM is wasted.

This extension allocates an area in shared segment (you have to choose the size in advance) and then loads the dictionary into it when it's used for the first time.

### F.50.1. Functions

The functions provided by the `shared_ispell` module are shown in Table F.32.

Table F.32. `shared_ispell` Functions

Function | Returns | Description
--- | --- | ---
`shared_ispell_reset()` | `void` | Resets the dictionaries (e.g. so that you can reload the updated files from disk). The sessions that already use the dictionaries will be forced to reinitialize them.
`shared_ispell_mem_used()` | `int` | Returns a value of used memory of the shared segment by loaded shared dictionaries in bytes.
`shared_ispell_mem_available()` | `int` | Returns a value of available memory of the shared segment.
`shared_ispell_dicts()` | `setof(dict_name varchar, affix_name varchar, words int, affixes int, bytes int)` | Returns a list of dictionaries loaded in the shared segment.
`shared_ispell_stoplists()` | `setof(stop_name varchar, words int, bytes int)` | Returns a list of stopwords loaded in the shared segment.

### F.50.2. GUC Parameters

`shared_ispell.max_size` (`int`)

  Defines the maximum size of the shared segment. This is a hard limit, the shared segment is not extensible and you need to set it so that all the dictionaries fit into it and not much memory is wasted.

### F.50.3. Using the dictionary

The module needs to allocate space in the shared memory segment. So add this to the config file (or update the current values):

    # libraries to load
    shared_preload_libraries = 'shared_ispell'

    # config of the shared memory
    shared_ispell.max_size = 32MB

To find out how much memory you actually need, use a large value (e.g. 200MB) and load all the dictionaries you want to use. Then use the `shared_ispell_mem_used()` function to find out how much memory was actually used (and set the `shared_ispell.max_size` GUC variable accordingly).

Don't set it exactly to that value, leave there some free space, so that you can reload the dictionaries without changing the GUC max_size limit (which requires a restart of the DB). Something like 512kB should be just fine.

The extension defines a `shared_ispell` template that you may use to define custom dictionaries. E.g. you may do this:

    CREATE TEXT SEARCH DICTIONARY english_shared (
        TEMPLATE = shared_ispell,
        DictFile = en_us,
        AffFile = en_us,
        StopWords = english
    );

    CREATE TEXT SEARCH CONFIGURATION public.english_shared
        ( COPY = pg_catalog.simple );

    ALTER TEXT SEARCH CONFIGURATION english_shared
        ALTER MAPPING FOR asciiword, asciihword, hword_asciipart,
                        word, hword, hword_part
        WITH english_shared, english_stem;

We can test created configuration:

    SELECT * FROM ts_debug('english_shared', 'abilities');
       alias   |   description   |   token   |         dictionaries          |   dictionary   |  lexemes
    -----------+-----------------+-----------+-------------------------------+----------------+-----------
     asciiword | Word, all ASCII | abilities | {english_shared,english_stem} | english_shared | {ability}
    (1 row)

Or you can update your own text search configuration. For example, you have the `public.english` dictionary. You can update it to use the `shared_ispell` template:

    ALTER TEXT SEARCH CONFIGURATION public.english
        ALTER MAPPING FOR asciiword, asciihword, hword_asciipart,
                        word, hword, hword_part
        WITH english_shared, english_stem;

### F.50.4. Author

Tomas Vondra `<tomas.vondra@2ndquadrant.com>`, Prague, Czech Republic