]> git.llucax.com Git - z.facultad/75.06/jacu.git/blob - src/blocksorting/bs.c
Huffman con capacidad de comprimir chunks y presentando nueva API. El descompresor...
[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 pos;
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         return (s1->c - s2->c);
21 }
22
23 int __compare(const void *d1, const void *d2) {
24         t_BlockSortData *s1, *s2;
25
26         s1 = (t_BlockSortData *)d1;
27         s2 = (t_BlockSortData *)d2;
28
29         return es_menor(s1->bs->data, s1->bs, s1->pos_inicial, s2->pos_inicial);
30 }
31
32 char es_menor(char *data, t_BlockSort *bs, int i, int j)
33 {
34         Uint32 pi, pj, k;
35
36         for(k=0; k<bs->len; k++) {
37                 pi = (i+k)%bs->len;
38                 pj = (j+k)%bs->len;
39
40                 if (data[pi] > data[pj]) return 1; /* El primero es mayor */
41                 if (data[pi] < data[pj]) return -1; /* El primero es menor */
42         }
43
44         /* Son iguales! */
45         return 0;
46 }
47
48 void generar_array(char *data, t_BlockSort *bs)
49 {
50         int i;
51         for(i=0; i<bs->len; i++) {
52                 bs->array[i].pos_inicial = i;
53                 bs->array[i].pos_final = (i+bs->len-1)%bs->len;
54                 bs->array[i].ord = (i==0)?1:0;
55                 bs->array[i].bs = bs;
56         }
57 }
58
59 void ordenar_array(char *data, t_BlockSort *bs)
60 {
61         qsort(bs->array, bs->len, sizeof(t_BlockSortData), __compare);
62 }
63
64 void print_(char *data, Uint32 pos, Uint32 len)
65 {
66         Uint32 i;
67
68         for(i=0; i<len; i++)
69                 fprintf(stderr, "%c", data[(pos+i)%len]);
70         fprintf(stderr, "\n");
71 }
72
73 int generar_salida(char *data, t_BlockSort *bs, char *salida)
74 {
75         Uint32 i, k;
76         char *out;
77
78         /* Dejo lugar para guardar el k y el tamaño de este bloque */
79         out = salida + sizeof(Uint32)*2;
80
81         k=-1;
82         for(i=0; i<bs->len; i++) {
83                 /* print_(data, bs->array[i].pos_inicial, bs->len); */
84                 out[i] = data[bs->array[i].pos_final];
85                 if (bs->array[i].ord == 1) k = i;
86         }
87         return k;
88 }
89
90 void bs_solve(char *in, char *out, t_BlockSort *bs, Uint32 *k, Uint32 leido)
91 {
92         unsigned int l;
93         l = bs->len;
94         /* Hack para pedasos menores a la pagina */
95         if (leido < bs->len) bs->len = leido;
96         bs->data = in;
97
98         generar_array(in, bs);
99         ordenar_array(in, bs);
100         (*k) = generar_salida(in, bs, out);
101
102         /* Guardo el k y el tamaño en el array */
103         memcpy(out, &leido, sizeof(Uint32));
104         memcpy(out+sizeof(Uint32), k, sizeof(Uint32));
105         bs->len = l;
106 }
107
108 void bs_restore(char *dst, char *c, Uint32 k, Uint32 len)
109 {
110         Uint32 i, current;
111         t_BlockSortDecode *in;
112
113         in = malloc(sizeof(t_BlockSortDecode)*len);
114
115         for(i=0; i<len; i++) {
116                 in[i].c = c[i];
117                 in[i].pos = i;
118         }
119
120         qsort(in, len, sizeof(t_BlockSortDecode), _compare);
121         
122         current = k;
123         i=0;
124         do {
125                 dst[i++] = in[current].c;
126                 current = in[current].pos;
127         } while (current != k);
128         free(in);
129 }
130
131 t_BlockSort *bs_create(Uint32 len)
132 {
133         t_BlockSort *tmp;
134
135         tmp = malloc(sizeof(t_BlockSort));
136         tmp->array = malloc(sizeof(t_BlockSortData)*len);
137         tmp->len = len;
138
139         return tmp;
140 }
141
142
143 void bs_destroy(t_BlockSort *bs)
144 {
145         free(bs->array);
146         free(bs);
147 }
148