add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / facet / src / java / org / apache / lucene / util / encoding / package.html
1 <html>
2 <head>
3 <title>Encoding</title>
4 </head>
5 <body>
6 Offers various encoders and decoders for integers, as well as the
7 mechanisms to create new ones. The super class for all encoders is
8 {@link org.apache.lucene.util.encoding.IntEncoder} and for most of the
9 encoders there is a matching {@link
10 org.apache.lucene.util.encoding.IntDecoder} implementation (not all
11 encoders need a decoder).
12 <p>An encoder encodes the integers that are passed to {@link
13 org.apache.lucene.util.encoding.IntEncoder#encode(int) encode} into a
14 set output stream (see {@link
15 org.apache.lucene.util.encoding.IntEncoder#reInit(OutputStream)
16 reInit}). One should always call {@link
17 org.apache.lucene.util.encoding.IntEncoder#close() close} when all
18 integers have been encoded, to ensure proper finish by the encoder. Some
19 encoders buffer values in-memory and encode in batches in order to
20 optimize the encoding, and not closing them may result in loss of
21 information or corrupt stream.
22 <p>A proper and typical usage of an encoder looks like this:
23 <blockquote><pre><code>
24 int[] data = &lt;the values to encode&gt;
25 IntEncoder encoder = new VInt8IntEncoder();
26 OutputStream out = new ByteArrayOutputStream();
27 encoder.reInit(out);
28 for (int val : data) {
29   encoder.encode(val);
30 }
31 encoder.close();
32
33 // Print the bytes in binary
34 byte[] bytes = out.toByteArray();
35 for (byte b : bytes) {
36   System.out.println(Integer.toBinaryString(b));
37 }
38 </code></pre></blockquote>
39 Each encoder also implements {@link
40 org.apache.lucene.util.encoding.IntEncoder#createMatchingDecoder()
41 createMatchingDecoder} which returns the matching decoder for this encoder.
42 As mentioned above, not all encoders have a matching decoder (like some
43 encoder filters which are explained next), however every encoder should
44 return a decoder following a call to that method. To complete the
45 example above, one can easily iterate over the decoded values like this:
46 <blockquote><pre><code>
47 IntDecoder d = e.createMatchingDecoder();
48 d.reInit(new ByteArrayInputStream(bytes));
49 long val;
50 while ((val = d.decode()) != IntDecoder.EOS) {
51   System.out.println(val);
52 }
53 </code></pre></blockquote>
54 <p>Some encoders don't perform any encoding at all, or do not include an
55 encoding logic. Those are called {@link
56 org.apache.lucene.util.encoding.IntEncoderFilter}s. A filter is an
57 encoder which delegates the encoding task to a given encoder, however
58 performs additional logic before the values are sent for encoding. An
59 example is {@link org.apache.lucene.util.encoding.DGapIntEncoder}
60 which encodes the gaps between values rather than the values themselves.
61 Another example is {@link
62 org.apache.lucene.util.encoding.SortingIntEncoder} which sorts all the
63 values in ascending order before they are sent for encoding. This
64 encoder aggregates the values in its {@link
65 org.apache.lucene.util.encoding.IntEncoder#encode(int) encode} implementation 
66 and decoding only happens upon calling {@link
67 org.apache.lucene.util.encoding.IntEncoder#close() close}.
68 <h4>Extending IntEncoder</h4>
69 Extending {@link org.apache.lucene.util.encoding.IntEncoder} is a very
70 easy task. One only needs to implement {@link
71 org.apache.lucene.util.encoding.IntEncoder#encode(int) encode} and
72 {@link org.apache.lucene.util.encoding.IntEncoder#createMatchingDecoder()
73 createMatchingDecoder} as the base implementation takes care of
74 re-initializing the output stream and closing it. The following example
75 illustrates how can one write an encoder (and a matching decoder) which
76 'tags' the stream with type/ID of the encoder. Such tagging is important
77 in scenarios where an application uses different encoders for different
78 streams, and wants to manage some sort of mapping between an encoder ID
79 to an IntEncoder/Decoder implementation, so a proper decoder will be
80 initialized on the fly:
81 <blockquote><pre><code>
82 public class TaggingIntEncoder extends IntEncoderFilter {
83   
84   public TaggingIntEncoder(IntEncoder encoder) {
85     super(encoder);
86   }
87   
88   &#64;Override
89   public void encode(int value) throws IOException {
90     encoder.encode(value);
91   }
92
93   &#64;Override
94   public IntDecoder createMatchingDecoder() {
95     return new TaggingIntDecoder();
96   }
97         
98   &#64;Override
99   public void reInit(OutputStream out) {
100     super.reInit(os);
101     // Assumes the application has a static EncodersMap class which is able to 
102     // return a unique ID for a given encoder.
103     int encoderID = EncodersMap.getID(encoder);
104     this.out.write(encoderID);
105   }
106
107   &#64;Override
108   public String toString() {
109     return "Tagging (" + encoder.toString() + ")";
110   }
111
112 }
113 </code></pre></blockquote>
114 And the matching decoder:
115 <blockquote><pre><code>
116 public class TaggingIntDecoder extends IntDecoder {
117   
118   // Will be initialized upon calling reInit.
119   private IntDecoder decoder;
120   
121   &#64;Override
122   public void reInit(InputStream in) {
123     super.reInit(in);
124     
125     // Read the ID of the encoder that tagged this stream.
126     int encoderID = in.read();
127     
128     // Assumes EncodersMap can return the proper IntEncoder given the ID.
129     decoder = EncodersMap.getEncoder(encoderID).createMatchingDecoder();
130   }
131         
132   &#64;Override
133   public long decode() throws IOException {
134     return decoder.decode();
135   }
136
137   &#64;Override
138   public String toString() {
139     return "Tagging (" + decoder == null ? "none" : decoder.toString() + ")";
140   }
141
142 }
143 </code></pre></blockquote>
144 The example implements <code>TaggingIntEncoder</code> as a filter over another 
145 encoder. Even though it does not do any filtering on the actual values, it feels 
146 right to present it as a filter. Anyway, this is just an example code and one 
147 can choose to implement it however it makes sense to the application. For 
148 simplicity, error checking was omitted from the sample code.
149 </body>
150 </html>