Для индексирования внешних источников данных Яndex.Server 3.4 использует специальные модули расширения, которые могут быть написаны независимыми разработчиками. Модуль расширения реализован в виде динамической библиотеки, экспортирующей определенные данной спецификацией функции. Ниже приведен включаемый файл, описывающий требуемые функции.
#if defined(_WIN32)
# ifdef YDS_EXPORTS
# define YDS_API __declspec(dllexport)
# else
# define YDS_API __declspec(dllimport)
# endif
#else
# define YDS_API
#endif
extern "C" {
typedef enum YDSstatus {
YDS_OK = 0, //все в порядке
YDS_COMMON = 1 << 29, //неизвестная ошибка
YDS_BADHANDLE, //плохой дескриптор
YDS_OUTOFMEMORY, //кончились ресурсы
YDS_EOF //конец блока данных
YDS_BADCONFIG
} YDS_STATUS;
typedef char* YDSURL;
typedef void *DATAOBJ; //дескриптор источника данных
typedef void *QURLOBJ; //дескриптор запроса, возвращающего список YDSURL-в для индексирования
typedef void *QDOCOBJ; //дескриптор запроса, возвращающего указатель на документ
//указатели, передаваемые через указатели на них, ссылаются на память,
//за выделение и освобождение которой ответственна библиотека
//Обязательные функции
YDS_API YDS_STATUS YDS_OpenDataSrc(DATAOBJ *db, const char *config_filename, int KeepAlive);
YDS_API YDS_STATUS YDS_CloseDataSrc(DATAOBJ db);
YDS_API YDS_STATUS YDS_OpenUrlList(QURLOBJ *Query, unsigned *flag, DATAOBJ db);
YDS_API YDS_STATUS YDS_MoveNextUrl(QURLOBJ Query, YDSURL *ppuri);
YDS_API YDS_STATUS YDS_CloseUrlList(QURLOBJ Query);
YDS_API YDS_STATUS YDS_OpenDocContent(QDOCOBJ* Query, YDSURL url, time_t *timestamp, char **mime, char **charset, DATAOBJ db);
YDS_API YDS_STATUS YDS_ReadDocumentBytes(QDOCOBJ Query, void *toFill, size_t maxToRead, size_t *Read);
YDS_API YDS_STATUS YDS_CloseDocQuery(QDOCOBJ Query);
//необязательные функции
YDS_API YDS_STATUS YDS_OpenDocParseUrl(QDOCOBJ* Query, YDSURL url, char **redir, size_t *redirsize, DATAOBJ db);
YDS_API YDS_STATUS YDS_Dump(DATAOBJ db, const char* dir);
YDS_API YDS_STATUS YDS_GetLastError(DATAOBJ db, char **err);
} // extern "C"Каждый документ в источнике данных уникально идентифицируется строкой, например, для SQL-баз, полями базы данных через слеш.
Функции библиотеки вызываются как при индексировании, так и при поиске, для получения подсвечиваемого документа. При индексировании, сначала вызываются функции для получения списка идентификаторов документов. Полученные идентификаторы передаются обратно библиотеке для получения содержимого документа. Все функции, вызываемые при индексировании, вызываются в одном треде. При поиске вызываются только функции для получения содержимого документа. Для каждого нового документа эти функции, в общем случае, вызываются в новом треде. Разберем последовательность вызова более подробно.
Сначала вызывается YDS_OpenDataSrc, которая должна прочитать конфигурационный файл и проинициализировать дескриптор источника данных. В качестве третьего параметра в этом вызове функция принимает 1. Затем вызывается YDS_OpenUrlList, которая должна инициализировать запрос на получение списка идентификаторов документов, которые надо индексировать. Библиотека устанавливает второй параметр в 0 или 1. 0 - библиотека создает отсортированный список идентификаторов документов, живущий все время индексирования. 1 - библиотека создает неотсортированный список урлов, живущий короткое время, до начала индексирования первого документа.
Если параметр установлен в 1, Яndex.Server 3.4 вызывает YDS_MoveNextUrl до тех пор, пока она не вернет YDS_EOF, сохраняет полученный список, вызывает YDS_CloseUrlList, после чего начинает индексирование документов. Если параметр установлен в 0, Яndex.Server 3.4 вызывает YDS_MoveNextUrl один раз перед каждым индексированием нового документа, и вызывает YDS_CloseUrlList в самом конце индексирования. В любом случае, вызов YDS_CloseDataSrc будет сделан в конце индексирования внешнего источника данных.
YDS_MoveNextUrl возвращает во втором параметре указатель на область памяти, в которой хранится идентификатор документа - строка, заканчивающаяся нулем. Между вызовами YDS_MoveNextUrl библиотека должна сохранять эту область памяти в корректном состоянии.
Перед началом индексирования первого документа Яndex.Server 3.4 повторно вызывает YDS_OpenDataSrc с новым первым параметром. Второй и третий параметры такие же, как и в первом вызове. В процессе индексирования каждого документа Яndex.Server 3.4 последовательно вызывает функции YDS_OpenDocContent, YDS_ReadDocumentBytes, и YDS_CloseDocQuery.
YDS_OpenDocContent должна по переданному идентификатору инициализировать запрос на получение содержимого документа. В параметре charset библиотека может вернуть строку-идентификатор кодировки документа. Библиотека может игнорировать этот параметр, тогда по умолчанию кодировка будет такой, как указано в настройках индексатора. В параметре mime библиотека может вернуть строку-идентификатор медиа-типа документа. Этот медиа-тип должен совпадать с одним из типов, указанных в настройках индексатора, и определяет используемый индексатором парсер документного формата. Библиотека может игнорировать этот параметр, тогда по умолчанию будет text/html. В параметре timestamp может передаваться 0 или время последнего обновления документа. При первом индексировании библиотека может установить этот параметр. Установленное значение будет передано библиотеке при повторном индексировании. В зависимости от своих настроек индексатор может не запрашивать документы (не вызывать функцию YDS_ReadDocumentBytes), если время последнего обновления не изменилось. YDS_ReadDocumentBytes последовательно вызывается один или несколько раз для получения содержимого документа. Библиотека должна записать по адресу toFill текущую порцию документа размером не более maxToRead байт и вернуть число реально записанных байт в параметре Read. Если функция возвращает YDS_EOF, значит документ закончился. Если *Read меньше, чем maxToRead, это также считается признаком окончания документа.
Если в библиотеке определена YDS_Dump, она будет вызвана после индексирования последнего документа. В качестве второго параметра передается директория, в которой будет размещен индекс. Библиотека опционально может создать файлы *c2n и c2p, которые могут понадобиться поисковому серверу при использовании группировочных атрибутов.
В конце индексирования документов вызывается YDS_CloseDataSrc.
Функция YDS_OpenDataSrc вызывается при выполнении первого поискового запроса, в результате которого нашлись документы из внешнего источника данных, и дизайн страницы результатов поиска предполагает ссылку на содержимое документа, с подсветкой или без. В третьем параметре передается 0. После формирования страницы выдачи вызывающий тред заканчивает свою работу. Гарантируется отсутствие повторных или одновременных вызовов.
Если библиотека содержит функцию YDS_OpenDocParseUrl, то при формировании показываемого пользователю URL, ведущему на содержание документа, последовательно вызываются функции YDS_OpenDocParseUrl и YDS_CloseDocQuery для каждого URL. YDS_OpenDocParseUrl возвращает YDS_OK, установив третий параметр на область памяти, включающую URL со схемой, которую понимает браузер, и остающуюся корректной до вызова YDS_CloseDocQuery. Этот URL будет показан на странице выдачи. Например, это может быть адрес скрипта на веб-сервере, принимающего CGI-параметры, сформированные на основании идентификатора документа, переданного во втором параметре функции YDS_OpenDocParseUrl. Если же YDS_OpenDocParseUrl отсутствует или возвращает YDS_EOF, в качестве URL, ведущего на содержание документа, будет показан тот же адрес, что и для подсвеченного документа, но без подсветки.
При выполнении запроса на получение подсвеченного документа последовательно вызываются YDS_OpenDocContent, YDS_ReadDocumentBytes, и YDS_CloseDocQuery в новом треде. В параметре timestamp в YDS_ReadDocumentBytes всегда передается 0, что соответствует необходимости получить содержание документа. После этого вызывающий тред заканчивает свою работу.
Функция YDS_CloseDataSrc вызывается из еще одного треда в момент остановки поискового сервиса.