mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-16 19:48:18 +00:00
115 lines
3.8 KiB
Java
115 lines
3.8 KiB
Java
|
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||
|
*
|
||
|
* The contents of this file are subject to the Mozilla Public License
|
||
|
* Version 1.0 (the "License"); you may not use this file except in
|
||
|
* compliance with the License. You may obtain a copy of the License at
|
||
|
* http://www.mozilla.org/MPL/
|
||
|
*
|
||
|
* Software distributed under the License is distributed on an "AS IS"
|
||
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||
|
* the License for the specific language governing rights and limitations
|
||
|
* under the License.
|
||
|
*
|
||
|
* The Original Code is the Grendel mail/news client.
|
||
|
*
|
||
|
* The Initial Developer of the Original Code is Netscape Communications
|
||
|
* Corporation. Portions created by Netscape are Copyright (C) 1997
|
||
|
* Netscape Communications Corporation. All Rights Reserved.
|
||
|
*
|
||
|
* Created: Jamie Zawinski <jwz@netscape.com>, 19 Sep 1997.
|
||
|
*/
|
||
|
|
||
|
package grendel.storage;
|
||
|
|
||
|
/** This class represents a Message-ID.
|
||
|
It does not contain the ID itself: there is no way to reconstruct the
|
||
|
original string from this object; however, it contains a hash of that
|
||
|
string which should be sufficiently unique so that the odds of a
|
||
|
collision are 1 in 2^32 (since it is a 64-bit hash.)
|
||
|
<P>
|
||
|
We store the hash instead of the original string because it takes up
|
||
|
<I>significantly</I> less memory, and in order to do threading, we
|
||
|
tend to need a huge number of Message-IDs in memory at once.
|
||
|
|
||
|
@see MessageIDTable
|
||
|
*/
|
||
|
|
||
|
class MessageID {
|
||
|
|
||
|
long hash; // not protected for the benfit of a MessageIDTable kludge.
|
||
|
|
||
|
// String debug_id_string;
|
||
|
|
||
|
|
||
|
/** Constructs a MessageID object with a null hash. */
|
||
|
MessageID() {
|
||
|
}
|
||
|
|
||
|
/** Constructs a MessageID object with the given hash. */
|
||
|
MessageID(long hash) {
|
||
|
this.hash = hash;
|
||
|
}
|
||
|
|
||
|
/** Constructs a MessageID object for the given sub-sequence of bytes.
|
||
|
A pointer to the bytes is not retained.
|
||
|
*/
|
||
|
MessageID(byte bytes[], int start, int length) {
|
||
|
hash = hashBytes(bytes, start, length);
|
||
|
// debug_id_string = new String(bytes, start, length);
|
||
|
}
|
||
|
|
||
|
MessageID(String chars) {
|
||
|
byte bytes[] = chars.getBytes();
|
||
|
hash = hashBytes(bytes, 0, bytes.length);
|
||
|
// debug_id_string = chars;
|
||
|
}
|
||
|
|
||
|
/** Converts it to a string, for debugging. */
|
||
|
public String toString() {
|
||
|
return "<" + this.getClass() + " hash=" + Long.toHexString(hash) +
|
||
|
// " string=" + debug_id_string +
|
||
|
">";
|
||
|
}
|
||
|
|
||
|
public int hashCode() {
|
||
|
// Note that this is a 32-bit hash, not the 64-bit internal hash;
|
||
|
// it's good enough for hash tables, but not for equality checks.
|
||
|
return (int) ((hash >> 32) ^ (hash & 0xFFFFFFFF));
|
||
|
}
|
||
|
|
||
|
public boolean equals(Object x) {
|
||
|
if (x instanceof MessageID)
|
||
|
return (hash == ((MessageID) x).hash);
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/** Computes a 64-bit hash of the given subsequence of bytes.
|
||
|
<P>
|
||
|
Note: this hash value is written out to mail summary files by the
|
||
|
MailSummaryFileGrendel class. If the hash algorithm is changed,
|
||
|
it will invalidate all existing mail summary files, and necessitate
|
||
|
a change of the file format version number.
|
||
|
@see MailSummaryFileGrendel
|
||
|
*/
|
||
|
protected long hashBytes(byte bytes[], int start, int length) {
|
||
|
long h = 0;
|
||
|
int end = start + length;
|
||
|
int i = start;
|
||
|
|
||
|
// Just in case, don't count a leading < or trailing > in the hash.
|
||
|
// All callers should strip those first, but be safe...
|
||
|
while (i < end && (bytes[i] == '<' || bytes[i] <= ' ')) i++;
|
||
|
while (end > i && (bytes[end-1] == '>' || bytes[end-1] <= ' ')) end--;
|
||
|
|
||
|
while (i < end) {
|
||
|
long hh = 0;
|
||
|
for (int j = 0; i < end && j < 16; j++) {
|
||
|
hh = (hh * 37) + bytes[i++]; // the guts of String.hashCode().
|
||
|
}
|
||
|
h = (h << 8) ^ hh; // fill in high-high-order bits too.
|
||
|
}
|
||
|
return h;
|
||
|
}
|
||
|
}
|