by
Krull >> Wed, 12 Jul 2000 7:02:15 GMT
Ray,
Your "No memory for buffers" problem is due to the cache sizing issue pointed out by Craig and others on this thread. However, I do have a couple of other comments that may (or may not) be of use to you:
In your code fragment:
while rec <> null do
rec := _file.readBinary (65536);
beginTransientTransaction;
file := file & rec;
commitTransientTransaction;
endwhile;
It looks like file is a property of self (shared transient), otherwise you would need to bound the update in a transient transaction. It is often better (performance-wise) to do this type of assembly of string or binary fragments in a local variable and then assign this to the property once. Try timing the above loop and compare it to something like:
while rec <> null do
rec := _file.readBinary (65536);
tempBinary := tempBinary & rec;
endwhile;
begin
TransientTransaction;
file := tempBinary;
commitTransientTransaction;
You should see a performance improvement. You would also get better performance if you increase your cache sizes as suggested by Craig and Darrell and go back to a single read. However, these approaches won't scale up to handling large files.
Do you really need to store the entire file in an object in the first place? Given that you are storing a copy of the file in a transient object implies that you don't need to share a copy between nodes so you could consider reading it each time you need to process the file. If you need to read the file more than once, you could make file access relatively transparent using a *virtual* mapping method similar to the following:
fileImage(set:Boolean; value:Binary io) mapping;begin
if not set then
value := myFile.readBinary (myFile.fileLength);
endif;
end;
or a just a method of the form:
fileImage() : Binary;begin
return myFile.readBinary (myFile.fileLength);
end;
Neither of these approaches involves updating a (blob) binary large object property, so cache size is no longer an issue (i.e. you won't get the 1018, regardless of cache size); the size of file you can handle this way is now limited by the JADE interpreter string pool size, which is mainly limited by the amount of virtual memory available on your machine. Doing it this way will give you better performance for files with a size approaching the size of your cache, even if you have to read the file more than once, since whenever a large binary object overflows cache it has to be written out to disk and gets read back in when reaccessed. A possible optimisation (using the virtual mapping method) would be to store files below a certain size threshold in an internal binary property; only useful if you process the file more than once (but I wouldn't bother with this).
All of the above approaches are only good for "moderate size" files, were moderate depends on the average amount of available *physical* (not virtual) memory on your machine. To get an idea what I mean, try opening a file that has a size close to your machines physical memory size with wordpad (wordpad also takes the approach of loding the entire file into memory).
Handling very large files efficiently is beyond the scope of this thread (that's why we have databases).