| | Модуль источника данных
API источника данных
API источника данных содержится в файле yandds.h.
Пример реализации источника данных находится в каталоге sample/flist.
Интерфейс каждого источника данных заключен в структуру DATASRC_LIB, состоящую из 6 указателей на функции:
typedef
struct DATASRC_LIB {
FUNC_DataSrc_OpenIndexingSession OpenIndexingSession;
FUNC_DataSrc_OpenSearchSession OpenSearchSession;
FUNC_DataSrc_OpenDoc OpenDoc;
FUNC_DataSrc_ReadDocumentBytes ReadDocumentBytes;
FUNC_DataSrc_CloseDoc CloseDoc;
FUNC_DataSrc_CloseSession CloseSession;
FUNC_DataSrc_GetProperty GetProperty;
} DATASRC_LIB;
Каждая из функций возвращает целое число, одно из следующих.
typedef enum YDS_STATUS {
YDS_ERROR = -2,
YDS_EOF = -1,
YDS_OK = 0
} YDS_STATUS;
Каждая из функций в качестве первого аргумента принимает дескриптор объекта, инкапсулирующего источник данных и определенного как
и должна быть потоково безопасна.
Работа источника данных при индексировании
В начале каждого сеанса индексирования индексатор загружает структуру DATASRC_LIB из указанного в конфигурации места. Затем один раз вызывается OpenIndexingSession. Если OpenIndexingSession возвращает YDS_OK, происходит индексирование, в конце которого один раз вызывается CloseSession(). В противном случае индексирования и каких-либо последующих вызовов не происходит.
В течение индексирования индексатор последовательно вызывает OpenDoc()/ReadDocumentBytes()/CloseDoc(). Индексирование прекращается в случае, если OpenDoc() возвращает YDS_EOF. Если OpenDoc() вернула YDS_OK, в дальнейшем последует вызов CloseDoc(). Когда OpenDoc() возвращает YDS_OK, она всегда должна установить поле DOCINPUT::UrlBase. Если при этом установлено поле DOCINPUT::ReaderObj, документ будет проиндексирован в первый раз или переиндексирован, в процессе этого между вызовами OpenDoc() и CloseDoc() будет один или несколько раз вызвана функция ReadDocumentBytes() для считывания содержимого документа. Если же DOCINPUT::ReaderObj нулевой, документ с идентификатором DOCINPUT::UrlBase будет удален из индекса, а вызовов ReadDocumentBytes() не будет.
Политика переиндексирования полностью определяется источником данных. Источник данных сам определяет, как формируются идентификаторы документов и где они хранятся, если их вообще нужно хранить между сеансами индексирования. Для каждого нового или изменившегося документа источник возвращает валидные DOCINPUT::UrlBase и DOCINPUT::ReaderObj. Источник может также установить и другие поля структуры DOCINPUT.
Работа источника данных при поиске
Во время поиска источник данных используется только для подсветки найденных слов в полном документе формата text/plain и text/html и для поиска похожих документов. Если такая функциональность не нужна, OpenSearchSession() должна просто возвращать YDS_EOF.
В начале каждого сеанса поиска загружается структура DATASRC_LIB из указанного в конфигурации места. Функция OpenSearchSession() вызывается один раз в каждом поисковом потоке, при первом запросе на подсветку или поиск похожего. Таким образом, во время поиска OpenSearchSession() может вызываться несколько раз из разных потоков. Если OpenSearchSession() возвращает YDS_OK, источник данных используется во время поиска, в конце которого один раз вызывается CloseSession().
Если поисковая сессия успешно открыта, при запросе на подсветку или поиск похожего документа будут вызываться функции OpenDoc()/ReadDocumentBytes()/CloseDoc(). Эта последовательность вызовов будет происходить в одном и том же поисковом потоке. Возможен одновременный параллельный вызов из разных потоков для разных документов.
Функции структуры DATASRC_LIB
| Функции и их описание |
|
typedef int (*FUNC_DataSrc_OpenIndexingSession)(DATAOBJ *DataObj, const char *Config, const INDEX_CONFIG *Ic)
Возвращает YDS_OK или YDS_ERROR.
DataObj - адрес объекта источника данных. Если открытие произошло успешно, переменной *DataObj должен быть присвоен допустимый адрес.
Config - строка конфигурации, указанная в директиве Config секции DataSrc конфигурации индексатора.
Ic - конфигурационные данные индексатора. Например, INDEX_CONFIG::tempdir может использоваться для создания временных файлов, если надо, а INDEX_CONFIG::newindexdir может служить префиксом файла с данными о текущем сеансе индексирования, которые нужны во время следующего.
|
|
typedef int (*FUNC_DataSrc_OpenSearchSession)(DATAOBJ *DataObj, const char *config, const char *indexprefix, YX_LOGNOTIFY YxLogNotify, YX_LOGOBJ LogObj)
Возвращает YDS_OK при успешном завершении, YDS_ERROR в случае ошибки и YDS_EOF в случае, если использовать источник данных во время поиска не нужно.
DataObj - адрес объекта источника данных. Если открытие произошло успешно, переменной *DataObj должен быть присвоен допустимый адрес.
Config - строка конфигурации, указанная в директиве Config секции DataSrc конфигурации поискового сервиса.
indexprefix - префикс индекса, по которому происходит поиск.
YxLogNotify, LogObj - обеспечивают доступ к логу вызывающей программы для протоколирования или записи отладочной информации.
|
|
typedef int (*FUNC_DataSrc_OpenDoc)(DATAOBJ DataObj, DOCINPUT *di)
Возвращает YDS_OK при успешном завершении, YDS_ERROR в случае ошибки и YDS_EOF в случае, если документов для индексирования больше нет.
DataObj - допустимый объект источника данных, открытый в функции OpenIndexingSession или OpenSearchSession.
di - информация о документе, содержимое которого будет предоставлено во время последующего вызова ReadDocumentBytes().
Если поля структуры di нулевые, вызов произошел из индексатора. В этом случае надо заполнить поле UrlBase для удаляемого документа и, как минимум, поля UrlBase, ReaderObj и MimeType для документа, предназначенного для индексации. Если такой UrlBase уже есть в индексе, он будет переиндексирован. Если ReaderObj оставлен нулевым, документ будет удален из индекса. Если в поле UrlProp предоставлен URL с префиксом http:, он будет передан клиенту конечного пользователя поиска для открытия найденного документа.
В противном случае, во время поиска будет использован источник данных, и в структуре di при вызове данной функции будет заполнено поле UrlProp. В этом случае также необходимо заполнить поле ReaderObj.
|
|
typedef int (*FUNC_DataSrc_ReadDocumentBytes)(DATAOBJ DataObj, YX_DOCOBJ ReaderObj, void *toFill, size_t maxToRead, size_t *Read)
Возвращает YDS_OK при успешном завершении, YDS_ERROR в случае ошибки и YDS_EOF в случае, если документ полностью прочитан.
DataObj - допустимый объект источника данных, открытый в функции OpenIndexingSession или OpenSearchSession.
ReaderObj - дескриптор объекта для чтения документа, указанный источником в OpenDoc().
toFill - буфер, в который надо записать содержимое документа.
maxToRead - размер переданного буфера.
Read - адрес переменной, в которой источник должен вернуть фактическое число байт, записанных им в буфер toFill (и меньшее maxToRead).
При успешном заполнении буфера для чтения функция возвращает YDS_OK.
Если возвращается YDS_EOF, вызовы функции прекращаются, документ полностью прочитан.
Если в какой-то момент возвращается YDS_ERROR, документ в индекс не попадает. Фактически, источник может читать содержимое документа в момент вызова этой функции, или возвращать прочитанное ранее в OpenDoc().
|
|
typedef int (*FUNC_DataSrc_CloseDoc)(DATAOBJ DataObj, DOCINPUT *di, IParser *pars)
Возвращает YDS_OK, YDS_EOF или YDS_ERROR.
DataObj - допустимый объект источника данных, открытый в функции OpenIndexingSession или OpenSearchSession.
di - тот же объект, что был передан в OpenDoc().
pars - объект парсера, который был использован для интерпретации данного документа.
Освобождает ресурсы, возможно занятые в OpenDoc(). При необходимости, может вызвать GetProperty для получения свойств документа, определенных при индексировании, например, кодировки или списка ссылок. Свойство парсера PP_INDEXRES будет содержать строку "OK" или описание ошибки, возникшей при индексировании. Если данная функция возвращает YDS_OK, документ будет сохранен в индексе. В противном случае индекс не будет содержать документа с di->UrlBase. Это может быть использовано, если решение о сохранении документа в индексе нужно принять после анализа свойств документа, определенных при индексировании.
Пример реализации функции:
int ::CloseDoc(DATAOBJ DataObj, DOCINPUT *di, IParser* P)
{
int ret = YDS_OK;
if (di && di->ReaderObj != NULL) {
// to do:
// освобождаем ресурсы, выделенные для di->ReaderObj в функции OpenDoc()
if (P) {
char* prop = 0;
ATTR_TYPE at;
P->GetProperty(PP_INDEXRES, &prop, &at);
if (prop && strcmp(indres, "OK") == 0) {
// to do:
// Записываем нужную информацию из di во внутренний лог источника данных
// для последующего использования при переиндексировании или
// в системе внешнего мониторинга.
// Посылаем любые сообщения во внешний мир о том, что данный документ проиндексирован.
}
if (P->GetProperty(PP_ROBOTS, &prop, &at) == 0) {
if (prop && prop[0] == '0') // noindex
ret = YDS_EOF; // не включать в индекс
}
}
// to do:
// освобождаем ресурсы, выделенные для di в функции OpenDoc()
}
return ret;
}
|
|
typedef int (*FUNC_DataSrc_CloseSession)(DATAOBJ DataObj)
Возвращает YDS_OK или YDS_ERROR.
DataObj - допустимый объект источника данных, открытый в функции OpenIndexingSession или OpenSearchSession.
Освобождает ресурсы, занятые в объекте DataObj. После вызова этой функции дальнейшее использование DataObj недопустимо.
|
|
typedef int (*FUNC_DataSrc_GetProperty)(DATAOBJ DataObj, YDS_PROPERTY PropName, YDSPVALUE *pPropValue)
Возвращает YDS_OK, если значение pPropValue установлено, или YDS_EOF, если нужно использовать поведение по умолчанию.
DataObj - допустимый объект источника данных, открытый в функции OpenIndexingSession или OpenSearchSession.
PropName - идентификатор параметра, значение которого запрашивается.
pPropValue - адрес указателя, в котором надо возвратить значение параметра.
Устанавливает значение одного из параметров, управляющих поведением индексатора.
Индексатор может запрашивать значение одного из следующих параметров:
YDSP_EXTENDID - нужно ли модифицировать идентификатор документа
YDSP_THREADMODEL - можно ли использовать источник данных в многопоточном режиме
YDSP_SAVEDFILES - список суффиксов файлов, в которых источник данных сохраняет информацию, нужную ему для следующего индексирования.
|
| |