KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > utilint > Adler32


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: Adler32.java,v 1.10 2006/10/30 21:14:28 bostic Exp $
7  */

8
9 package com.sleepycat.je.utilint;
10
11 import java.util.zip.Checksum JavaDoc;
12
13 import com.sleepycat.je.dbi.EnvironmentImpl;
14
15 /**
16  * Adler32 checksum implementation.
17  *
18  * This class is used rather than the native java.util.zip.Adler32 class
19  * because we have seen a JIT problem when calling the Adler32 class using
20  * the Server JVM on Linux and Solaris. Specifically, we suspect this may
21  * be Bug Parade number 4965907. See SR [#9376]. We also believe that this
22  * bug is fixed in Java 5 and therefore only use this class conditionally
23  * if we find that we're in a 1.4 JVM. [#13354].
24  *
25  * The Adler32 checksum is discussed in RFC1950. The sample implementation
26  * from this RFC is shown below:
27  *
28  * <pre>
29  * #define BASE 65521 largest prime smaller than 65536
30  * unsigned long update_adler32(unsigned long adler,
31  * unsigned char *buf, int len)
32  * {
33  * unsigned long s1 = adler & 0xffff;
34  * unsigned long s2 = (adler >> 16) & 0xffff;
35  * int n;
36  *
37  * for (n = 0; n < len; n++) {
38  * s1 = (s1 + buf[n]) % BASE;
39  * s2 = (s2 + s1) % BASE;
40  * }
41  * return (s2 << 16) + s1;
42  * }
43  *
44  * unsigned long adler32(unsigned char *buf, int len)
45  * {
46  * return update_adler32(1L, buf, len);
47  * }
48  * </pre>
49  *
50  * The NMAX optimization is so that we don't have to do modulo calculations
51  * on every iteration. NMAX is the max number of additions to make
52  * before you have to perform the modulo calculation.
53  */

54 public class Adler32 implements Checksum JavaDoc {
55
56     /* This class and the ctor are public for the unit tests. */
57     public static class ChunkingAdler32 extends java.util.zip.Adler32 JavaDoc {
58     int adler32ChunkSize = 0;
59
60     public ChunkingAdler32(int adler32ChunkSize) {
61         this.adler32ChunkSize = adler32ChunkSize;
62     }
63
64     public void update(byte[] b, int off, int len) {
65         if (len < adler32ChunkSize) {
66         super.update(b, off, len);
67         return;
68         }
69
70         int i = 0;
71         while (i < len) {
72         int bytesRemaining = len - i;
73         int nBytesThisChunk =
74             Math.min(bytesRemaining, adler32ChunkSize);
75         super.update(b, off + i, nBytesThisChunk);
76         i += nBytesThisChunk;
77         }
78     }
79     }
80
81     public static Checksum JavaDoc makeChecksum() {
82     if (EnvironmentImpl.JAVA5_AVAILABLE) {
83         int adler32ChunkSize = EnvironmentImpl.getAdler32ChunkSize();
84         if (adler32ChunkSize > 0) {
85         return new ChunkingAdler32(adler32ChunkSize);
86         } else {
87         return new java.util.zip.Adler32 JavaDoc();
88         }
89     } else {
90         return new Adler32();
91     }
92     }
93
94     private long adler = 1;
95
96     /*
97      * BASE is the largest prime number smaller than 65536
98      * NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1
99      */

100     private static final int BASE = 65521;
101     private static final int NMAX = 5552;
102
103     /**
104      * Update current Adler-32 checksum given the specified byte.
105      */

106     public void update(int b) {
107         long s1 = adler & 0xffff;
108         long s2 = (adler >> 16) & 0xffff;
109         s1 = (s1 + (b & 0xff)) % BASE;
110         s2 = (s1 + s2) % BASE;
111         adler = (s2 << 16) | s1;
112     }
113
114     /**
115      * Update current Adler-32 checksum given the specified byte array.
116      */

117     public void update(byte[] b, int off, int len) {
118         long s1 = adler & 0xffff;
119         long s2 = (adler >> 16) & 0xffff;
120
121         while (len > 0) {
122             int k = len < NMAX ? len : NMAX;
123             len -= k;
124
125         /* This does not benefit from loop unrolling. */
126             while (k-- > 0) {
127                 s1 += (b[off++] & 0xff);
128                 s2 += s1;
129             }
130
131             s1 %= BASE;
132             s2 %= BASE;
133         }
134         adler = (s2 << 16) | s1;
135     }
136
137     /**
138      * Reset Adler-32 checksum to initial value.
139      */

140     public void reset() {
141         adler = 1;
142     }
143
144     /**
145      * Returns current checksum value.
146      */

147     public long getValue() {
148         return adler;
149     }
150 }
151
Popular Tags