Comments on: SKIP and SEEK on Ports
As you may or may not know, in R3, a port value no longer stores the series offset. Instead, the offset is determined at a lower level within the port object.
As a clear example, if you write:
port: open %file
d1: read/part port 100
d2: read/part port 100
You will read the first 100 bytes, then the next 100 bytes, etc.
But, what if you want to read 100 bytes offset at a specific location, say 1000 bytes into the file. There are two possible solutions.
Method 1: use a refinement
We can add the /at refinement:
data: read/part/at port 100 1000
The advantage is that the seek operation occurs during the read action itself, so the port handler and device are only called once. This eliminates a small amount of overhead, at the small cost of an extra refinement.
Another advantage is that you can read part of an unopened file:
data: read/part/at %file.txt 100 1000
So, everything happens on that one line. It can be useful at times.
Method 2: Make the AT action work for ports
This would be defined to specify the absolute position, and would effect the port state.
at port 1000
data: read/part port 100
And, because at returns the port, you can write:
data: read/part at port 1000 100
The advantage is that we can eliminate one refinement from read, but we must make the additional call for at, which is an extra call to the port handler, dispatched to the device.
SKIP also could be allowed
For both of these, it would also be possible to support skip, a relative offset function:
data: read/part/skip port 100 512
data: read/part skip port 512 100
I would say that I am leaning toward the refinement. The two main reasons are:
- It eliminates an extra call to the port handler and device, and it calls the seek immediately before the actual low level read.
- It works for un-opened files, so you can easily fetch a chunk from a file without opening it beforehand.
Note that it may also be possible to allow both the refinement and the at but is there an advantage in that?
But, I'm writing all of this to get your comments, so let me know your thoughts.
Yes Carl, I agree. Go for the extra refinement. However it sounds similiar to what open/seek does in 2.7.x versions.|
Turns out that OPEN will still have a /seek refinement. It is used to tell the OS that we expect non-linear access to the file, and it should optimize accordingly.|
The second method allows the same way for writing to a file and it must be implemented only once.|
Unless there is an overarching need for creation of a cursor within TCP ports, or ports in general; on balance of consideration between control and efficiency, I would agree with making this a refinement.
As a refinement, this keeps the effect specifically limited to the local code; also, "read/part/at" is elegantly intuitive. I feel that any time the prospect of such inherently readable syntax presents itself during the design process, it should be recognized and seized upon ;).
Furthermore, as a logical objection to implementation within the port itself, I see an inherent complexity in having to keep track of an alteration of a port state, and an inherent inefficiency in attaching a more generally applicable method at the port level for what is essentially a locally based need. These considerations become necessary and balanced against the costs described here, only if it suits the roles of ports overall in addressing a need for handling content of files within the structure of ports, in general.
In other words, there probably are better ways to implement reading and writing to files in these situations, than by conflating functions of one role (port content access and control) with another (file content access and control). However, if it becomes apparent that there are other good reasons to implement what is, in effect, a cursor for ports, then this second method could become an alternative way of accessing file content.
Post a Comment:
You can post a comment here. Keep it on-topic.