0001 function result = doxysearch(query,filename)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 error(nargchk(1,2,nargin));
0033 if nargin == 1,
0034 filename = 'search.idx';
0035 end
0036
0037
0038 [fid, errmsg] = fopen(filename,'r','ieee-be');
0039 if fid == -1, error(errmsg); end
0040
0041
0042 header = char(fread(fid,4,'uchar'))';
0043 if ~all(header == 'DOXS')
0044 error('[doxysearch] Header of index file is invalid!');
0045 end
0046
0047
0048 r = query;
0049 requiredWords = {};
0050 forbiddenWords = {};
0051 foundWords = {};
0052 res = {};
0053 while 1
0054
0055 [t,r] = strtok(r);
0056 if isempty(t), break, end;
0057 if t(1) == '+'
0058 t = t(2:end); requiredWords{end+1} = t;
0059 elseif t(1) == '-'
0060 t = t(2:end); forbiddenWords{end+1} = t;
0061 end
0062 if ~ismember(t,foundWords)
0063 foundWords{end+1} = t;
0064 res = searchAgain(fid,t,res);
0065 end
0066 end
0067
0068
0069 docs = combineResults(res);
0070 filtdocs = filterResults(docs,requiredWords,forbiddenWords);
0071 filtdocs = normalizeResults(filtdocs);
0072 res = sortResults(filtdocs);
0073
0074
0075 if nargout
0076 result = res;
0077 else
0078 for i=1:size(res,1)
0079 fprintf(' %d. %s - %s\n ',i,res{i,1},res{i,2});
0080 for j=1:size(res{i,4},1)
0081 fprintf('%s ',res{i,4}{j,1});
0082 end
0083 fprintf('\n');
0084 end
0085 end
0086
0087
0088 fclose(fid);
0089
0090
0091 function res = searchAgain(fid, word,res)
0092
0093 i = computeIndex(word);
0094 if i > 0
0095
0096 fseek(fid,i*4+4,'bof');
0097 start = size(res,1);
0098 idx = readInt(fid);
0099
0100 if idx > 0
0101
0102 fseek(fid,idx,'bof');
0103 statw = readString(fid);
0104 while ~isempty(statw)
0105 statidx = readInt(fid);
0106 if length(statw) >= length(word) & ...
0107 strcmp(statw(1:length(word)),word)
0108 res{end+1,1} = statw;
0109 res{end,2} = word;
0110 res{end,3} = statidx;
0111 res{end,4} = (length(statw) == length(word));
0112 res{end,5} = {};
0113 end
0114 statw = readString(fid);
0115 end
0116
0117 totalfreq = 0;
0118 for j=start+1:size(res,1)
0119 fseek(fid,res{j,3},'bof');
0120 numdoc = readInt(fid);
0121 docinfo = {};
0122 for m=1:numdoc
0123 docinfo{m,1} = readInt(fid);
0124 docinfo{m,2} = readInt(fid);
0125 docinfo{m,3} = 0;
0126 totalfreq = totalfreq + docinfo{m,2};
0127 if res{j,2},
0128 totalfreq = totalfreq + docinfo{m,2};
0129 end;
0130 end
0131 for m=1:numdoc
0132 fseek(fid, docinfo{m,1}, 'bof');
0133 docinfo{m,4} = readString(fid);
0134 docinfo{m,5} = readString(fid);
0135 end
0136 res{j,5} = docinfo;
0137 end
0138
0139 for j=start+1:size(res,1)
0140 for m=1:size(res{j,5},1)
0141 res{j,5}{m,3} = res{j,5}{m,2} / totalfreq;
0142 end
0143 end
0144
0145 end
0146
0147 end
0148
0149
0150 function docs = combineResults(result)
0151
0152 docs = {};
0153 for i=1:size(result,1)
0154 for j=1:size(result{i,5},1)
0155 key = result{i,5}{j,5};
0156 rank = result{i,5}{j,3};
0157 if ~isempty(docs) & ismember(key,{docs{:,1}})
0158 l = find(ismember({docs{:,1}},key));
0159 docs{l,3} = docs{l,3} + rank;
0160 docs{l,3} = 2 * docs{l,3};
0161 else
0162 l = size(docs,1)+1;
0163 docs{l,1} = key;
0164 docs{l,2} = result{i,5}{j,4};
0165 docs{l,3} = rank;
0166 docs{l,4} = {};
0167 end
0168 n = size(docs{l,4},1);
0169 docs{l,4}{n+1,1} = result{i,1};
0170 docs{l,4}{n+1,2} = result{i,2};
0171 docs{l,4}{n+1,3} = result{i,5}{j,2};
0172 end
0173 end
0174
0175
0176 function filtdocs = filterResults(docs,requiredWords,forbiddenWords)
0177
0178 filtdocs = {};
0179 for i=1:size(docs,1)
0180 words = docs{i,4};
0181 c = 1;
0182 j = size(words,1);
0183
0184 if ~isempty(requiredWords)
0185 found = 0;
0186 for k=1:j
0187 if ismember(words{k,1},requiredWords)
0188 found = 1;
0189 break;
0190 end
0191 end
0192 if ~found, c = 0; end
0193 end
0194
0195 if ~isempty(forbiddenWords)
0196 for k=1:j
0197 if ismember(words{k,1},forbiddenWords)
0198 c = 0;
0199 break;
0200 end
0201 end
0202 end
0203
0204 if c,
0205 l = size(filtdocs,1)+1;
0206 filtdocs{l,1} = docs{i,1};
0207 filtdocs{l,2} = docs{i,2};
0208 filtdocs{l,3} = docs{i,3};
0209 filtdocs{l,4} = docs{i,4};
0210 end;
0211 end
0212
0213
0214 function docs = normalizeResults(docs);
0215
0216 m = max([docs{:,3}]);
0217 for i=1:size(docs,1)
0218 docs{i,3} = 100 * docs{i,3} / m;
0219 end
0220
0221
0222 function result = sortResults(docs);
0223
0224 [y, ind] = sort([docs{:,3}]);
0225 result = {};
0226 ind = fliplr(ind);
0227 for i=1:size(docs,1)
0228 result{i,1} = docs{ind(i),1};
0229 result{i,2} = docs{ind(i),2};
0230 result{i,3} = docs{ind(i),3};
0231 result{i,4} = docs{ind(i),4};
0232 end
0233
0234
0235 function i = computeIndex(word)
0236
0237 if length(word) < 2,
0238 i = -1;
0239 else
0240 i = double(word(1)) * 256 + double(word(2));
0241 end
0242
0243
0244 function s = readString(fid)
0245
0246 s = '';
0247 while 1
0248 w = fread(fid,1,'uchar');
0249 if w == 0, break; end
0250 s(end+1) = char(w);
0251 end
0252
0253
0254 function i = readInt(fid)
0255
0256 i = fread(fid,1,'uint32');