All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.teamapps.universaldb.index.log.LogIterator Maven / Gradle / Ivy

There is a newer version: 0.6.20
Show newest version
/*-
 * ========================LICENSE_START=================================
 * UniversalDB
 * ---
 * Copyright (C) 2014 - 2023 TeamApps.org
 * ---
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =========================LICENSE_END==================================
 */
package org.teamapps.universaldb.index.log;

import java.io.*;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

public class LogIterator implements Iterator, AutoCloseable {

	private final List logFiles;
	private int currentFileIndex = -1;
	private DataInputStream dis;
	private byte[] nextLog;
	private long currentReadPos;

	public LogIterator(List logFiles, long startPosition, boolean rotatingLogIndex) {
		this.logFiles = logFiles;
		seekLogPosition(startPosition, rotatingLogIndex);
		readLog();
	}

	private void seekLogPosition(long startPosition, boolean rotatingLogIndex) {
		try {
			long skipBytes = startPosition;
			if (rotatingLogIndex) {
				currentFileIndex = RotatingLogIndex.getFileIndex(startPosition);
				int filePos = RotatingLogIndex.getFilePos(startPosition);
				if (currentFileIndex >= logFiles.size()) {
					return;
				}
				skipBytes = filePos;
			} else {
				currentFileIndex = 0;
			}
			dis = new DataInputStream(new BufferedInputStream(new FileInputStream(logFiles.get(currentFileIndex)), 64_000));
			if (skipBytes > 0) {
				dis.skipNBytes(skipBytes);
				currentReadPos = RotatingLogIndex.calculatePosition(currentFileIndex, (int) skipBytes);
			} else if (!rotatingLogIndex) {
				dis.readInt();
				currentReadPos = 4;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void readLog() {
		try {
			nextLog = null;
			if (dis == null) {
				currentFileIndex++;
				if (currentFileIndex >= logFiles.size()) {
					return;
				}
				dis = new DataInputStream(new BufferedInputStream(new FileInputStream(logFiles.get(currentFileIndex)), 64_000));
				currentReadPos = RotatingLogIndex.calculatePosition(currentFileIndex, 0);
			}
			int size = dis.readInt();
			currentReadPos += size + 4;
			byte[] bytes = new byte[size];
			dis.readFully(bytes);
			nextLog = bytes;
		} catch (EOFException ignore) {
			closeStream();
			dis = null;
			readLog();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void readMessages(List messages) {
		if (messages.isEmpty() || logFiles.isEmpty()) {
			return;
		}
		long position = 0;
		int index = 0;
		while (hasNext()) {
			PositionIndexedMessage message = messages.get(index);
			boolean addMessage = message.getPosition() == position || index == 0;
			position = currentReadPos;
			byte[] bytes = next();
			if (addMessage) {
				message.setMessage(bytes);
				index++;
				if (index >= messages.size()) {
					break;
				}
			}
		}
		messages.sort(Comparator.comparingInt(PositionIndexedMessage::getId));
		closeSave();
	}


	@Override
	public boolean hasNext() {
		if (nextLog != null) {
			return true;
		} else {
			closeStream();
			return false;
		}
	}

	@Override
	public byte[] next() {
		byte[] bytes = nextLog;
		readLog();
		return bytes;
	}

	public long getCurrentReadPosition() {
		return currentReadPos;
	}

	@Override
	public void close() throws Exception {
		if (dis != null) {
			dis.close();
		}
	}

	public void closeSave() {
		try {
			close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void closeStream() {
		try {
			if (dis == null) {
				return;
			}
			dis.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy