~ubuntu-branches/ubuntu/warty/swish-e/warty

« back to all changes in this revision

Viewing changes to src/metanames.c

  • Committer: Bazaar Package Importer
  • Author(s): Ludovic Drolez
  • Date: 2004-03-11 08:41:07 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040311084107-7vp0mu82blq1qjvo
Tags: 2.4.1-3
Oops ! A comment was not removed to disable interactive compilation.
Closes: Bug#237332

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
   -- This module does metaname handling for swish-e
 
4
   -- 
 
5
** This program and library is free software; you can redistribute it and/or
 
6
** modify it under the terms of the GNU (Library) General Public License
 
7
** as published by the Free Software Foundation; either version 2
 
8
** of the License, or any later version.
 
9
**
 
10
** This program is distributed in the hope that it will be useful,
 
11
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
13
** GNU (Library) General Public License for more details.
 
14
**
 
15
** You should have received a copy of the GNU (Library) General Public License
 
16
** along with this program; if not, write to the Free Software
 
17
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
18
 
 
19
 
 
20
   -- 2001-02-12 rasc    minor changes, concering the tolower problem 
 
21
                 (unsigned char) problem!!!
 
22
 
 
23
*/
 
24
 
 
25
 
 
26
 
 
27
 
 
28
#include "swish.h"
 
29
#include "mem.h"
 
30
#include "merge.h"
 
31
#include "swstring.h"
 
32
#include "search.h"
 
33
#include "docprop.h"
 
34
#include "metanames.h"
 
35
#include "dump.h"
 
36
#include "error.h"
 
37
 
 
38
typedef struct
 
39
{
 
40
    char   *metaName;
 
41
    int     metaType;           /* see metanames.h for values. All values must be "ored" */
 
42
}
 
43
defaultMetaNames;
 
44
 
 
45
 
 
46
/**************************************************************************
 
47
*   List of *internal* meta names
 
48
*
 
49
*   Note:
 
50
*       Removing any of these will prevent access for result output
 
51
*       Removing any of the "real" meta names will also prevent storing
 
52
*       of the data in the property file.
 
53
*       That is, they may be commented out and then selected in the
 
54
*       configuration file as needed.
 
55
*       Hard to imagine not wanting the doc path!
 
56
*
 
57
***************************************************************************/
 
58
 
 
59
 
 
60
static defaultMetaNames SwishDefaultMetaNames[] = {
 
61
 
 
62
    /* This is the default meta ID ( number 1 ) that plain text is stored as */
 
63
    { AUTOPROPERTY_DEFAULT,      META_INDEX },  /* REQUIRED */
 
64
 
 
65
 
 
66
    /* These are the "internal" meta names generated at search time they are all required */
 
67
    { AUTOPROPERTY_REC_COUNT,    META_PROP | META_INTERNAL | META_NUMBER },
 
68
    { AUTOPROPERTY_RESULT_RANK,  META_PROP | META_INTERNAL | META_NUMBER },
 
69
    { AUTOPROPERTY_FILENUM,      META_PROP | META_INTERNAL | META_NUMBER },
 
70
    { AUTOPROPERTY_INDEXFILE,    META_PROP | META_INTERNAL | META_STRING },
 
71
 
 
72
    /* These meta names "real" meta names that are available by default */
 
73
    /* These can be commented out (e.g. to save disk space) and added back in with PropertyNames */
 
74
    { AUTOPROPERTY_DOCPATH,      META_PROP | META_STRING },
 
75
    { AUTOPROPERTY_TITLE,        META_PROP | META_STRING | META_IGNORE_CASE },
 
76
    { AUTOPROPERTY_DOCSIZE,      META_PROP | META_NUMBER},
 
77
    { AUTOPROPERTY_LASTMODIFIED, META_PROP | META_DATE},
 
78
 // { AUTOPROPERTY_SUMMARY,      META_PROP | META_STRING},
 
79
 // { AUTOPROPERTY_STARTPOS,     META_PROP | META_NUMBER},  // should be added only if LST is selected
 
80
};
 
81
 
 
82
/* Add the Internal swish metanames to the index file structure */
 
83
void    add_default_metanames(IndexFILE * indexf)
 
84
{
 
85
    int     i;
 
86
 
 
87
    for (i = 0; i < (int)(sizeof(SwishDefaultMetaNames) / sizeof(SwishDefaultMetaNames[0])); i++)
 
88
        addMetaEntry(&indexf->header, SwishDefaultMetaNames[i].metaName, SwishDefaultMetaNames[i].metaType, 0);
 
89
}
 
90
 
 
91
 
 
92
 
 
93
/**************************************************************************
 
94
*   These next routines add a new property/metaname to the list
 
95
*
 
96
*
 
97
***************************************************************************/
 
98
 
 
99
 
 
100
 
 
101
/* Add an entry to the metaEntryArray if one doesn't already exist */
 
102
 
 
103
 
 
104
struct metaEntry *addMetaEntry(INDEXDATAHEADER *header, char *metaname, int metaType, int metaID)
 
105
{
 
106
    struct metaEntry *tmpEntry = NULL;
 
107
    char *metaWord;
 
108
 
 
109
    if (metaname == NULL || metaname[0] == '\0')
 
110
        progerr("internal error - called addMetaEntry without a name");
 
111
 
 
112
 
 
113
    metaWord = estrdup( metaname );
 
114
    strtolower(metaWord);
 
115
 
 
116
 
 
117
    /* See if there is a previous metaname with the same name */
 
118
//    tmpEntry = metaType & META_PROP
 
119
//               ? getPropNameByName(header, metaWord)
 
120
//               : getMetaNameByName(header, metaWord);
 
121
               
 
122
 
 
123
    if (!tmpEntry)              /* metaName not found - Create a new one */
 
124
        tmpEntry = addNewMetaEntry( header, metaWord, metaType, metaID);
 
125
 
 
126
    else
 
127
        /* This allows adding Numeric or Date onto an existing property. */
 
128
        /* Probably not needed */
 
129
        tmpEntry->metaType |= metaType;
 
130
 
 
131
 
 
132
    efree( metaWord );
 
133
 
 
134
    return tmpEntry;
 
135
        
 
136
}
 
137
 
 
138
static struct metaEntry *create_meta_entry( char *name )
 
139
{
 
140
    struct metaEntry *newEntry = (struct metaEntry *) emalloc(sizeof(struct metaEntry));
 
141
 
 
142
    memset(newEntry, 0, sizeof(struct metaEntry));
 
143
    newEntry->metaName = (char *) estrdup( name );
 
144
    newEntry->sort_len = MAX_SORT_STRING_LEN;  /* default for sorting strings */
 
145
    return newEntry;
 
146
}
 
147
    
 
148
 
 
149
 
 
150
struct metaEntry *addNewMetaEntry(INDEXDATAHEADER *header, char *metaWord, int metaType, int metaID)
 
151
{
 
152
    int    metaCounter = header->metaCounter;
 
153
    struct metaEntry *newEntry;
 
154
    struct metaEntry **metaEntryArray = header->metaEntryArray;
 
155
    newEntry = create_meta_entry( metaWord );
 
156
    
 
157
    newEntry->metaType = metaType;
 
158
 
 
159
    /* If metaID is 0 asign a value using metaCounter */
 
160
    /* Loaded stored metanames from index specifically sets the metaID */
 
161
    
 
162
    newEntry->metaID = metaID ? metaID : metaCounter + 1;
 
163
 
 
164
 
 
165
    /* Create or enlarge the array, as needed */
 
166
    if(! metaEntryArray)
 
167
    {
 
168
        metaEntryArray = (struct metaEntry **) emalloc(sizeof(struct metaEntry *));
 
169
        metaCounter = 0;
 
170
    }
 
171
    else
 
172
        metaEntryArray = (struct metaEntry **) erealloc(metaEntryArray,(metaCounter + 1) * sizeof(struct metaEntry *));
 
173
 
 
174
 
 
175
    /* And save it in the array */
 
176
    metaEntryArray[metaCounter++] = newEntry;
 
177
 
 
178
    /* Now update the header */
 
179
    header->metaCounter = metaCounter;
 
180
    header->metaEntryArray = metaEntryArray;
 
181
 
 
182
    return newEntry;
 
183
}
 
184
 
 
185
/**************************************************************************
 
186
*   Clear in_tag flags on all metanames
 
187
*   The flags are used for indexing
 
188
*
 
189
***************************************************************************/
 
190
 
 
191
 
 
192
/** Lookup META_INDEX -- these only return meta names, not properties **/
 
193
 
 
194
void ClearInMetaFlags(INDEXDATAHEADER * header)
 
195
{
 
196
    int     i;
 
197
 
 
198
    for (i = 0; i < header->metaCounter; i++)
 
199
        header->metaEntryArray[i]->in_tag = 0;
 
200
}
 
201
 
 
202
 
 
203
 
 
204
 
 
205
/**************************************************************************
 
206
*   Initialize the property mapping array
 
207
*   Used to get the property seek pointers from the index file
 
208
*
 
209
*   THIS IS TEMPORARY until I break up the metanames and properties
 
210
*
 
211
*   This just creates two arrays to map metaIDs between property index numbers.
 
212
*
 
213
***************************************************************************/
 
214
 
 
215
void init_property_list(INDEXDATAHEADER *header)
 
216
{
 
217
    int i;
 
218
 
 
219
    /* only needs to be called one time */
 
220
    if ( header->property_count )
 
221
        return;
 
222
 
 
223
    if ( header->propIDX_to_metaID )
 
224
        progerr("Called init_property_list with non-null header->propIDX_to_metaID");
 
225
 
 
226
    if ( !header->metaCounter )
 
227
    {
 
228
        header->property_count = -1;  
 
229
        return;
 
230
    }
 
231
 
 
232
 
 
233
    header->propIDX_to_metaID = emalloc( (1 + header->metaCounter) * sizeof( int ) );
 
234
    header->metaID_to_PropIDX = emalloc( (1 + header->metaCounter) * sizeof( int ) );
 
235
 
 
236
    for (i = 0; i < header->metaCounter; i++)
 
237
    {
 
238
        if (is_meta_property(header->metaEntryArray[i]) && !header->metaEntryArray[i]->alias && !is_meta_internal(header->metaEntryArray[i]) )
 
239
        {
 
240
            header->metaID_to_PropIDX[header->metaEntryArray[i]->metaID] = header->property_count;
 
241
            header->propIDX_to_metaID[header->property_count++] = header->metaEntryArray[i]->metaID;
 
242
        }
 
243
        else
 
244
            header->metaID_to_PropIDX[header->metaEntryArray[i]->metaID] = -1;
 
245
    }
 
246
 
 
247
    if ( !header->property_count )
 
248
        header->property_count = -1;
 
249
}
 
250
 
 
251
    
 
252
 
 
253
 
 
254
/**************************************************************************
 
255
*   These routines lookup either a property or a metaname
 
256
*   by its ID or name
 
257
*
 
258
*   The routines only look at either properites or metanames
 
259
*
 
260
*   Note: probably could save a bit by just saying that if not META_PROP then
 
261
*   it's a a meta index entry.  In otherwords, the type flag of zero could mean
 
262
*   META_INDEX, otherwise it's a PROPERTY.  $$$ todo...
 
263
*
 
264
*
 
265
***************************************************************************/
 
266
 
 
267
 
 
268
/** Lookup META_INDEX -- these only return meta names, not properties **/
 
269
 
 
270
struct metaEntry *getMetaNameByNameNoAlias(INDEXDATAHEADER * header, char *word)
 
271
{
 
272
    int     i;
 
273
 
 
274
    for (i = 0; i < header->metaCounter; i++)
 
275
        if (is_meta_index(header->metaEntryArray[i]) && !strcasecmp(header->metaEntryArray[i]->metaName, word))
 
276
            return header->metaEntryArray[i];
 
277
 
 
278
    return NULL;
 
279
}
 
280
 
 
281
 
 
282
/* Returns the structure associated with the metaName if it exists
 
283
*  Requests for Aliased names returns the base meta entry, not the alias meta entry.
 
284
*  Note that on a alias it checks the *alias*'s type, so it must match.
 
285
*/
 
286
 
 
287
struct metaEntry *getMetaNameByName(INDEXDATAHEADER * header, char *word)
 
288
{
 
289
    int     i;
 
290
 
 
291
    for (i = 0; i < header->metaCounter; i++)
 
292
        if (is_meta_index(header->metaEntryArray[i]) && !strcasecmp(header->metaEntryArray[i]->metaName, word))
 
293
            return header->metaEntryArray[i]->alias
 
294
                   ? getMetaNameByID( header, header->metaEntryArray[i]->alias )
 
295
                   : header->metaEntryArray[i];
 
296
 
 
297
    return NULL;
 
298
}
 
299
 
 
300
 
 
301
/* Returns the structure associated with the metaName ID if it exists
 
302
*/
 
303
 
 
304
struct metaEntry *getMetaNameByID(INDEXDATAHEADER *header, int number)
 
305
{
 
306
    int     i;
 
307
 
 
308
    for (i = 0; i < header->metaCounter; i++)
 
309
    {
 
310
        if (is_meta_index(header->metaEntryArray[i]) && number == header->metaEntryArray[i]->metaID)
 
311
            return header->metaEntryArray[i];
 
312
    }
 
313
    return NULL;
 
314
}
 
315
 
 
316
 
 
317
 
 
318
/** Lookup META_PROP -- these only return properties **/
 
319
 
 
320
struct metaEntry *getPropNameByNameNoAlias(INDEXDATAHEADER * header, char *word)
 
321
{
 
322
    int     i;
 
323
 
 
324
    for (i = 0; i < header->metaCounter; i++)
 
325
        if (is_meta_property(header->metaEntryArray[i]) && !strcasecmp(header->metaEntryArray[i]->metaName, word))
 
326
            return header->metaEntryArray[i];
 
327
 
 
328
    return NULL;
 
329
}
 
