]> git.llucax.com Git - z.facultad/75.06/jacu.git/blob - src/blocksorting/bs.c
ddd6aef86a89e989fb5b7bd200b99bebb4f13be8
[z.facultad/75.06/jacu.git] / src / blocksorting / bs.c
1
2 #include "bs.h"
3 #include <stdlib.h>
4
5 /* Block Sorting Optimizado en memoria! */
6
7 typedef struct _bs_decode_t_ {
8         char c;
9         Uint32 sig;
10 } t_BlockSortDecode;
11
12 char es_menor(char *data, t_BlockSort *bs, int i, int j);
13
14 int _compare(const void *d1, const void *d2) {
15         t_BlockSortDecode *s1, *s2;
16
17         s1 = (t_BlockSortDecode *)d1;
18         s2 = (t_BlockSortDecode *)d2;
19
20         /* Hack si es el mismo caracter, dejo como mejor la de menor sig */
21         if (s1->c == s2->c) {
22                 return (s1->sig - s2->sig);
23         }
24
25         return (s1->c - s2->c);
26 }
27
28 int __compare(const void *d1, const void *d2) {
29         t_BlockSortData *s1, *s2;
30         char i;
31
32         s1 = (t_BlockSortData *)d1;
33         s2 = (t_BlockSortData *)d2;
34
35         i = es_menor(s1->bs->data, s1->bs, s1->pos_inicial, s2->pos_inicial);
36
37 /*      if (i == 0) {*/
38                 /* si ambos strings son iguales, fuerzo a que d1 quede primero */
39                 /*return -1;
40         }*/
41         return i;
42 }
43
44 char es_menor(char *data, t_BlockSort *bs, int i, int j)
45 {
46         Uint32 pi, pj, k;
47
48         for(k=0; k<bs->len; k++) {
49                 pi = (i+k)%bs->len;
50                 pj = (j+k)%bs->len;
51
52                 if (data[pi] > data[pj]) return 1; /* El primero es mayor */
53                 if (data[pi] < data[pj]) return -1; /* El primero es menor */
54         }
55
56         /* Son iguales! */
57         return 0;
58 }
59
60 void generar_array(char *data, t_BlockSort *bs)
61 {
62         int i;
63         for(i=0; i<bs->len; i++) {
64                 bs->array[i].pos_inicial = i;
65                 bs->array[i].pos_final = (i+bs->len-1)%bs->len;
66                 bs->array[i].ord = (i==0)?1:0;
67                 bs->array[i].bs = bs;
68         }
69 }
70
71 void ordenar_array(char *data, t_BlockSort *bs)
72 {
73         qsort(bs->array, bs->len, sizeof(t_BlockSortData), __compare);
74 }
75
76 void print_(char *data, Uint32 pos, Uint32 len)
77 {
78         Uint32 i;
79
80         for(i=0; i<len; i++)
81                 fprintf(stderr, "%c", data[(pos+i)%len]);
82         fprintf(stderr, "\n");
83 }
84
85 int generar_salida(char *data, t_BlockSort *bs, char *salida)
86 {
87         Uint32 i, k;
88         char *out;
89
90         /* Dejo lugar para guardar el k y el tamaño de este bloque */
91         out = salida + sizeof(Uint32)*2;
92
93         k=-1;
94         for(i=0; i<bs->len; i++) {
95                 /* print_(data, bs->array[i].pos_inicial, bs->len); */
96                 out[i] = data[bs->array[i].pos_final];
97                 if (bs->array[i].ord == 1) k = i;
98         }
99         return k;
100 }
101
102 void bs_solve(char *in, char *out, t_BlockSort *bs, Uint32 *k, Uint32 leido)
103 {
104         unsigned int l;
105         l = bs->len;
106         /* Hack para pedasos menores a la pagina */
107         if (leido < bs->len) bs->len = leido;
108         bs->data = in;
109
110         generar_array(in, bs);
111         ordenar_array(in, bs);
112         (*k) = generar_salida(in, bs, out);
113
114         /* Guardo el k y el tamaño en el array */
115         memcpy(out, &leido, sizeof(Uint32));
116         memcpy(out+sizeof(Uint32), k, sizeof(Uint32));
117         bs->len = l;
118 }
119
120 void print_v(t_BlockSortDecode *d, size_t len)
121 {
122         size_t i;
123         
124         for(i=0; i<len; i++)
125                 printf("(%ld)", d[i].sig);
126         printf("\n");
127         for(i=0; i<len; i++)
128                 printf("(%d)", d[i].c);
129         printf("\n");
130 }
131
132 void bs_restore(char *dst, char *c, Uint32 k, Uint32 len)
133 {
134         Uint32 i, current;
135         t_BlockSortDecode *in;
136
137         in = malloc(sizeof(t_BlockSortDecode)*len);
138
139         for(i=0; i<len; i++) {
140                 in[i].c = c[i];
141                 in[i].sig = i;
142         }
143
144         /*printf("Antes de QSort\n");
145         print_v(in, len);*/
146         qsort(in, len, sizeof(t_BlockSortDecode), _compare);
147         /*printf("Despues de QSort\n");
148         print_v(in, len);*/
149         
150         current = k;
151         i=0;
152         do {
153                 dst[i++] = in[current].c;
154                 current = in[current].sig;
155         } while (current != k);
156         free(in);
157
158         if (i < len) printf("Noo %ld != %ld\n", i, len);
159 }
160
161 t_BlockSort *bs_create(Uint32 len)
162 {
163         t_BlockSort *tmp;
164
165         tmp = malloc(sizeof(t_BlockSort));
166         tmp->array = malloc(sizeof(t_BlockSortData)*len);
167         tmp->len = len;
168
169         return tmp;
170 }
171
172
173 void bs_destroy(t_BlockSort *bs)
174 {
175         free(bs->array);
176         free(bs);
177 }
178