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

com.javanut.pronghorn.pipe.util.ISOTimeFormatterLowGC Maven / Gradle / Ivy

Go to download

Ring buffer based queuing utility for applications that require high performance and/or a small footprint. Well suited for embedded and stream based processing.

There is a newer version: 1.1.27
Show newest version
package com.javanut.pronghorn.pipe.util;

import java.io.IOException;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

import com.javanut.pronghorn.pipe.ChannelWriter;
import com.javanut.pronghorn.pipe.DataInputBlobReader;
import com.javanut.pronghorn.pipe.DataOutputBlobWriter;
import com.javanut.pronghorn.pipe.Pipe;
import com.javanut.pronghorn.pipe.RawDataSchema;
import com.javanut.pronghorn.util.Appendables;

public class ISOTimeFormatterLowGC {
	
	//////// constants
	private final String YYYY_MM_DD_HH_MM_SS_SSS_Z;
	private final int SECONDS_OFFSET; //where the seconds begin
	private final int SECONDS_LENGTH; //where the seconds begin
	private final byte SECONDS_PLACES; //sub second places of accuracy (always negative)
	////////////////////////////////////
	
	private final DateTimeFormatter formatter;
	private long validRange = 0;

	Pipe temp;
	
	public ISOTimeFormatterLowGC() {
		this(false);
	}
	
	public ISOTimeFormatterLowGC(boolean fileNameSafe) {
		
		if (fileNameSafe) {
			YYYY_MM_DD_HH_MM_SS_SSS_Z = "yyyyMMddHHmmssSSS";
			SECONDS_OFFSET  = 12; //where the seconds begin
			SECONDS_LENGTH  = 5; //where the seconds begin
			SECONDS_PLACES =  0; //sub second places of accuracy (always negative)
		} else {
			YYYY_MM_DD_HH_MM_SS_SSS_Z = "yyyy-MM-dd HH:mm:ss.SSS z";
			SECONDS_OFFSET  = 17; //where the seconds begin
			SECONDS_LENGTH  = 6; //where the seconds begin
			SECONDS_PLACES = -3; //sub second places of accuracy (always negative)
		}
		
		
		formatter = DateTimeFormatter
				    .ofPattern(YYYY_MM_DD_HH_MM_SS_SSS_Z)
				    .withZone( ZoneOffset.UTC );
	
		temp = RawDataSchema.instance.newPipe(2, 32);
		temp.initBuffers();
		
	}
		
	public void write(long time, ChannelWriter writer) {
		
		long localMinute = time/60_000L;
		
		if (localMinute != validRange) {
						
		    //this is so we know that we are in the same minute next time
		    validRange = localMinute; 
		    		    
		    temp.reset();
		    int size = Pipe.addMsgIdx(temp, RawDataSchema.MSG_CHUNKEDSTREAM_1);
		    
		    DataOutputBlobWriter targetStream = Pipe.openOutputStream(temp);
		    		    
		    //expensive call, must keep infrequent
			formatter.formatTo(Instant.ofEpochMilli(time), targetStream);// 2018-04-24 17:43:04.490 Z
			targetStream.replicate(writer);
			
			DataOutputBlobWriter.closeLowLevelField(targetStream);
			Pipe.confirmLowLevelWrite(temp);
			Pipe.publishWrites(temp);
				
		} else {
			//just update seconds but use the rest
			
			Pipe.markTail(temp);
			Pipe.takeMsgIdx(temp);
			DataInputBlobReader inStream = Pipe.openInputStream(temp);
			inStream.readInto(writer, SECONDS_OFFSET);
			inStream.skip(SECONDS_LENGTH);
			
			long sec = time%60_000L;
			if (SECONDS_PLACES != 0) {
				if (sec<10_000) {
					writer.writeByte('0');
				}
				assert(sec<100_000);
				Appendables.appendDecimalValue(writer, sec, SECONDS_PLACES);
			} else {			
				Appendables.appendFixedDecimalDigits(writer, sec, 10000);
			}
			
			inStream.readInto(writer, inStream.available());
			
			Pipe.resetTail(temp);
			
		}
		
	}
	
	public void write(long time, Appendable target) {
		
		long localMinute = time/60_000L;
		
		if (localMinute != validRange) {
						
		    //this is so we know that we are in the same minute next time
		    validRange = localMinute; 
		    		    
		    temp.reset();
		    int size = Pipe.addMsgIdx(temp, RawDataSchema.MSG_CHUNKEDSTREAM_1);
		    
		    DataOutputBlobWriter targetStream = Pipe.openOutputStream(temp);
		    		    
		    //expensive call, must keep infrequent
			formatter.formatTo(Instant.ofEpochMilli(time), targetStream);// 2018-04-24 17:43:04.490 Z
			targetStream.replicate(target);
			
			DataOutputBlobWriter.closeLowLevelField(targetStream);
			Pipe.confirmLowLevelWrite(temp);
			Pipe.publishWrites(temp);
				
		} else {
			//just update seconds but use the rest
			
			Pipe.markTail(temp);
			Pipe.takeMsgIdx(temp);
			DataInputBlobReader inStream = Pipe.openInputStream(temp);
			inStream.readUTFOfLength(SECONDS_OFFSET, target);
			inStream.skip(SECONDS_LENGTH);
			
			long sec = time%60_000L;
			if (SECONDS_PLACES != 0) {
				if (sec<10_000) {
					try {
						target.append('0');
					} catch (IOException e) {
						throw new RuntimeException(e);
					}
				}
				assert(sec<100_000);
				Appendables.appendDecimalValue(target, sec, SECONDS_PLACES);
			} else {			
				Appendables.appendFixedDecimalDigits(target, sec, 10000);
			}
			inStream.readUTFOfLength(inStream.available(), target);
				
			Pipe.resetTail(temp);
			
		}
		
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy