19 using Lucene.Net.Documents;
20 using Lucene.Net.Search;
21 using Lucene.Net.Support;
24 namespace Lucene.Net.Util
75 public const int PRECISION_STEP_DEFAULT = 4;
80 public static char SHIFT_START_LONG = (char) 0x20;
87 public const int BUF_SIZE_LONG = 63 / 7 + 2;
92 public static char SHIFT_START_INT = (char) 0x60;
99 public const int BUF_SIZE_INT = 31 / 7 + 2;
113 public static int LongToPrefixCoded(
long val,
int shift,
char[] buffer)
115 if (shift > 63 || shift < 0)
116 throw new System.ArgumentException(
"Illegal shift value, must be 0..63");
117 int nChars = (63 - shift) / 7 + 1, len = nChars + 1;
118 buffer[0] = (char) (SHIFT_START_LONG + shift);
119 ulong sortableBits = BitConverter.ToUInt64(BitConverter.GetBytes(val), 0) ^ 0x8000000000000000L;
120 sortableBits = sortableBits >> shift;
126 buffer[nChars--] = (char) (sortableBits & 0x7f);
127 sortableBits = sortableBits >> 7;
139 public static System.String LongToPrefixCoded(
long val,
int shift)
141 char[] buffer =
new char[BUF_SIZE_LONG];
142 int len = LongToPrefixCoded(val, shift, buffer);
143 return new System.String(buffer, 0, len);
151 public static System.String LongToPrefixCoded(
long val)
153 return LongToPrefixCoded(val, 0);
168 public static int IntToPrefixCoded(
int val,
int shift,
char[] buffer)
170 if (shift > 31 || shift < 0)
171 throw new System.ArgumentException(
"Illegal shift value, must be 0..31");
172 int nChars = (31 - shift) / 7 + 1, len = nChars + 1;
173 buffer[0] = (char) (SHIFT_START_INT + shift);
174 int sortableBits = val ^ unchecked((
int) 0x80000000);
181 buffer[nChars--] = (char) (sortableBits & 0x7f);
194 public static System.String IntToPrefixCoded(
int val,
int shift)
196 char[] buffer =
new char[BUF_SIZE_INT];
197 int len = IntToPrefixCoded(val, shift, buffer);
198 return new System.String(buffer, 0, len);
206 public static System.String IntToPrefixCoded(
int val)
208 return IntToPrefixCoded(val, 0);
220 public static long PrefixCodedToLong(System.String prefixCoded)
222 int shift = prefixCoded[0] - SHIFT_START_LONG;
223 if (shift > 63 || shift < 0)
224 throw new System.FormatException(
"Invalid shift value in prefixCoded string (is encoded value really a LONG?)");
225 ulong sortableBits = 0UL;
226 for (
int i = 1, len = prefixCoded.Length; i < len; i++)
229 char ch = prefixCoded[i];
232 throw new System.FormatException(
"Invalid prefixCoded numerical value representation (char " + System.Convert.ToString((
int) ch, 16) +
" at position " + i +
" is invalid)");
234 sortableBits |= (ulong) ch;
236 return BitConverter.ToInt64(BitConverter.GetBytes((sortableBits << shift) ^ 0x8000000000000000L), 0);
248 public static int PrefixCodedToInt(System.String prefixCoded)
250 int shift = prefixCoded[0] - SHIFT_START_INT;
251 if (shift > 31 || shift < 0)
252 throw new System.FormatException(
"Invalid shift value in prefixCoded string (is encoded value really an INT?)");
253 int sortableBits = 0;
254 for (
int i = 1, len = prefixCoded.Length; i < len; i++)
257 char ch = prefixCoded[i];
260 throw new System.FormatException(
"Invalid prefixCoded numerical value representation (char " + System.Convert.ToString((
int) ch, 16) +
" at position " + i +
" is invalid)");
262 sortableBits |= (int) ch;
264 return (sortableBits << shift) ^ unchecked((
int) 0x80000000);
274 public static long DoubleToSortableLong(
double val)
276 long f = BitConverter.DoubleToInt64Bits(val);
278 f ^= 0x7fffffffffffffffL;
285 public static System.String DoubleToPrefixCoded(
double val)
287 return LongToPrefixCoded(DoubleToSortableLong(val));
293 public static double SortableLongToDouble(
long val)
296 val ^= 0x7fffffffffffffffL;
297 return BitConverter.Int64BitsToDouble(val);
303 public static double PrefixCodedToDouble(System.String val)
305 return SortableLongToDouble(PrefixCodedToLong(val));
315 public static int FloatToSortableInt(
float val)
317 int f = BitConverter.ToInt32(BitConverter.GetBytes(val), 0);
326 public static System.String FloatToPrefixCoded(
float val)
328 return IntToPrefixCoded(FloatToSortableInt(val));
334 public static float SortableIntToFloat(
int val)
338 return BitConverter.ToSingle(BitConverter.GetBytes(val), 0);
344 public static float PrefixCodedToFloat(System.String val)
346 return SortableIntToFloat(PrefixCodedToInt(val));
356 public static void SplitLongRange(
LongRangeBuilder builder,
int precisionStep,
long minBound,
long maxBound)
358 SplitRange(builder, 64, precisionStep, minBound, maxBound);
368 public static void SplitIntRange(
IntRangeBuilder builder,
int precisionStep,
int minBound,
int maxBound)
370 SplitRange(builder, 32, precisionStep, (
long) minBound, (
long) maxBound);
374 private static void SplitRange(System.Object builder,
int valSize,
int precisionStep,
long minBound,
long maxBound)
376 if (precisionStep < 1)
377 throw new System.ArgumentException(
"precisionStep must be >=1");
378 if (minBound > maxBound)
380 for (
int shift = 0; ; shift += precisionStep)
383 long diff = 1L << (shift + precisionStep);
384 long mask = ((1L << precisionStep) - 1L) << shift;
385 bool hasLower = (minBound & mask) != 0L;
386 bool hasUpper = (maxBound & mask) != mask;
387 long nextMinBound = (hasLower?(minBound + diff):minBound) & ~ mask;
388 long nextMaxBound = (hasUpper?(maxBound - diff):maxBound) & ~ mask;
389 bool lowerWrapped = nextMinBound < minBound,
390 upperWrapped = nextMaxBound > maxBound;
392 if (shift+precisionStep>=valSize || nextMinBound>nextMaxBound || lowerWrapped || upperWrapped)
395 AddRange(builder, valSize, minBound, maxBound, shift);
401 AddRange(builder, valSize, minBound, minBound | mask, shift);
403 AddRange(builder, valSize, maxBound & ~ mask, maxBound, shift);
406 minBound = nextMinBound;
407 maxBound = nextMaxBound;
412 private static void AddRange(System.Object builder,
int valSize,
long minBound,
long maxBound,
int shift)
418 maxBound |= (1L << shift) - 1L;
424 ((LongRangeBuilder) builder).AddRange(minBound, maxBound, shift);
428 ((IntRangeBuilder) builder).AddRange((
int) minBound, (
int) maxBound, shift);
433 throw new System.ArgumentException(
"valSize must be 32 or 64.");
449 public virtual void AddRange(System.String minPrefixCoded, System.String maxPrefixCoded)
451 throw new System.NotSupportedException();
457 public virtual void AddRange(
long min,
long max,
int shift)
459 AddRange(Lucene.Net.Util.NumericUtils.LongToPrefixCoded(min, shift), Lucene.Net.Util.NumericUtils.LongToPrefixCoded(max, shift));
474 public virtual void AddRange(System.String minPrefixCoded, System.String maxPrefixCoded)
476 throw new System.NotSupportedException();
482 public virtual void AddRange(
int min,
int max,
int shift)
484 AddRange(Lucene.Net.Util.NumericUtils.IntToPrefixCoded(min, shift), Lucene.Net.Util.NumericUtils.IntToPrefixCoded(max, shift));