source: npl/mailserver/dspam/dspam-3.10.2/src/heap.c

Last change on this file was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 3.6 KB
Line 
1/* $Id: heap.c,v 1.94 2011/06/28 00:13:48 sbajic Exp $ */
2
3/*
4 DSPAM
5 COPYRIGHT (C) 2002-2012 DSPAM PROJECT
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Affero General Public License as
9 published by the Free Software Foundation, either version 3 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU Affero General Public License for more details.
16
17 You should have received a copy of the GNU Affero General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20*/
21
22/*
23 * heap.c - fast heap-based sorting algorithm with maximum window size
24 *
25 * DESCRIPTION
26 *   This sorting algorithm is designed to perform very efficiently when there
27 *   is a small window-size of 'peak' values, such as the 15 bayes slots.
28 */
29
30#include <stdlib.h>
31#include <math.h>
32#include "heap.h"
33
34ds_heap_t
35ds_heap_create(int size, int type)
36{
37  ds_heap_t h;
38
39  h = calloc(1, sizeof(struct _ds_heap));
40  h->size = size;
41  h->type = type;
42  return h;
43}
44
45void
46ds_heap_destroy(ds_heap_t h)
47{
48  if (h) {
49    ds_heap_element_t node, next;
50    node = h->root;
51    while(node) {
52      next = node->next;
53      free(node);
54      node = next;
55    }
56    free(h);
57  }
58  return;
59}
60
61ds_heap_element_t
62ds_heap_element_create (double probability,
63                  unsigned long long token,
64                  unsigned long frequency,
65                  int complexity)
66{
67  ds_heap_element_t element = calloc(1, sizeof(struct _ds_heap_element));
68
69  if (!element)
70    return NULL;
71
72  element->delta       = fabs(0.5-probability);
73  element->probability = probability;
74  element->token       = token;
75  element->frequency   = frequency;
76  element->complexity  = complexity;
77
78  return element;
79}
80
81ds_heap_element_t
82ds_heap_insert (ds_heap_t h,
83             double probability,
84             unsigned long long token,
85             unsigned long frequency,
86             int complexity)
87{
88  ds_heap_element_t current = NULL;
89  ds_heap_element_t insert = NULL;
90  ds_heap_element_t node;
91  float delta = fabs(0.5-probability);
92
93  current = h->root;
94
95  /* Determine if and where we should insert this item */
96  if (h->type == HP_DELTA) {
97    while(current) {
98      if (delta > current->delta)
99        insert = current;
100      else if (delta == current->delta) {
101        if (frequency > current->frequency)
102          insert = current;
103        else if (frequency == current->frequency)
104          if (complexity >= current->complexity)
105            insert = current;
106      }
107      if (!insert)
108        break;
109      else
110        current = current->next;
111    }
112  } else {
113   while(current) {
114      if (probability > current->probability)
115        insert = current;
116      if (!insert)
117        break;
118      else
119        current = current->next;
120    }
121  }
122
123  if (insert != NULL) {
124
125    /* Insert item, throw out new least significant item if necessary */
126    node = ds_heap_element_create( probability, token, frequency, complexity);
127    node->next = insert->next;
128    insert->next = node;
129    h->items++;
130    if (h->items > h->size) {
131      node = h->root;
132      h->root = node->next;
133      free(node);
134      h->items--;
135    }
136  } else {
137   
138    /* Item is least significant; throw it out or grow the heap */
139    if (h->items == h->size)
140      return NULL;
141
142    /* Grow heap */
143    node = ds_heap_element_create(probability, token, frequency, complexity);
144    node->next = h->root;
145    h->root = node;
146    h->items++;
147  }
148
149  return node;
150}
151
Note: See TracBrowser for help on using the repository browser.