Fixed notification of live-updates. Fixed minor problem with mf_init
[idzebra-moved-to-github.git] / isamb / isamb.c
1
2 #include <yaz/xmalloc.h>
3 #include <isamb.h>
4
5 struct ISAMB_s {
6     BFiles bfs;
7     ISAMC_M method;
8 };
9
10 typedef unsigned char *Bpage;
11
12 ISAMB isamb_open (BFiles bfs, const char *name, ISAMC_M method)
13 {
14     ISAMB isamb = xmalloc (sizeof(*isamb));
15
16     isamb->bfs = bfs;
17     isamb->method = (ISAMC_M) xmalloc (sizeof(*method));
18     memcpy (isamb->method, method, sizeof(*method));
19     return isamb;
20 }
21
22 void isamb_close (ISAMB isamb)
23 {
24     xfree (isamb->method);
25     xfree (isamb);
26 }
27
28 #if 0
29 /* read page at pos */
30 void isamb_get_block (ISAMB is, ISAMB_pos pos, Bpage *page)
31 {
32 }
33
34 /* alloc page */
35 ISAMB_pos isamb_alloc_block (ISAMB is, int block_size, Bpage *page)
36 {
37 }
38
39 #define isamb_page_set_leaf (p)   0[p] = 1
40 #define isamb_page_set_noleaf (p) 0[p] = 0
41 #define isamb_page_datalist (4+p)
42
43 static void isamb_page_set_no(Bpage page, int no)
44 {
45     page[1] = no & 255;
46     page[2] = (no >> 8) & 255;
47     page[3] = (no >> 16) & 255;
48 }
49
50 static int isamb_page_get_no(Bpage page)
51 {
52     return page[1] + 256*page[2] + 65536*page[3];
53 }
54
55 void isamb_insert_sub(ISAMB is, ISAMB_pos *pos, const void *data)
56 {
57     const char *src;
58     char dst[200];
59     int no, i;
60     
61     isamb_get_block (is, *pos, &page);
62     if (!isamb_page_isleaf (page))
63     {
64         ISAMB_pos subptr;
65         src = isamb_page_datalist (page);
66         no = isamb_page_get_no (page);
67         decodeClientData = (*is->method->code_start)(ISAMC_DECODE);
68         
69         isamb_read_subptr (&subptr, &src);
70         for (i = 0; i<no; i++)
71         {
72             const char *src0 = src;
73             
74             (*is->method->code_item)(ISAMC_DECODE, decodeClientData,
75                                      dst, &src);
76             if ((*is->method->compare_item)(data, dst) < 0)
77                 break;
78             
79             isamb_read_subptr (&subptr, src);
80         }
81         isamb_insert_sub (is, subptr, data);
82         *pos = subptr;
83         (*is->method->code_stop)(ISAMC_DECODE, decodeClientData);
84     }
85     else
86     {
87         src = isamb_page_datalist (page);
88         no = isamb_page_get_no (page);
89         decodeClientData = (*is->method->code_start)(ISAMC_DECODE);
90         diff = -1;
91         for (i = 0; i<no; i++)
92         {
93             int diff;
94             (*is->method->code_item)(ISAMC_DECODE, decodeClientData,
95                                      dst, &src);
96             diff = (*is->method->compare_item)(data, dst);
97             if (diff <= 0)
98                 break;
99         }
100         if (diff < 0)
101         {
102             int j;
103             src = isamb_page_datalist (page);
104             page2 = isamb_page_dup (is, page);
105             dst2 = isamb_page_datalist (page2);
106             src2 = data;
107             for (j = 0; j <= no; j++)
108             {
109                 if ( i == j)
110                     (*is->method->code_item)(ISAMC_ENCODE, encodeClientData,
111                                              &dst2, &src2);
112                 if (j < no)
113                 {
114                     char *dst0 = dst;
115                     (*is->method->code_item)(ISAMC_DECODE, decodeClientData,
116                                              &dst, &src);
117                     (*is->method->code_item)(ISAMC_ENCODE, encodeClientData,
118                                              &dst2, &dst0);
119                 }
120             }
121         }
122     }
123 }
124 /* insert data(input) in table is(input) at pos(input/output) */
125 int isamb_insert (ISAMB is, ISAMB_pos *pos, const void *data)
126 {
127     void *decodeClientData;
128
129     Bpage page;
130     if (*pos == 0)
131     {
132         *pos = isamb_alloc_block (is, 1024, &page);
133         isamb_page_set_leaf (page);
134         isamb_page_set_no (page, 0);
135     }
136     else     /* find leaf ... */
137     {
138         isamb_insert_sub (is, pos, const void *data);
139
140     }
141 }
142 #endif