source: icXML/icXML-devel/src/icxmlc/XMLSymbolResolver.hpp @ 2720

Last change on this file since 2720 was 2720, checked in by cameron, 6 years ago

Initial check-in of icXML 0.8 source files

File size: 11.8 KB
Line 
1/*
2 *  Copyright © 2012 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icXML is a trademark of International Characters.
5 */
6
7/*
8 * @author Nigel Medforth, nigelm -at- interational-characters.com
9 * @version $Id: XMLSymbolResolver.hpp 207 2012-12-02 20:38:22Z robc $
10 *
11 */
12
13#ifndef XMLSYMBOLTABLEGROUPS_TEMPLATE_HPP
14#define XMLSYMBOLTABLEGROUPS_TEMPLATE_HPP
15
16#include <icxmlc/XMLConfig.hpp>
17#include <simd-lib/bitblock.hpp>
18#include <simd-lib/carryQ.hpp>
19#include <simd-lib/bitblock_scan.hpp>
20#include <icxmlc/XMLSymbol.hpp>
21#include <icxmlc/Array.hpp>
22#include <icxmlc/symbol_table/src/gid.hpp>
23#include <icxmlc/symbol_table/lib/allocator.hpp>
24#include <xercesc/util/XMLString.hpp>
25#include <icxmlc/XMLConfig.hpp>
26#include <iostream>
27
28  struct Groups {
29  BitBlock starts;
30  BitBlock ends;
31  BitBlock ends_1;
32  BitBlock ends_2;
33  BitBlock ends_3;
34  BitBlock ends_4;
35  BitBlock ends_5;
36  BitBlock ends_6;
37  BitBlock ends_7;
38  BitBlock ends_8;
39  BitBlock ends_9;
40  BitBlock ends_10;
41  BitBlock ends_11;
42  BitBlock ends_12;
43  BitBlock ends_13;
44  BitBlock ends_14;
45  BitBlock ends_15;
46  BitBlock ends_16;
47  BitBlock ends_gte_17;
48};
49
50  struct Gen_lgth_groups {
51  Gen_lgth_groups() {
52 }
53  IDISA_ALWAYS_INLINE void do_block(Groups & groups) {
54                BitBlock cursor, temp;
55
56
57                cursor = groups.starts;
58                temp = groups.ends;
59                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(0), 0);
60                groups.ends_1 = simd_and(cursor, temp);
61                temp = simd_andc(temp, groups.ends_1);
62                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(1), 1);
63                groups.ends_2 = simd_and(cursor, temp);
64                temp = simd_andc(temp, groups.ends_2);
65                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(2), 2);
66                groups.ends_3 = simd_and(cursor, temp);
67                temp = simd_andc(temp, groups.ends_3);
68                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(3), 3);
69                groups.ends_4 = simd_and(cursor, temp);
70                temp = simd_andc(temp, groups.ends_4);
71                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(4), 4);
72                groups.ends_5 = simd_and(cursor, temp);
73                temp = simd_andc(temp, groups.ends_5);
74                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(5), 5);
75                groups.ends_6 = simd_and(cursor, temp);
76                temp = simd_andc(temp, groups.ends_6);
77                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(6), 6);
78                groups.ends_7 = simd_and(cursor, temp);
79                temp = simd_andc(temp, groups.ends_7);
80                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(7), 7);
81                groups.ends_8 = simd_and(cursor, temp);
82                temp = simd_andc(temp, groups.ends_8);
83                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(8), 8);
84                groups.ends_9 = simd_and(cursor, temp);
85                temp = simd_andc(temp, groups.ends_9);
86                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(9), 9);
87                groups.ends_10 = simd_and(cursor, temp);
88                temp = simd_andc(temp, groups.ends_10);
89                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(10), 10);
90                groups.ends_11 = simd_and(cursor, temp);
91                temp = simd_andc(temp, groups.ends_11);
92                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(11), 11);
93                groups.ends_12 = simd_and(cursor, temp);
94                temp = simd_andc(temp, groups.ends_12);
95                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(12), 12);
96                groups.ends_13 = simd_and(cursor, temp);
97                temp = simd_andc(temp, groups.ends_13);
98                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(13), 13);
99                groups.ends_14 = simd_and(cursor, temp);
100                temp = simd_andc(temp, groups.ends_14);
101                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(14), 14);
102                groups.ends_15 = simd_and(cursor, temp);
103                temp = simd_andc(temp, groups.ends_15);
104                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(15), 15);
105                groups.ends_16 = simd_and(cursor, temp);
106                temp = simd_andc(temp, groups.ends_16);
107                groups.ends_gte_17 = temp;
108                carryQ.CarryQ_Adjust(16);
109  }
110  IDISA_ALWAYS_INLINE void do_final_block(Groups & groups, BitBlock EOF_mask) {
111                BitBlock cursor, temp;
112
113
114                cursor = groups.starts;
115                temp = groups.ends;
116                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(0), 0);
117                groups.ends_1 = simd_and(cursor, temp);
118                temp = simd_andc(temp, groups.ends_1);
119                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(1), 1);
120                groups.ends_2 = simd_and(cursor, temp);
121                temp = simd_andc(temp, groups.ends_2);
122                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(2), 2);
123                groups.ends_3 = simd_and(cursor, temp);
124                temp = simd_andc(temp, groups.ends_3);
125                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(3), 3);
126                groups.ends_4 = simd_and(cursor, temp);
127                temp = simd_andc(temp, groups.ends_4);
128                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(4), 4);
129                groups.ends_5 = simd_and(cursor, temp);
130                temp = simd_andc(temp, groups.ends_5);
131                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(5), 5);
132                groups.ends_6 = simd_and(cursor, temp);
133                temp = simd_andc(temp, groups.ends_6);
134                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(6), 6);
135                groups.ends_7 = simd_and(cursor, temp);
136                temp = simd_andc(temp, groups.ends_7);
137                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(7), 7);
138                groups.ends_8 = simd_and(cursor, temp);
139                temp = simd_andc(temp, groups.ends_8);
140                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(8), 8);
141                groups.ends_9 = simd_and(cursor, temp);
142                temp = simd_andc(temp, groups.ends_9);
143                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(9), 9);
144                groups.ends_10 = simd_and(cursor, temp);
145                temp = simd_andc(temp, groups.ends_10);
146                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(10), 10);
147                groups.ends_11 = simd_and(cursor, temp);
148                temp = simd_andc(temp, groups.ends_11);
149                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(11), 11);
150                groups.ends_12 = simd_and(cursor, temp);
151                temp = simd_andc(temp, groups.ends_12);
152                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(12), 12);
153                groups.ends_13 = simd_and(cursor, temp);
154                temp = simd_andc(temp, groups.ends_13);
155                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(13), 13);
156                groups.ends_14 = simd_and(cursor, temp);
157                temp = simd_andc(temp, groups.ends_14);
158                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(14), 14);
159                groups.ends_15 = simd_and(cursor, temp);
160                temp = simd_andc(temp, groups.ends_15);
161                cursor = carryQ.BitBlock_advance_ci_co(cursor, carryQ.get_carry_in(15), 15);
162                groups.ends_16 = simd_and(cursor, temp);
163                temp = simd_andc(temp, groups.ends_16);
164                groups.ends_gte_17 = temp;
165  }
166  void do_segment(Groups groups[], int segment_blocks) {
167  int i;
168  for (i = 0; i < segment_blocks; i++)
169        do_block(groups[i]);
170  }
171  CarryArray<16> carryQ;
172  };
173
174
175
176#define ID_SYMBOL_STORE_SYMBOL_GIDS_AT_END_POSITION
177
178#ifdef PRINT_DEBUG_MESSAGE
179#define ID_SYMBOL_TABLE_TEMPLATE_HPP_DEBUG
180#endif
181
182#include <icxmlc/symbol_table/src/id_symbol_table.hpp>
183
184XERCES_CPP_NAMESPACE_BEGIN
185
186template <class XMLScannerType>
187class XMLSymbolResolver
188{
189        private:
190
191                struct InternalGidArray
192                {
193                        gid_t gids[BLOCK_SIZE];
194                };
195
196        public:
197
198                XMLSymbolResolver(XMLScannerType * scanner)
199                : fScanner(scanner)
200                {
201
202                }
203
204                IDISA_ALWAYS_INLINE
205                void resolve
206                (
207                        XMLByte * rawData
208                        , BitBlock * starts, BitBlock * ends
209                        , BitBlock * hash0, BitBlock * hash1
210                        , unsigned int blockCount
211                        , SymbolArray & symbolArray
212                        , unsigned int & symbolCount
213                )
214                {
215                        InternalGidArray internalGidArray;
216                        Groups groups;
217                        scanword_t count = symbolCount;
218                        scanword_t remaining = blockCount;
219                        const gid_t initial_max_gid = fSymbolTable.get_max_gid();
220
221                        for (scanword_t idx = 0; remaining--; idx++)
222                        {
223                                groups.starts = starts[idx];
224                                groups.ends = ends[idx];
225
226  gen_lgth_groups.do_block(groups);
227
228                                #if defined(PRINT_DEBUG_MESSAGE) && !defined(DEBUG_IGNORE_TRANSITION_STREAM_MESSAGES)
229
230                                XMLByte data_block[65];
231                                data_block[64] = '\0';
232
233                                for (unsigned int offset = 0; offset < BLOCK_SIZE; offset += 64)
234                                {
235                                        const XMLByte * byteStream = &rawData[(idx << LOG_2_BLOCK_SIZE) + offset];
236
237                                        for (unsigned int i = 0; i < 64; i++)
238                                        {
239                                                XMLByte cx = byteStream[i];
240                                                if (cx < 32) cx = ' ';
241                                                data_block[i] = cx;
242                                        }
243
244                                        DEBUG_TRANSITION_MESSAGE("----------------------------------------------------------------------");
245                                        DEBUG_TRANSITION_MESSAGE(
246                                                 XERCES_STD_QUALIFIER setw(5) <<
247                                                 ((idx << LOG_2_BLOCK_SIZE) | offset) <<
248                                                 XERCES_STD_QUALIFIER setw(0) <<
249                                                 '|' << data_block );
250                                        DEBUG_TRANSITION_MESSAGE("----------------------------------------------------------------------");
251                                }
252                                #endif
253
254                                // resolve this block into a position indexed gid array
255                                fSymbolTable.resolve(0, &rawData[idx << LOG_2_BLOCK_SIZE], groups, &starts[idx], &hash0[idx], &hash1[idx], internalGidArray);
256
257                                // now compact all of the position indexed gids into the output gid queue
258                                ForwardScanner<BitBlock, scanword_t> itr(&groups.ends);
259                                // what if a start pos exists but no end position exists? I think this is the cause of the 128 limit issue.
260                                itr.scan_to_next();
261                                while (!itr.is_done())
262                                {
263                                        // first get the gid
264                                        const gid_t gid = internalGidArray.gids[itr.get_pos()];
265                                        // add the gid to the output queue
266                                        symbolArray[count++] = gid;
267                                        itr.scan_to_next();
268                                }
269                        }
270
271                        symbolCount = count;
272
273                        // now check if it exists in the symbol array
274                        for (gid_t gid = initial_max_gid; unlikely(gid < fSymbolTable.get_max_gid()); gid++)
275                        {
276                                // this is a new symbol; create it
277                                createNewSymbol(gid, fSymbolTable.get_raw_data(gid), fSymbolTable.get_lgth(gid));
278                        }
279                }
280
281                IDISA_ALWAYS_INLINE
282                void setTranscoder(XMLTranscoder * transcoder)
283                {
284                        fTranscoder = transcoder;
285                }
286
287        private:
288
289                IDISA_ALWAYS_INLINE
290                XMLSymbol * get(const gid_t gid)
291                {
292                        return &fSymbolArray[gid];
293                }
294
295                IDISA_ALWAYS_INLINE
296                void createNewSymbol(const gid_t gid, const uint8_t * rawSymbol, const uint32_t rawLength);
297
298        private:
299                  Gen_lgth_groups gen_lgth_groups;
300
301                id_symbol_table<InternalGidArray, fast_pool_allocator<1024> >   fSymbolTable;
302                StackArray<XMLSymbol, 1024>                                     fSymbolArray;
303                XMLScannerType * const                                          fScanner;
304                XMLTranscoder *                                                 fTranscoder;
305};
306
307template <class XMLScannerType>
308void
309XMLSymbolResolver<XMLScannerType>::createNewSymbol(const gid_t gid, const uint8_t * rawSymbol, const uint32_t rawLength)
310{
311        /* --- we failed to find some symbol. create a new one --- */
312
313        XMLBuffer symbolBuf(rawLength + 1);
314        fTranscoder->transcodeFrom(rawSymbol, rawLength, symbolBuf);
315        const XMLCh * symbolName = symbolBuf.getRawBuffer();
316
317        if (fSymbolArray.capacity() < gid)
318        {
319                DEBUG_MESSAGE(" ## expanding new symbol capacity to " << (fSymbolArray.capacity() * 2));
320                // double the capacity of the current array
321                fSymbolArray.expand(fSymbolArray.capacity());
322        }
323
324        XMLSymbol * entry = &fSymbolArray[gid];
325
326        entry->fFlags = 0;
327        unsigned int uriId = fScanner->getEmptyNamespaceId();
328        if (fScanner->getDoNamespaces())
329        {
330                int colonInd;
331                uriId = fScanner->getUnknownNamespaceId();
332                if (!*symbolName)
333                {
334                        uriId = fScanner->getEmptyNamespaceId();
335                }
336                else if (XMLString::isXML(symbolName))
337                {
338                        uriId = fScanner->getXMLNamespaceId();
339                }
340                else if (XMLString::isXMLNS(symbolName, colonInd))
341                {
342                        uriId = (colonInd < 0)
343                                  ? fScanner->getEmptyNamespaceId()
344                                  : fScanner->getXMLNSNamespaceId();
345
346                        entry->fFlags |= XMLSymbol::XMLNS;
347                }
348        }
349
350        entry->fQName = new QName(symbolName, uriId, fScanner->getMemoryManager());
351        entry->fAttr = NULL;
352        entry->fElement = NULL;
353        #ifdef PRINT_DEBUG_MESSAGE
354        entry->fUTF8String = XMLString::toUTF8String(entry.fQName->getRawName());
355        #endif
356}
357
358XERCES_CPP_NAMESPACE_END
359
360#endif // XMLSYMBOLTABLEGROUPS_TEMPLATE_HPP
Note: See TracBrowser for help on using the repository browser.