org.bitcoinj.utils.CacheMap Maven / Gradle / Ivy
package org.bitcoinj.utils;
import org.bitcoinj.core.*;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
/**
* Map like container that keeps the N most recently added items
*/
public class CacheMap extends ChildMessage {
private long nMaxSize;
private long nCurrentSize;
private LinkedList> listItems = new LinkedList>();
private LinkedHashMap> mapIndex = new LinkedHashMap>();
public CacheMap() {
this(0);
}
public CacheMap(long nMaxSizeIn) {
this.nMaxSize = nMaxSizeIn;
this.nCurrentSize = 0;
this.listItems = new LinkedList>();
this.mapIndex = new LinkedHashMap>();
}
public CacheMap(CacheMap other) {
this.nMaxSize = other.nMaxSize;
this.nCurrentSize = other.nCurrentSize;
this.listItems = new LinkedList>(other.listItems);
this.mapIndex = new LinkedHashMap>();
rebuildIndex();
}
public CacheMap(NetworkParameters params, byte [] payload, int cursor) {
super(params, payload, cursor);
}
public final void clear() {
mapIndex.clear();
listItems.clear();
nCurrentSize = 0;
}
public final void setMaxSize(long nMaxSizeIn) {
nMaxSize = nMaxSizeIn;
}
public final long getMaxSize() {
return nMaxSize;
}
public final long getSize() {
return nCurrentSize;
}
public final void insert(K key, V value) {
CacheItem it = mapIndex.get(key);
if (it != null) {
CacheItem item = it;
item.value = value;
return;
}
if (nCurrentSize == nMaxSize) {
pruneLast();
}
CacheItem item = new CacheItem(key, value);
listItems.addFirst(item);
mapIndex.put(key, item);
++nCurrentSize;
}
public final boolean hasKey(K key) {
return mapIndex.containsKey(key);
}
public final CacheItem get(K key) {
CacheItem it = mapIndex.get(key);
if (it == null) {
return null;
}
return it;
}
public final void erase(K key) {
CacheItem it = mapIndex.get(key);
if (it == null) {
return;
}
listItems.remove(it);
mapIndex.remove(it.key);
--nCurrentSize;
}
public final LinkedList> getItemList() {
return listItems;
}
public final CacheMap copyFrom(CacheMap other) {
nMaxSize = other.nMaxSize;
nCurrentSize = other.nCurrentSize;
listItems = new LinkedList>(other.listItems);
rebuildIndex();
return this;
}
private void pruneLast() {
if (nCurrentSize < 1) {
return;
}
CacheItem item = listItems.getLast();
mapIndex.remove(item.key);
listItems.removeLast();
--nCurrentSize;
}
private void rebuildIndex() {
mapIndex.clear();
for(CacheItem item : listItems) {
mapIndex.put(item.key, item);
}
}
@Override
protected void parse() throws ProtocolException {
nMaxSize = readInt64();
nCurrentSize = readInt64();
long size = readVarInt();
mapIndex = new LinkedHashMap>();
listItems = new LinkedList>();
for (int i = 0; i < size; ++i) {
CacheItem item = new CacheItem(params, payload, cursor);
cursor += item.getMessageSize();
listItems.add(item);
}
length = cursor - offset;
rebuildIndex();
}
@Override
protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
Utils.int64ToByteStreamLE(nMaxSize, stream);
Utils.int64ToByteStreamLE(nCurrentSize, stream);
stream.write(new VarInt(listItems.size()).encode());
for(CacheItem item : listItems) {
item.bitcoinSerialize(stream);
}
}
public String toString() {
return "CacheMap("+nCurrentSize+" of {"+nMaxSize+"}}";
}
}