Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
241852 views
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <string.h>
4
#include <memory.h>
5
#include "cstd.h"
6
#include "smalljactab.h"
7
8
9
/*
10
Copyright 2007 Andrew V. Sutherland
11
12
This file is part of smalljac.
13
14
smalljac is free software: you can redistribute it and/or modify
15
it under the terms of the GNU General Public License as published by
16
the Free Software Foundation, either version 2 of the License, or
17
(at your option) any later version.
18
19
smalljac is distributed in the hope that it will be useful,
20
but WITHOUT ANY WARRANTY; without even the implied warranty of
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
GNU General Public License for more details.
23
24
You should have received a copy of the GNU General Public License
25
along with smalljac. If not, see <http://www.gnu.org/licenses/>.
26
*/
27
28
/*
29
We allocate three sections of memory, all of which will be small in practice (a few megabytes).
30
31
(1) the hash table - 64 bits per entry
32
(2) the lookaside table - 128 bits per entry
33
(3) overflow lists - 128 bits per entry
34
35
In most cases, only (1) gets used, and this is what we want to keep in cache. We don't really
36
care about the size of the rest.
37
38
Currently the number of overflow entries is equal the size of the hash table. If we exceed this we
39
are getting a whole lot of collisions and should increase the table size anway.
40
*/
41
42
void smalljac_table_alloc (int bits)
43
{
44
if ( bits > 31 ) { err_printf ("smalljac_table_alloc: bits=%d too large!\n", bits); exit (0); }
45
smalljac_htab = malloc(sizeof(*smalljac_htab)*(1<<bits)); // use malloc rather than mem_alloc - we don't need the memory initialized
46
// allocate space equal to table size for overflow - this could be made bigger
47
smalljac_htab_lists = malloc(sizeof(*smalljac_htab_lists)*2*(1<<bits)); // ditto
48
smalljac_htab_end = smalljac_htab_lists + 2*(1<<bits);
49
smalljac_table_bits = bits;
50
}
51
52
53
void smalljac_table_init (int bits)
54
{
55
static int warn;
56
57
if ( bits > smalljac_table_bits ) {
58
if ( ! warn ) { printf ("%lu: smalljac_table_init: bits=%d exceeds allocated table size of %d bits\n", _ff_p, bits, smalljac_table_bits); warn = 1; }
59
if ( bits-smalljac_table_bits > 4 ) { printf ("you must increase the allocated table size"); exit (0); }
60
bits = smalljac_table_bits;
61
}
62
smalljac_tabmask = (1UL<<bits)-1;
63
memset (smalljac_htab, 0, (1<<bits)*sizeof(unsigned long));
64
smalljac_htab_next = smalljac_htab_lists + (1<<bits);
65
}
66
67
68
void _smalljac_table_collision_insert (int index, unsigned long item)
69
{
70
// printf ("collision at index %d\n", index);
71
if ( ! smalljac_htab_lists[index].item ) { smalljac_htab_lists[index].item = item; smalljac_htab_lists[index].pNext = 0; return; }
72
if ( smalljac_htab_next >= smalljac_htab_end ) {
73
err_printf ("%lu: Ran out of htab overflow entries smalljac_htab_next-smalljac_htab_lists = %index - increase table size.\n", _ff_p, smalljac_htab_next-smalljac_htab_lists); exit (0); }
74
smalljac_htab_next->item = item;
75
smalljac_htab_next->pNext = smalljac_htab_lists[index].pNext;
76
smalljac_htab_lists[index].pNext = smalljac_htab_next++;
77
}
78
79
80
int _smalljac_table_get_matches (uint32_t matches[SMALLJAC_MAX_MATCHES], jac_t a[1], int index)
81
{
82
register unsigned long item;
83
register struct smalljac_htab_list_item *pItem;
84
register int i;
85
86
#if HECURVE_GENUS == 1
87
item = a[0].u[0];
88
#else
89
item = (_ff_one(a[0].u[HECURVE_GENUS]) ? (1UL<<SMALLJAC_ITEM_BITS) : 0) + a[0].u[HECURVE_GENUS-1];
90
item <<= SMALLJAC_ITEM_BITS;
91
item += a[0].u[HECURVE_GENUS-2];
92
#endif
93
#if HECURVE_GENUS == 3
94
item <<= SMALLJAC_ITEM_BITS;
95
item += a[0].u[HECURVE_GENUS-3];
96
#endif
97
item <<= SMALLJAC_VBITS;
98
i = 0;
99
if ( (smalljac_htab[index] ^ item) <= SMALLJAC_VMASK ) matches[i++] = smalljac_htab[index]&SMALLJAC_VMASK;
100
if ( ! smalljac_htab_lists[index].item ) return i;
101
if ( (smalljac_htab_lists[index].item ^ item) <= SMALLJAC_VMASK ) matches[i++] = smalljac_htab_lists[index].item&SMALLJAC_VMASK;
102
if ( ! smalljac_htab_lists[index].pNext ) return i;
103
pItem = smalljac_htab_lists[index].pNext;
104
do {
105
if ( (pItem->item ^ item) <= SMALLJAC_VMASK ) {
106
if ( i >= SMALLJAC_MAX_MATCHES ) { err_printf ("Exceeded SMALLJAC_MAX_MATCHES!\n"); exit (0); }
107
matches[i++] = pItem->item&SMALLJAC_VMASK;
108
}
109
pItem = pItem->pNext;
110
} while ( pItem );
111
return i;
112
}
113
114
115
116