/[bfilter]/trunk/bfilter.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/bfilter.js

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 7 by dpavlin, Tue Sep 7 17:44:56 2004 UTC revision 28 by dpavlin, Thu Sep 23 18:22:50 2004 UTC
# Line 1  Line 1 
1  /*  /*
2     Fast filtering function using pre-sorted list elements     Fast filtering function using pre-sorted list elements
3     Dobrica Pavlinusic, dpavlin@rot13.org 2004-09-06     Dobrica Pavlinusic, dpavlin@rot13.org 2004-09-06
4       Matko Andjelinic, matko.andjelinic@gmail.com 2004-09-09 (contributed OO implementation)
5  */  */
6    
 var debug = 0;  
7    
8  function bfilter_init() {  function BFilter(arr) {
9          show_status();          this.id_cache = Array();
10  }          // total number of hits
11            this.hits = 0;
12    
13            this.results_html = null;
14    
15            // this function is called for each result
16            this.result = function (arr) {
17                    this.results_html += '<li><a href="'+arr[1]+'">'+
18                            (this.hits % 2 == 0 ? '<span style="background: #e0e0e0;">' : '') +
19                            arr[0] +
20                            (this.hits % 2 == 0 ? '</span>' : '') +
21                            '</a></li>';
22                    return true;
23            }
24    
25            // this function is called when updating innerHTML with results
26            this.display = function () {
27                    if (this.results_html) {
28                            return '<ul>'+this.results_html+'</ul>';
29                    } else {
30                            return null;
31                    }
32            }
33    
34    
35            if (! arr) {
36                    this.debug("ERROR: can't search empty array");
37                    return;
38            }
39    
40  var id_cache = Array();          this.arr = arr;
41            this.debug("index has "+this.arr.length+" parts");
42    
43  function element_id(id) {          if (! arr.min_len) {
44          if (id_cache[id]) {                  this.results("ERROR: index structure problem");
45                  return id_cache[id];                  return;
46            } else {
47                    this.min_len = arr.min_len;
48            }
49    
50            this.debug("index part has "+this.min_len+" parts");
51    
52            this.show_status();
53    
54    }
55    
56    BFilter.prototype.element_id = function (id,no_alert) {
57            if (this.id_cache[id]) {
58                    return this.id_cache[id];
59          } else {          } else {
60                  var el = document.getElementById(id);                  var el = document.getElementById(id);
61                  if (el) {                  if (el) {
62                          id_cache[id] = el;                          this.id_cache[id] = el;
63                          return el;                          return el;
64                  } else {                  } else {
65                          alert("can't find element id: "+id);                          if (! no_alert) {
66                                    alert("can't find element id: "+id);
67                            } else {
68                                    // don't look it up again
69                                    this.id_cache[id] = null;
70                            }
71                  }                  }
72          }          }
73            return null;
74  }  }
75    
 // total number of hits  
 var hits = 0;  
76    
77  function show_status(status) {  BFilter.prototype.show_status = function (status) {
78          var html;          var html;
79          if (hits > 0) {          if (this.hits > 0) {
80                  html = "shown "+hits+" entries";                  html = "shown "+this.hits+" entries";
81          } else {          } else {
82                  html = "no results";                  html = "no results";
83          }          }
84          if (! status) {          if (! status) {
85                  html = "Enter "+min_len+" letter"+(min_len == 1 ? '' : 's')+" to filter entries";                  html = "Enter "+this.min_len+" letter"+(this.min_len == 1 ? '' : 's')+" to filter entries";
86                  status = "";                  status = "";
87          }          }
88    
89          var el = element_id("status");          var el = this.element_id("status");
90          el.innerHTML = html+status+"\n";          el.innerHTML = html+status+"\n";
91  }  }
92    
93  var wait = 0;  BFilter.prototype.results = function (html,clean) {
   
 function results(html,clean) {  
94    
95          if (! html) { html = ""; }          if (! html) { html = ""; }
96    
97          // results_div.style.cursor = 'wait'; // 'auto'          // results_div.style.cursor = 'wait'; // 'auto'
98          var results_div = element_id("results");          var results_div = this.element_id("results");
99          if (clean) {          if (clean) {
100                  results_div.innerHTML = html+"\n";                  results_div.innerHTML = html;
101          } else {          } else {
102                  results_div.innerHTML += html+"\n";                  html = this.display();
103                    if (html) results_div.innerHTML += html;
104          }          }
105  }  }
106    
107    
108    BFilter.prototype.debug = function (html) {
109    
110            //return;
111    
112            // check if debugging is on
113            if (! html) { return 1; }
114    
115            var debug_div = this.element_id("debug",1);
116            if (! debug_div) { return null; }
117    
118            debug_div.innerHTML += html + "<br>\n";
119    
120            return null;
121    }
122    
123    
124  // modified binary search to find first element with substring  // modified binary search to find first element with substring
125  function binarySearch(arr, find) {  BFilter.prototype.binarySearch = function (arr, find) {
126          if (!arr || typeof (find) == "undefined" || !arr.length) {          if (!arr || typeof (find) == "undefined" || !arr.length) {
127                  return null;                  return null;
128          }          }
# Line 72  function binarySearch(arr, find) { Line 134  function binarySearch(arr, find) {
134                  var mid = (low + high) / 2;                  var mid = (low + high) / 2;
135                  var aTry = (mid < 1) ? 0 : parseInt(mid);                  var aTry = (mid < 1) ? 0 : parseInt(mid);
136                    
137                  var curr = arr[aTry][1].substr(0,find.length).toLowerCase();                  var curr = arr[aTry][0].substr(0,find.length).toLowerCase();
138                  if (debug) { results("low="+low+" high="+high+" lastTry="+lastTry+" "+aTry+": "+curr+"<br>"); }                  this.debug("low="+low+" high="+high+" lastTry="+lastTry+" "+aTry+": "+curr);
139                  if (curr < find) {                  if (curr < find) {
140                          low = aTry + 1;                          low = aTry + 1;
141                          continue;                          continue;
# Line 89  function binarySearch(arr, find) { Line 151  function binarySearch(arr, find) {
151                  }                  }
152                  return aTry;                  return aTry;
153          }          }
154          if (debug) { results("lastTry="+lastTry+"<br>"); }          this.debug("lastTry="+lastTry);
155    
156          if (typeof (lastTry) != "undefined") {          if (typeof (lastTry) != "undefined") {
157                  return lastTry;                  return lastTry;
# Line 98  function binarySearch(arr, find) { Line 160  function binarySearch(arr, find) {
160          }          }
161  }  }
162    
163  function bfilter(document, id, find, arr) {  BFilter.prototype.filter = function (document, find) {
164    
165          results('',1);          this.results('',1);
166          hits = 0;          this.hits = 0;
167    
168          if (find.length < min_len) {          if (find.length < this.min_len) {
169                  show_status();                  this.show_status();
170                  return;                  return;
171          }          }
172    
173          if (debug) { results("filter: '"+find+"'<br>"); }          this.debug("filter: '"+find+"'");
174    
175          var find_lc = find.toLowerCase();          var find_lc = find.toLowerCase();
176    
177          var part = find_lc.substr(0,min_len);          var part = find_lc.substr(0,this.min_len);
178    
179          // no part found          // no part found
180          if (! arr[part]) {          if (! this.arr[part]) {
181                  show_status(" for <em>"+find+"</em><br>");                  this.show_status(" for <em>"+find+"</em><br>");
182                    this.debug("no part "+part);
183                  return;                  return;
184          }          }
185    
186          // start anim icon          // start anim icon
187          //results("<img  src=\"pie.gif\">&nbsp;Please wait, filtering...\n",1);          //results("<img  src=\"pie.gif\">&nbsp;Please wait, filtering...\n",1);
188    
189            var i;
190    
191          // full part? (optimization)          // full part? (optimization)
192          if (find.length == min_len) {          if (find.length == this.min_len) {
193                  var html = '';                  for (i = 0; i < this.arr[part].length; i++) {
194                  for (var i = 0; i < arr[part].length; i++) {                          this.result(this.arr[part][i]);
195                          html += html_pre + arr[part][i][0] + html_mid;                          this.hits++;
                         if (debug) { $html += i+": "; }  
                         html += arr[part][i][1] + html_post + "\n";  
                         hits++;  
196                  }                  }
197                  results(html);                  this.results();
198          } else {          } else {
199    
200                  var from = binarySearch(arr[part], find_lc);                  var from = this.binarySearch(this.arr[part], find_lc);
201    
202                  if (from != null) {                  if (from != null) {
203                                    
204                          if (debug) { results("loop "+from+" ... "+arr[part].length)+"<br>\n"; }                          this.debug("loop "+from+" ... "+this.arr[part].length);
   
                         var html = '';  
205    
206                          for(var i = from ; i < arr[part].length ; i++) {                          for(i = from ; i < this.arr[part].length ; i++) {
207                                  if (arr[part][i][1].substring(0,find.length).toLowerCase() != find_lc) {                                  if (this.arr[part][i][0].substring(0,find.length).toLowerCase() != find_lc) {
208                                            this.debug("loop exit at "+i);
209                                          break;                                          break;
210                                  }                                  }
211                                  html += html_pre + arr[part][i][0] + html_mid;                                  this.result(this.arr[part][i]);
212                                  if (debug) { html += i+": "; }                                  this.hits++;
                                 html += arr[part][i][1] + html_post + "\n";  
                                 hits++;  
213                          }                          }
214    
215                          results(html);                          this.results();
216                  }                  }
217    
218          }          }
219    
220          show_status(" for <em>"+find+"</em>");          this.show_status(" for <em>"+find+"</em>");
221    
222  }  }
223    

Legend:
Removed from v.7  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26