New month.


So there have been about 440 commits for the entire month, which is not too bad. Although I have yet to reach native code compilation and I had part of an interpreter which I deleted (it was very ugly). The early part of the month was refactoring. I had working inflate code, but my current partial refactor is changing how the code works underneath (datapipe and such). I thought about compiling to C and using GCJ but that would be very ugly. And the last day or so is a refactor of the extra packages that I have.


So from where I left off, I get an AC0a which means that the dual state of the pipeline was not specifically set when I try reading input bytes from the pipeline. So I propose that if the input is complete and the input pipeline is empty that all reads cause EOF to occur.


I also get it now in completeOutput, since the input state may be complete then output completion may occur if the faucet is being filled.


And output completion is called twice, but that is the inflate code which I added since nothing was being called.


Then right now I have truncated output, at least for the very large compressed data set. Well actually it is not truncated, quite a number of the output is missing. Quite a number of zeros are missing from the output. So it seems as if zeros are never recorded in the output. Since my output sink is a single byte it is possible that it is recorded incorrectly when sent to the output that it does not like zero values.


So the values are sent to the data filler, so then it must be the drain side which is not correct.


Actually it is the input stream for the data pipe:

// {@squirreljme.error AC0e Forced stall.}
else if (rv == 0)
    throw new PipeStalledException("AC0e");

That is discard read zero values and treating them as stall, this would be correct if the read were multiple bytes instead of just one.


Using zero it can be seen how slow the official pure interpreter is, however my decompression algorithm seems rather fast. So the next speed optimization I can make is rewriting the circular buffers so that they are standalone rather than being part of generic buffers.


I also can remove potentially MissingCollections and use the unmodifiable classes semi-directly instead. So just UnmodifiableSet.<A>of(foo) instead of the longer MissingCollections.<A>unmodifiableSet(foo). I believe I will do that first since I must prepare food to cook and changing that would be simpler than rewriting the circular buffers in a short amount of time.


I can also move them into their own packages. So just extra-util-unmodifiable and extra-util-boxed so that they are part of the same family and such.


Then after those two, implement the CRC32 algorithm so that ZIP entries are verified.


Of the things used, the boxed integers and empty collections have not been used at all.


Real life stuff puts a large dent into refactoring today.


I walked 8 miles in 2 hours.


Right now the only thing to implement is offerLast and removeFirst.


The CircularByteBuffer could just use the DynamicByteBuffer although there may be an added inefficiency. However, an improvement in DynamicByteBuffer could increase the speed of the circular byte buffer, especially if the dynamic byte buffer becomes like the circular byte buffer more.


The CircularByteBuffer is not really circular, it is more of a queue so I suppose I shall call it that instead.


Changing the ByteDeque to use DynamicByteBuffer despite some speed limitations of the dynamic byte buffer results in the tests for the deflate algorithm running a bit faster now. A second is small on this system (which is quite old), but on an even slower system that second could be 5 minutes.


Also, the obvious big speed increase would be the removal of insane amounts of boxing due to the way the generic deque worked. Should also result in less pointless and quick allocations also. So on more memory constrained systems it should also be faster. I just now need to implement the boolean side of the data. I will do something similar and perform a large copy and paste of the ByteDeque code but handle a higher precision at the boolean level.


The boolean based version which would use the DynamicByteBuffer will have to handle shifts for the head and tail. Much more complex.


One thing would be to handle the slight offset since the backing store are bytes rather than booleans. I could write a DynamicBooleanBuffer but that would just duplicate the code.