11package org .threeten .bp .zone
22
33import java .util
4- import java .util .{Collection => JCollection , Map => JMap , Set => JSet }
4+ import java .util .{Collection => JCollection , Map => JMap , SortedMap => JSortedMap , Set => JSet }
55import java .util .AbstractMap
66import java .util .AbstractMap .SimpleEntry
77import java .util .Comparator
88
99import scala .reflect .ClassTag
1010import scala .collection .JavaConverters ._
11+ import scala .collection .immutable
1112
1213// TreeMap is not available in Scala.js however it is needed for Time Zone support
13- // This is a simple implementation of NavigableMap
14- private [zone] class ZoneMap [K : ClassTag , V ](implicit ordering : Ordering [K ]) extends AbstractMap [K , V ] with java.util.NavigableMap [K , V ] {
15- // Use an immutable TreeMap and replace it completely on updates
16- private var map = scala.collection.immutable.TreeMap [K , V ]()
17-
18- override def descendingMap () = ???
14+ // This is a simple implementation of NavigableMap, performance is likely terrible
15+ private [bp] class ZoneMap [K : ClassTag , V ] private [bp] (var map : immutable.TreeMap [K , V ])(implicit ordering : Ordering [K ]) extends AbstractMap [K , V ] with java.util.NavigableMap [K , V ] {
16+ def this ()(implicit ordering : Ordering [K ]) =
17+ this (immutable.TreeMap [K , V ]())
18+
19+ override def descendingMap (): java.util.NavigableMap [K , V ] = {
20+ val ord = ordering.reverse
21+ new ZoneMap [K , V ](map)
22+ }
1923
2024 override def firstEntry (): java.util.Map .Entry [K , V ] = {
2125 val fk = firstKey()
22- map.get(fk).map(new SimpleEntry (firstKey() , _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
26+ map.get(fk).map(new SimpleEntry (fk , _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
2327 }
2428
25- override def navigableKeySet () = ???
29+ override def higherEntry (key : K ): java.util.Map .Entry [K , V ] = {
30+ val k = map.filterKeys(x => ordering.compare(x, key) > 0 )
31+ if (k.isEmpty) null .asInstanceOf [java.util.Map .Entry [K , V ]] else new SimpleEntry (k.head._1, k.head._2)
32+ }
2633
27- override def subMap (fromKey : K , fromInclusive : Boolean , toKey : K , toInclusive : Boolean ) = ???
34+ override def ceilingEntry (key : K ): java.util.Map .Entry [K , V ] = {
35+ val k = map.filterKeys(x => ordering.compare(x, key) >= 0 )
36+ if (k.isEmpty) null .asInstanceOf [java.util.Map .Entry [K , V ]] else new SimpleEntry (k.head._1, k.head._2)
37+ }
2838
29- override def subMap (fromKey : K , toKey : K ) = ???
39+ override def pollFirstEntry (): java.util.Map .Entry [K , V ] = {
40+ val fk = firstKey()
41+ val entry = map.get(fk).map(new SimpleEntry (fk, _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
42+ map -= fk
43+ entry
44+ }
3045
31- override def headMap (toKey : K , inclusive : Boolean ) = ???
46+ override def floorEntry (key : K ): java.util.Map .Entry [K , V ] = {
47+ val k = map.filterKeys(x => ordering.compare(x, key) <= 0 )
48+ if (k.isEmpty) null .asInstanceOf [java.util.Map .Entry [K , V ]] else new SimpleEntry (k.last._1, k.last._2)
49+ }
3250
33- override def headMap (toKey : K ) = ???
51+ override def lowerEntry (key : K ): java.util.Map .Entry [K , V ] = {
52+ val k = map.filterKeys(x => ordering.compare(x, key) < 0 )
53+ if (k.isEmpty) null .asInstanceOf [java.util.Map .Entry [K , V ]] else new SimpleEntry (k.last._1, k.last._2)
54+ }
3455
35- override def ceilingKey (key : K ) = ???
56+ override def pollLastEntry (): java.util.Map .Entry [K , V ] = {
57+ val lk = lastKey()
58+ val entry = map.get(lk).map(new SimpleEntry (lk, _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
59+ map -= lk
60+ entry
61+ }
3662
37- override def higherEntry (key : K ) = ???
63+ override def lastEntry (): java.util.Map .Entry [K , V ] = {
64+ val lk = lastKey()
65+ map.get(lk).map(new SimpleEntry (lk, _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
66+ }
3867
39- override def ceilingEntry (key : K ) = ???
68+ // Will not be implemented. It needs NavigableSet
69+ override def navigableKeySet () = ???
4070
41- override def pollFirstEntry () = ???
71+ override def subMap (fromKey : K , fromInclusive : Boolean , toKey : K , toInclusive : Boolean ) = {
72+ val hk = if (toInclusive) map.filterKeys(x => ordering.compare(x, toKey) <= 0 ) else
73+ map.filterKeys(x => ordering.compare(x, toKey) < 0 )
74+ val fk = if (fromInclusive) map.filterKeys(x => ordering.compare(x, fromKey) >= 0 ) else
75+ map.filterKeys(x => ordering.compare(x, fromKey) > 0 )
76+ val intersect = hk.keySet.intersect(fk.keySet).map(k => k -> hk.get(k).getOrElse(fk(k))).toMap
77+ new ZoneMap (immutable.TreeMap (intersect.toSeq: _* ))
78+ }
4279
43- override def floorKey ( key : K ) = ???
80+ override def subMap ( fromKey : K , toKey : K ) = subMap(fromKey, true , toKey, false )
4481
45- override def floorEntry (key : K ) = ???
82+ override def headMap (toKey : K , inclusive : Boolean ): java.util.NavigableMap [K , V ] = {
83+ val k = if (inclusive) map.filterKeys(x => ordering.compare(x, toKey) <= 0 ) else
84+ map.filterKeys(x => ordering.compare(x, toKey) < 0 )
85+ if (k.isEmpty) new ZoneMap (immutable.TreeMap ()) else new ZoneMap (immutable.TreeMap (k.toSeq: _* ))
86+ }
4687
47- override def lowerEntry ( key : K ) = ???
88+ override def headMap ( toKey : K ): JSortedMap [ K , V ] = headMap(toKey, false )
4889
49- override def pollLastEntry () = ???
90+ override def ceilingKey (key : K ): K = {
91+ val k = map.filterKeys(x => ordering.compare(x, key) >= 0 )
92+ if (k.isEmpty) null .asInstanceOf [K ] else k.head._1
93+ }
5094
51- override def descendingKeySet () = ???
95+ override def floorKey (key : K ): K = {
96+ val k = map.filterKeys(x => ordering.compare(x, key) <= 0 )
97+ if (k.isEmpty) null .asInstanceOf [K ] else k.last._1
98+ }
5299
53- override def lastEntry (): java.util.Map .Entry [K , V ] = {
54- val fk = firstKey()
55- map.get(fk).map(new SimpleEntry (lastKey(), _)).getOrElse(null .asInstanceOf [java.util.Map .Entry [K , V ]])
56- }
100+ // Will not be implemented. It needs NavigableSet
101+ override def descendingKeySet () = ???
57102
58- override def tailMap (fromKey : K , inclusive : Boolean ) = ???
103+ override def tailMap (fromKey : K , inclusive : Boolean ): java.util.NavigableMap [K , V ]= {
104+ val k = if (inclusive) map.filterKeys(x => ordering.compare(x, fromKey) >= 0 ) else
105+ map.filterKeys(x => ordering.compare(x, fromKey) > 0 )
106+ if (k.isEmpty) new ZoneMap (immutable.TreeMap ()) else new ZoneMap (immutable.TreeMap (k.toSeq: _* ))
107+ }
59108
60- override def tailMap (fromKey : K ) = ???
109+ override def tailMap (fromKey : K ): JSortedMap [ K , V ] = tailMap(fromKey, true )
61110
62- override def lowerKey (key : K ) = ???
111+ override def lowerKey (key : K ): K = {
112+ val k = map.filterKeys(x => ordering.compare(x, key) < 0 )
113+ if (k.isEmpty) null .asInstanceOf [K ] else k.last._1
114+ }
63115
64- override def higherKey (key : K ) = ???
116+ override def higherKey (key : K ) = {
117+ val k = map.filterKeys(x => ordering.compare(x, key) > 0 )
118+ if (k.isEmpty) null .asInstanceOf [K ] else k.head._1
119+ }
65120
66121 override def firstKey (): K = map.firstKey
67122
@@ -72,16 +127,22 @@ private[zone] class ZoneMap[K: ClassTag, V](implicit ordering: Ordering[K]) exte
72127 override def values (): JCollection [V ] = map.values.asJavaCollection
73128
74129 override def put (key : K , value : V ): V = {
75- map = map + ((key, value))
76- value
130+ val prev : Option [V ] = map.get(key)
131+ map += ((key, value))
132+ prev.getOrElse(null .asInstanceOf [V ])
77133 }
78134
79135 override def clear (): Unit =
80- map = scala.collection. immutable.TreeMap [ K , V ] ()
136+ map = immutable.TreeMap ()
81137
82138 override def entrySet (): JSet [JMap .Entry [K , V ]] = {
83139 map.map {
84140 case (k, v) => new SimpleEntry [K , V ](k, v): JMap .Entry [K , V ]
85141 }.toSet.asJava
86142 }
87143}
144+
145+ object ZoneMap {
146+
147+ def apply [K : ClassTag , V ](map : immutable.TreeMap [K , V ])(implicit ordering : Ordering [K ]): java.util.NavigableMap [K , V ] = new ZoneMap [K , V ](map)
148+ }
0 commit comments