| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- package linkedhashmap
- import (
- "bytes"
- "github.com/goccy/go-json"
- "github.com/sagernet/sing/common"
- E "github.com/sagernet/sing/common/exceptions"
- "github.com/sagernet/sing/common/x/list"
- )
- type Map[K comparable, V any] struct {
- raw list.List[mapEntry[K, V]]
- rawMap map[K]*list.Element[mapEntry[K, V]]
- }
- func (m *Map[K, V]) init() {
- if m.rawMap == nil {
- m.rawMap = make(map[K]*list.Element[mapEntry[K, V]])
- }
- }
- func (m *Map[K, V]) MarshalJSON() ([]byte, error) {
- buffer := new(bytes.Buffer)
- buffer.WriteString("{")
- for item := m.raw.Front(); item != nil; {
- entry := item.Value
- err := json.NewEncoder(buffer).Encode(entry.Key)
- if err != nil {
- return nil, err
- }
- buffer.WriteString(": ")
- err = json.NewEncoder(buffer).Encode(entry.Value)
- if err != nil {
- return nil, err
- }
- item = item.Next()
- if item != nil {
- buffer.WriteString(", ")
- }
- }
- buffer.WriteString("}")
- return buffer.Bytes(), nil
- }
- func (m *Map[K, V]) UnmarshalJSON(content []byte) error {
- decoder := json.NewDecoder(bytes.NewReader(content))
- m.Clear()
- m.init()
- objectStart, err := decoder.Token()
- if err != nil {
- return err
- } else if objectStart != json.Delim('{') {
- return E.New("expected json object start, but starts with ", objectStart)
- }
- for decoder.More() {
- var entryKey K
- err = decoder.Decode(&entryKey)
- if err != nil {
- return err
- }
- var entryValue V
- err = decoder.Decode(&entryValue)
- if err != nil {
- return err
- }
- m.rawMap[entryKey] = m.raw.PushBack(mapEntry[K, V]{Key: entryKey, Value: entryValue})
- }
- objectEnd, err := decoder.Token()
- if err != nil {
- return err
- } else if objectEnd != json.Delim('}') {
- return E.New("expected json object end, but ends with ", objectEnd)
- }
- return nil
- }
- type mapEntry[K comparable, V any] struct {
- Key K
- Value V
- }
- func (m *Map[K, V]) Size() int {
- return m.raw.Size()
- }
- func (m *Map[K, V]) IsEmpty() bool {
- return m.raw.IsEmpty()
- }
- func (m *Map[K, V]) ContainsKey(key K) bool {
- m.init()
- _, loaded := m.rawMap[key]
- return loaded
- }
- func (m *Map[K, V]) Get(key K) (V, bool) {
- m.init()
- value, loaded := m.rawMap[key]
- return value.Value.Value, loaded
- }
- func (m *Map[K, V]) Put(key K, value V) V {
- m.init()
- entry, loaded := m.rawMap[key]
- if loaded {
- oldValue := entry.Value.Value
- entry.Value.Value = value
- return oldValue
- }
- entry = m.raw.PushBack(mapEntry[K, V]{Key: key, Value: value})
- m.rawMap[key] = entry
- return common.DefaultValue[V]()
- }
- func (m *Map[K, V]) PutAll(other *Map[K, V]) {
- for item := other.raw.Front(); item != nil; item = item.Next() {
- m.Put(item.Value.Key, item.Value.Value)
- }
- }
- func (m *Map[K, V]) Remove(key K) bool {
- m.init()
- entry, loaded := m.rawMap[key]
- if !loaded {
- return false
- }
- m.raw.Remove(entry)
- delete(m.rawMap, key)
- return true
- }
- func (m *Map[K, V]) RemoveAll(keys []K) {
- m.init()
- for _, key := range keys {
- entry, loaded := m.rawMap[key]
- if !loaded {
- continue
- }
- m.raw.Remove(entry)
- delete(m.rawMap, key)
- }
- }
- func (m *Map[K, V]) AsMap() map[K]V {
- result := make(map[K]V, m.raw.Len())
- for item := m.raw.Front(); item != nil; item = item.Next() {
- result[item.Value.Key] = item.Value.Value
- }
- return result
- }
- func (m *Map[K, V]) Keys() []K {
- result := make([]K, 0, m.raw.Len())
- for item := m.raw.Front(); item != nil; item = item.Next() {
- result = append(result, item.Value.Key)
- }
- return result
- }
- func (m *Map[K, V]) Values() []V {
- result := make([]V, 0, m.raw.Len())
- for item := m.raw.Front(); item != nil; item = item.Next() {
- result = append(result, item.Value.Value)
- }
- return result
- }
- func (m *Map[K, V]) Clear() {
- *m = Map[K, V]{}
- }
|