330
 
 
331
 
 
332
/* Returns the structure associated with the metaName if it exists
 
333
*  Requests for Aliased names returns the base meta entry, not the alias meta entry.
 
334
*  Note that on a alias it checks the *alias*'s type, so it must match.
 
335
*/
 
336
 
 
337
struct metaEntry *getPropNameByName(INDEXDATAHEADER * header, char *word)
 
338
{
 
339
    int     i;
 
340
 
 
341
 
 
342
    for (i = 0; i < header->metaCounter; i++)
 
343
        if (is_meta_property(header->metaEntryArray[i]) && !strcasecmp(header->metaEntryArray[i]->metaName, word))
 
344
            return header->metaEntryArray[i]->alias
 
345
                   ? getPropNameByID( header, header->metaEntryArray[i]->alias )
 
346
                   : header->metaEntryArray[i];
 
347
 
 
348
    return NULL;
 
349
}
 
350
 
 
351
 
 
352
/* Returns the structure associated with the metaName ID if it exists
 
353
*/
 
354
 
 
355
struct metaEntry *getPropNameByID(INDEXDATAHEADER *header, int number)
 
356
{
 
357
    int     i;
 
358
 
 
359
    for (i = 0; i < header->metaCounter; i++)
 
360
    {
 
361
        if (is_meta_property(header->metaEntryArray[i]) && number == header->metaEntryArray[i]->metaID)
 
362
            return header->metaEntryArray[i];
 
363
    }
 
364
 
 
365
    return NULL;
 
366
}
 
367
 
 
368
 
 
369
 
 
370
 
 
371
 
 
372
/* This is really used to check for seeing which internal metaname is being requested */
 
373
 
 
374
int is_meta_entry( struct metaEntry *meta_entry, char *name )
 
375
{
 
376
    return strcasecmp( meta_entry->metaName, name ) == 0;
 
377
}
 
378
 
 
379
 
 
380
/**************************************************************************
 
381
*   Free list of MetaEntry's
 
382
*
 
383
***************************************************************************/
 
384
 
 
385
 
 
386
 
 
387
/* Free meta entries for an index file */
 
388
 
 
389
void   freeMetaEntries( INDEXDATAHEADER *header )
 
390
{
 
391
    int i;
 
392
 
 
393
    /* Make sure there are meta names assigned */
 
394
    if ( !header->metaCounter )
 
395
        return; 
 
396
 
 
397
 
 
398
    /* should the elements be set to NULL? */
 
399
    for( i = 0; i < header->metaCounter; i++ )
 
400
    {
 
401
        struct metaEntry *meta = header->metaEntryArray[i];
 
402
 
 
403
        efree( meta->metaName );
 
404
 
 
405
#ifndef USE_BTREE
 
406
        if ( meta->sorted_data)
 
407
            efree( meta->sorted_data );
 
408
#endif
 
409
 
 
410
        if ( meta->extractpath_default )
 
411
            efree( meta->extractpath_default );
 
412
            
 
413
 
 
414
        efree( meta );
 
415
    }
 
416
 
 
417
    /* And free the pointer to the list */
 
418
    efree( header->metaEntryArray);
 
419
    header->metaEntryArray = NULL;
 
420
    header->metaCounter = 0;
 
421
}
 
422
 
 
423
 
 
424
/**************************************************************************
 
425
*   Check if should bump word position on this meta name
 
426
*
 
427
***************************************************************************/
 
428
 
 
429
 
 
430
int isDontBumpMetaName( struct swline *tmplist, char *tag)
 
431
{
 
432
char *tmptag;
 
433
 
 
434
    if (!tmplist) return 0;
 
435
    if (strcmp(tmplist->line,"*")==0) return 1;
 
436
    
 
437
    tmptag=estrdup(tag);
 
438
    tmptag=strtolower(tmptag);
 
439
    while(tmplist)
 
440
    {
 
441
    
 
442
        if( strcasecmp(tmptag,tmplist->line)==0 )
 
443
        {
 
444
            efree(tmptag);
 
445
            return 1;
 
446
        }
 
447
        tmplist=tmplist->next;
 
448
    }
 
449
    efree(tmptag);
 
450
    return 0;
 
451
 
 
452
}
 
453
 
 
454
/*************************************************
 
455
* int properties_compatible -
 
456
*
 
457
*  checks to see if two properties can be compared
 
458
*
 
459
**************************************************/
 
460
int properties_compatible( struct metaEntry *m1, struct metaEntry *m2 )
 
461
{
 
462
    int mask = META_STRING | META_NUMBER | META_DATE | META_IGNORE_CASE;
 
463
    return (m1->metaType & mask ) == ( m2->metaType & mask);
 
464
 
465