View Javadoc

1   /*
2    * Copyright (c) 2015 Cisco Systems, Inc.  All rights reserved.
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6    * and is available at http://www.eclipse.org/legal/epl-v10.html
7    */
8   
9   package org.opendaylight.lispflowmapping.inmemorydb;
10  
11  import java.util.Date;
12  import java.util.Map;
13  import java.util.concurrent.ConcurrentHashMap;
14  import java.util.concurrent.ConcurrentMap;
15  import java.util.concurrent.TimeUnit;
16  
17  import org.opendaylight.lispflowmapping.interfaces.dao.ILispDAO;
18  import org.opendaylight.lispflowmapping.interfaces.dao.IRowVisitor;
19  import org.opendaylight.lispflowmapping.interfaces.dao.MappingEntry;
20  import org.opendaylight.lispflowmapping.interfaces.dao.SubKeys;
21  import org.slf4j.Logger;
22  import org.slf4j.LoggerFactory;
23  
24  public class HashMapDb implements ILispDAO, AutoCloseable {
25  
26      protected static final Logger LOG = LoggerFactory.getLogger(HashMapDb.class);
27      private ConcurrentMap<Object, ConcurrentMap<String, Object>> data = new ConcurrentHashMap<Object, ConcurrentMap<String, Object>>();
28      private TimeUnit timeUnit = TimeUnit.SECONDS;
29      private int recordTimeOut = 240;
30      private final Object TABLES = (Object) "tables";
31  
32      @Override
33      public void put(Object key, MappingEntry<?>... values) {
34          if (!data.containsKey(key)) {
35              data.put(key, new ConcurrentHashMap<String, Object>());
36          }
37          for (MappingEntry<?> entry : values) {
38              data.get(key).put(entry.getKey(), entry.getValue());
39          }
40      }
41  
42      @Override
43      public Object getSpecific(Object key, String valueKey) {
44          Map<String, Object> keyToValues = data.get(key);
45          if (keyToValues == null) {
46              return null;
47          }
48          return keyToValues.get(valueKey);
49      }
50  
51      @Override
52      public Map<String, Object> get(Object key) {
53          return data.get(key);
54      }
55  
56      @Override
57      public void getAll(IRowVisitor visitor) {
58          for (ConcurrentMap.Entry<Object, ConcurrentMap<String, Object>> keyEntry : data.entrySet()) {
59              for (Map.Entry<String, Object> valueEntry : keyEntry.getValue().entrySet()) {
60                  visitor.visitRow(keyEntry.getKey(), valueEntry.getKey(), valueEntry.getValue());
61              }
62          }
63      }
64  
65      @Override
66      public void remove(Object key) {
67          data.remove(key);
68      }
69  
70      @Override
71      public void removeSpecific(Object key, String valueKey) {
72          if (data.containsKey(key) && data.get(key).containsKey(valueKey)) {
73              data.get(key).remove(valueKey);
74          }
75      }
76  
77      @Override
78      public void removeAll() {
79          data.clear();
80      }
81  
82      // TODO: this should be moved outside of DAO implementation
83      public void cleanOld() {
84          getAll(new IRowVisitor() {
85              public void visitRow(Object keyId, String valueKey, Object value) {
86                  if (value != null && valueKey instanceof String && ((String) valueKey).equals(SubKeys.REGDATE)) {
87                      Date date = (Date) value;
88                      if (isExpired(date)) {
89                          removeSpecific(keyId, SubKeys.RECORD);
90                      }
91                  }
92              }
93  
94              private boolean isExpired(Date date) {
95                  return System.currentTimeMillis() - date.getTime() > TimeUnit.MILLISECONDS.convert(recordTimeOut, timeUnit);
96              }
97          });
98      }
99  
100     public TimeUnit getTimeUnit() {
101         return timeUnit;
102     }
103 
104     public void setRecordTimeOut(int recordTimeOut) {
105         this.recordTimeOut = recordTimeOut;
106     }
107 
108     public int getRecordTimeOut() {
109         return recordTimeOut;
110     }
111 
112     public void setTimeUnit(TimeUnit timeUnit) {
113         this.timeUnit = timeUnit;
114     }
115 
116     public void close() throws Exception {
117         data.clear();
118     }
119 
120     @Override
121     public ILispDAO putNestedTable(Object key, String valueKey) {
122         ILispDAO nestedTable = (ILispDAO) getSpecific(key, valueKey);
123         if (nestedTable != null) {
124             LOG.warn("Trying to add nested table that already exists. Aborting!");
125             return nestedTable;
126         }
127         nestedTable = new HashMapDb();
128         put(key, new MappingEntry<>(valueKey, nestedTable));
129         return nestedTable;
130     }
131 
132     @Override
133     public ILispDAO putTable(String key) {
134         ILispDAO table = (ILispDAO) getSpecific(TABLES, key);
135         if (table != null) {
136             LOG.warn("Trying to add table that already exists. Aborting!");
137             return table;
138         }
139         table = new HashMapDb();
140         put(TABLES, new MappingEntry<>(key, table));
141         return table;
142     }
143 }