1919
2020package org .elasticsearch .index .mapper ;
2121
22+ import org .apache .lucene .document .InetAddressPoint ;
23+ import org .apache .lucene .store .ByteArrayDataInput ;
2224import org .apache .lucene .store .ByteArrayDataOutput ;
2325import org .apache .lucene .util .BytesRef ;
2426import org .apache .lucene .util .NumericUtils ;
27+ import org .elasticsearch .common .TriFunction ;
2528
2629import java .io .IOException ;
30+ import java .net .InetAddress ;
2731import java .util .ArrayList ;
32+ import java .util .Arrays ;
2833import java .util .Comparator ;
2934import java .util .List ;
3035import java .util .Set ;
@@ -33,6 +38,32 @@ enum BinaryRangeUtil {
3338
3439 ;
3540
41+ static BytesRef encodeIPRanges (Set <RangeFieldMapper .Range > ranges ) throws IOException {
42+ final byte [] encoded = new byte [5 + (16 * 2 ) * ranges .size ()];
43+ ByteArrayDataOutput out = new ByteArrayDataOutput (encoded );
44+ out .writeVInt (ranges .size ());
45+ for (RangeFieldMapper .Range range : ranges ) {
46+ InetAddress fromValue = (InetAddress ) range .from ;
47+ byte [] encodedFromValue = InetAddressPoint .encode (fromValue );
48+ out .writeBytes (encodedFromValue , 0 , encodedFromValue .length );
49+
50+ InetAddress toValue = (InetAddress ) range .to ;
51+ byte [] encodedToValue = InetAddressPoint .encode (toValue );
52+ out .writeBytes (encodedToValue , 0 , encodedToValue .length );
53+ }
54+ return new BytesRef (encoded , 0 , out .getPosition ());
55+ }
56+
57+ static List <RangeFieldMapper .Range > decodeIPRanges (BytesRef encodedRanges ) {
58+ return decodeRanges (encodedRanges , RangeType .IP , BinaryRangeUtil ::decodeIP );
59+ }
60+
61+ private static InetAddress decodeIP (byte [] bytes , int offset , int length ) {
62+ // offset + length because copyOfRange wants a from and a to, not an offset & length
63+ byte [] slice = Arrays .copyOfRange (bytes , offset , offset + length );
64+ return InetAddressPoint .decode (slice );
65+ }
66+
3667 static BytesRef encodeLongRanges (Set <RangeFieldMapper .Range > ranges ) throws IOException {
3768 List <RangeFieldMapper .Range > sortedRanges = new ArrayList <>(ranges );
3869 Comparator <RangeFieldMapper .Range > fromComparator = Comparator .comparingLong (range -> ((Number ) range .from ).longValue ());
@@ -51,6 +82,11 @@ static BytesRef encodeLongRanges(Set<RangeFieldMapper.Range> ranges) throws IOEx
5182 return new BytesRef (encoded , 0 , out .getPosition ());
5283 }
5384
85+ static List <RangeFieldMapper .Range > decodeLongRanges (BytesRef encodedRanges ) {
86+ return decodeRanges (encodedRanges , RangeType .LONG ,
87+ BinaryRangeUtil ::decodeLong );
88+ }
89+
5490 static BytesRef encodeDoubleRanges (Set <RangeFieldMapper .Range > ranges ) throws IOException {
5591 List <RangeFieldMapper .Range > sortedRanges = new ArrayList <>(ranges );
5692 Comparator <RangeFieldMapper .Range > fromComparator = Comparator .comparingDouble (range -> ((Number ) range .from ).doubleValue ());
@@ -69,6 +105,43 @@ static BytesRef encodeDoubleRanges(Set<RangeFieldMapper.Range> ranges) throws IO
69105 return new BytesRef (encoded , 0 , out .getPosition ());
70106 }
71107
108+ static List <RangeFieldMapper .Range > decodeDoubleRanges (BytesRef encodedRanges ) {
109+ return decodeRanges (encodedRanges , RangeType .DOUBLE ,
110+ BinaryRangeUtil ::decodeDouble );
111+ }
112+
113+ static List <RangeFieldMapper .Range > decodeFloatRanges (BytesRef encodedRanges ) {
114+ return decodeRanges (encodedRanges , RangeType .FLOAT ,
115+ BinaryRangeUtil ::decodeFloat );
116+ }
117+
118+ static List <RangeFieldMapper .Range > decodeRanges (BytesRef encodedRanges , RangeType rangeType ,
119+ TriFunction <byte [], Integer , Integer , Object > decodeBytes ) {
120+
121+ RangeType .LengthType lengthType = rangeType .lengthType ;
122+ ByteArrayDataInput in = new ByteArrayDataInput ();
123+ in .reset (encodedRanges .bytes , encodedRanges .offset , encodedRanges .length );
124+ int numRanges = in .readVInt ();
125+
126+ List <RangeFieldMapper .Range > ranges = new ArrayList <>(numRanges );
127+
128+ final byte [] bytes = encodedRanges .bytes ;
129+ int offset = in .getPosition ();
130+ for (int i = 0 ; i < numRanges ; i ++) {
131+ int length = lengthType .readLength (bytes , offset );
132+ Object from = decodeBytes .apply (bytes , offset , length );
133+ offset += length ;
134+
135+ length = lengthType .readLength (bytes , offset );
136+ Object to = decodeBytes .apply (bytes , offset , length );
137+ offset += length ;
138+ // TODO: Support for exclusive ranges, pending resolution of #40601
139+ RangeFieldMapper .Range decodedRange = new RangeFieldMapper .Range (rangeType , from , to , true , true );
140+ ranges .add (decodedRange );
141+ }
142+ return ranges ;
143+ }
144+
72145 static BytesRef encodeFloatRanges (Set <RangeFieldMapper .Range > ranges ) throws IOException {
73146 List <RangeFieldMapper .Range > sortedRanges = new ArrayList <>(ranges );
74147 Comparator <RangeFieldMapper .Range > fromComparator = Comparator .comparingDouble (range -> ((Number ) range .from ).floatValue ());
@@ -93,12 +166,20 @@ static byte[] encodeDouble(double number) {
93166 return encoded ;
94167 }
95168
169+ static double decodeDouble (byte [] bytes , int offset , int length ){
170+ return NumericUtils .sortableLongToDouble (NumericUtils .sortableBytesToLong (bytes , offset ));
171+ }
172+
96173 static byte [] encodeFloat (float number ) {
97174 byte [] encoded = new byte [4 ];
98175 NumericUtils .intToSortableBytes (NumericUtils .floatToSortableInt (number ), encoded , 0 );
99176 return encoded ;
100177 }
101178
179+ static float decodeFloat (byte [] bytes , int offset , int length ) {
180+ return NumericUtils .sortableIntToFloat (NumericUtils .sortableBytesToInt (bytes , offset ));
181+ }
182+
102183 /**
103184 * Encodes the specified number of type long in a variable-length byte format.
104185 * The byte format preserves ordering, which means the returned byte array can be used for comparing as is.
@@ -114,6 +195,23 @@ static byte[] encodeLong(long number) {
114195 return encode (number , sign );
115196 }
116197
198+ static long decodeLong (byte [] bytes , int offset , int length ) {
199+ boolean isNegative = (bytes [offset ] & 128 ) == 0 ;
200+ // Start by masking off the last three bits of the first byte - that's the start of our number
201+ long decoded ;
202+ if (isNegative ) {
203+ decoded = -8 | bytes [offset ];
204+ } else {
205+ decoded = bytes [offset ] & 7 ;
206+ }
207+ for (int i = 1 ; i < length ; i ++) {
208+ decoded <<= 8 ;
209+ decoded += Byte .toUnsignedInt (bytes [offset + i ]);
210+ }
211+
212+ return decoded ;
213+ }
214+
117215 private static byte [] encode (long l , int sign ) {
118216 assert l >= 0 ;
119217
@@ -158,4 +256,5 @@ private static byte[] encode(long l, int sign) {
158256 }
159257 return encoded ;
160258 }
259+
161260}
0 commit comments