001: // kelondroNaturalOrder.java
002: // -----------------------
003: // part of The Kelondro Database
004: // (C) by Michael Peter Christen; mc@anomic.de
005: // first published on http://www.anomic.de
006: // Frankfurt, Germany, 2005
007: // created 29.12.2005
008: //
009: // $LastChangedDate: 2005-09-22 22:01:26 +0200 (Thu, 22 Sep 2005) $
010: // $LastChangedRevision: 774 $
011: // $LastChangedBy: orbiter $
012: //
013: // This program is free software; you can redistribute it and/or modify
014: // it under the terms of the GNU General Public License as published by
015: // the Free Software Foundation; either version 2 of the License, or
016: // (at your option) any later version.
017: //
018: // This program is distributed in the hope that it will be useful,
019: // but WITHOUT ANY WARRANTY; without even the implied warranty of
020: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
021: // GNU General Public License for more details.
022: //
023: // You should have received a copy of the GNU General Public License
024: // along with this program; if not, write to the Free Software
025: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
026: //
027: // Using this software in any meaning (reading, learning, copying, compiling,
028: // running) means that you agree that the Author(s) is (are) not responsible
029: // for cost, loss of data or any harm that may be caused directly or indirectly
030: // by usage of this softare or this documentation. The usage of this software
031: // is on your own risk. The installation and usage (starting/running) of this
032: // software may allow other people or application to access your computer and
033: // any attached devices and is highly dependent on the configuration of the
034: // software which must be done by the user of the software; the author(s) is
035: // (are) also not responsible for proper configuration and usage of the
036: // software, even if provoked by documentation provided together with
037: // the software.
038: //
039: // Any changes to this file according to the GPL as documented in the file
040: // gpl.txt aside this file in the shipment you received can be done to the
041: // lines that follows this copyright notice here, but changes must not be
042: // done inside the copyright notive above. A re-distribution must contain
043: // the intact and unchanged copyright notice.
044: // Contributions and changes to the program code must be marked as such.
045:
046: package de.anomic.kelondro;
047:
048: import java.util.Comparator;
049:
050: public final class kelondroNaturalOrder extends
051: kelondroAbstractOrder<byte[]> implements kelondroByteOrder,
052: Comparator<byte[]>, Cloneable {
053:
054: public static final kelondroByteOrder naturalOrder = new kelondroNaturalOrder(
055: true);
056: public static final Comparator<String> naturalComparator = new kelondroByteOrder.StringOrder(
057: naturalOrder);
058:
059: public kelondroNaturalOrder(boolean ascending) {
060: this .asc = ascending;
061: this .zero = null;
062: }
063:
064: public boolean wellformed(byte[] a) {
065: return true;
066: }
067:
068: public boolean wellformed(byte[] a, int astart, int alength) {
069: return true;
070: }
071:
072: public final kelondroOrder<byte[]> clone() {
073: kelondroNaturalOrder o = new kelondroNaturalOrder(this .asc);
074: o.rotate(this .zero);
075: return o;
076: }
077:
078: public final static kelondroByteOrder bySignature(String signature) {
079: if (signature.equals("nd"))
080: return new kelondroNaturalOrder(false);
081: if (signature.equals("nu"))
082: return new kelondroNaturalOrder(true);
083: return null;
084: }
085:
086: public final String signature() {
087: if (!asc)
088: return "nd";
089: if (asc)
090: return "nu";
091: return null;
092: }
093:
094: private final static long cardinalI(byte[] key) {
095: // returns a cardinal number in the range of 0 .. Long.MAX_VALUE
096: long c = 0;
097: int p = 0;
098: while ((p < 8) && (p < key.length))
099: c = (c << 8) | ((long) key[p++] & 0xFF);
100: while (p++ < 8)
101: c = (c << 8);
102: c = c >>> 1;
103: return c;
104: }
105:
106: public final long cardinal(byte[] key) {
107: if (this .zero == null)
108: return cardinalI(key);
109: long zeroCardinal = cardinalI(this .zero);
110: long keyCardinal = cardinalI(key);
111: if (keyCardinal > zeroCardinal)
112: return keyCardinal - zeroCardinal;
113: return Long.MAX_VALUE - keyCardinal + zeroCardinal;
114: }
115:
116: public final static byte[] encodeLong(long c, int length) {
117: byte[] b = new byte[length];
118: while (length > 0) {
119: b[--length] = (byte) (c & 0xFF);
120: c >>= 8;
121: }
122: return b;
123: }
124:
125: public final static void encodeLong(long c, byte[] b, int offset,
126: int length) {
127: assert offset + length <= b.length;
128: while (length > 0) {
129: b[--length + offset] = (byte) (c & 0xFF);
130: c >>= 8;
131: }
132: }
133:
134: public final static long decodeLong(byte[] s) {
135: if (s == null)
136: return 0;
137: long c = 0;
138: int p = 0;
139: while (p < s.length)
140: c = (c << 8) | ((long) s[p++] & 0xFF);
141: return c;
142: }
143:
144: public final static long decodeLong(byte[] s, int offset, int length) {
145: if (s == null)
146: return 0;
147: long c = 0;
148: final int m = Math.min(s.length, offset + length);
149: while (offset < m)
150: c = (c << 8) | ((long) s[offset++] & 0xFF);
151: return c;
152: }
153:
154: private static final int sig(int x) {
155: return (x > 0) ? 1 : (x < 0) ? -1 : 0;
156: }
157:
158: // Compares its two arguments for order.
159: // Returns -1, 0, or 1 as the first argument
160: // is less than, equal to, or greater than the second.
161: // two arrays are also equal if one array is a subset of the other's array
162: // with filled-up char(0)-values
163: public final int compare(byte[] a, byte[] b) {
164: return (asc) ? compare0(a, 0, a.length, b, 0, b.length)
165: : compare0(b, 0, b.length, a, 0, a.length);
166: }
167:
168: public final int compare(byte[] a, int aoffset, int alength,
169: byte[] b, int boffset, int blength) {
170: return (asc) ? compare0(a, aoffset, alength, b, boffset,
171: blength) : compare0(b, boffset, blength, a, aoffset,
172: alength);
173: }
174:
175: public final int compare0(byte[] a, int aoffset, int alength,
176: byte[] b, int boffset, int blength) {
177: if (zero == null)
178: return compares(a, aoffset, alength, b, boffset, blength);
179: // we have an artificial start point. check all combinations
180: final int az = compares(a, aoffset, alength, zero, 0,
181: zero.length); // -1 if a < z; 0 if a == z; 1 if a > z
182: final int bz = compares(b, boffset, blength, zero, 0,
183: zero.length); // -1 if b < z; 0 if b == z; 1 if b > z
184: if (az == bz)
185: return compares(a, aoffset, alength, b, boffset, blength);
186: return sig(az - bz);
187: }
188:
189: public static final boolean equal(byte[] a, byte[] b) {
190: if ((a == null) && (b == null))
191: return true;
192: if ((a == null) || (b == null))
193: return false;
194: return compares(a, 0, a.length, b, 0, b.length) == 0;
195: }
196:
197: public static final int compares(byte[] a, int aoffset,
198: int alength, byte[] b, int boffset, int blength) {
199: int i = 0;
200: final int al = Math.min(alength, a.length - aoffset);
201: final int bl = Math.min(blength, b.length - boffset);
202: int aa, bb;
203: while ((i < al) && (i < bl)) {
204: aa = 0xff & (int) a[i + aoffset];
205: bb = 0xff & (int) b[i + boffset];
206: if (aa > bb)
207: return 1;
208: if (aa < bb)
209: return -1;
210: // else the bytes are equal and it may go on yet undecided
211: i++;
212: }
213: // compare length
214: if (al > bl)
215: return 1;
216: if (al < bl)
217: return -1;
218: // they are equal
219: return 0;
220: }
221:
222: public static void main(String[] args) {
223: byte[] t = new byte[12];
224: for (int i = 0; i < 12; i++)
225: t[i] = (byte) 255;
226: t[0] = (byte) 127;
227: kelondroOrder<byte[]> o = new kelondroNaturalOrder(true);
228: System.out.println(o.partition(t, 16));
229: }
230:
231: }
|