package com.ctriposs.tsdb.iterator; import java.io.IOException; import java.util.Iterator; import java.util.Map.Entry; import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListMap; import com.ctriposs.tsdb.ISeekIterator; import com.ctriposs.tsdb.InternalKey; import com.ctriposs.tsdb.manage.FileManager; import com.ctriposs.tsdb.table.MemTable; import com.ctriposs.tsdb.util.ByteUtil; public class MemSeekIterator implements ISeekIterator<InternalKey, byte[]> { private ConcurrentSkipListMap<InternalKey, byte[]> dataMap; private Iterator<Entry<InternalKey, byte[]>> curSeeIterator; private Entry<InternalKey, byte[]> curEntry; private InternalKey curSeekKey; private FileManager fileManager; private long fileNumber; public MemSeekIterator(FileManager fileManager,MemTable memTable,long fileNumber){ this.dataMap = memTable.getAllConcurrentSkipList(); this.fileManager = fileManager; this.fileNumber = fileNumber; this.curSeeIterator = null; this.curSeekKey = null; this.curEntry = null; } @Override public boolean hasNext() { if(curEntry != null){ if(curEntry.getKey().getCode() == curSeekKey.getCode()){ return true; } } return false; } @Override public boolean hasPrev() { if(curEntry != null){ if(curEntry.getKey().getCode() == curSeekKey.getCode()){ return true; } } return false; } @Override public Entry<InternalKey, byte[]> next() { Entry<InternalKey, byte[]> entry = curEntry; if(curSeeIterator != null){ if(curSeeIterator.hasNext()){ curEntry = curSeeIterator.next(); }else{ curEntry = null; } } return entry; } @Override public Entry<InternalKey, byte[]> prev() { Entry<InternalKey, byte[]> entry = curEntry; if(curSeeIterator != null){ if(curEntry != null){ curEntry = dataMap.lowerEntry(curEntry.getKey()); } } return entry; } @Override public void seek(String table, String column, long time) throws IOException { int code = ByteUtil.ToInt(fileManager.getCode(table),fileManager.getCode(column)); seek(code, time); } @Override public void seek(int code, long time) throws IOException { curSeekKey = new InternalKey(code, time); Entry<InternalKey, byte[]> entry = dataMap.lowerEntry(curSeekKey); ConcurrentNavigableMap<InternalKey, byte[]> subMap = null; if(entry == null){ subMap = dataMap.subMap(curSeekKey, new InternalKey(code, Long.MAX_VALUE)); }else{ subMap = dataMap.subMap(entry.getKey(), new InternalKey(code, Long.MAX_VALUE)); } curSeeIterator = subMap.entrySet().iterator(); curEntry = null; while(curSeeIterator.hasNext()){ curEntry = curSeeIterator.next(); if(curEntry.getKey().getCode()==code){ break; } } if(curEntry != null){ if(curEntry.getKey().getCode()!=code){ curEntry = null; } } } @Override public String table() { if(curEntry != null){ return fileManager.getName(curEntry.getKey().getTableCode()); } return null; } @Override public String column() { if (curEntry != null) { return fileManager.getName(curEntry.getKey().getColumnCode()); } return null; } @Override public InternalKey key() { if (curEntry != null) { return curEntry.getKey(); } return null; } @Override public long time() { if (curEntry != null) { return curEntry.getKey().getTime(); } return 0; } @Override public byte[] value() throws IOException { if (curEntry != null) { return curEntry.getValue(); } return null; } @Override public boolean valid() { if (curEntry == null) { return false; } else { return true; } } @Override public void close() throws IOException { dataMap = null; } @Override public void remove() { throw new UnsupportedOperationException("unsupport remove operation!"); } @Override public long priority() { return fileNumber; } }