Forum > General

[SOLVED] Passing static array of byte by reference... without creating copies

(1/2) > >>

BigChimp:
I've read
http://stackoverflow.com/questions/3911432/pass-static-byte-array-in-parameter-in-delphi
and tried to apply it.... without success... or perhaps with other complications.

More eyes welcome

The program recurses through files/directories, and stores details in a Firebird (embedded0 database. Sort of like locate

My goal: have 1 buffer that is used for all md5 calculations instead of having duplicates.
The application is single threaded so 1 buffer should be ok..

In search.pas, the search happens in AddFileToResult
FFileBuffer should create a new array once...

--- Code: ---  TFileSearch = class
  private
...
    // Buffer that can be used by e.g. md5 hashes
    FFileBuffer: TFileBuffer; //Buffer used e.g. in md5 calculations, defined in flocatecommon as array[1...1024*1024] of byte

--- End code ---
...and this is passed to the directoryentry constructor (should be as reference)...

--- Code: ---procedure TFileSearch.AddFileToResult(const ThisDir: String; item: TSearchRec);
// Finds out properties of file specified in item, adds this information
// to a record, and adds a pointer in the Res list to this record.
var
  DirEntry: TDirectoryEntry;
begin
  assert(ThisDir <> '', 'Directory to be searched may not be empty');
  assert(Item.Name <> '', 'File to be searched must have a filename');
  //Create a new file object and let it figure out all properties of the file.
  DirEntry := TDirectoryEntry.Create(ThisDir + Item.Name,FFileBuffer,FReadFileContents);

--- End code ---
... then directoryentry.pas does this

--- Code: ---  TDirectoryEntry = class(TObject)
  private
...
    FFileBuffer: TFileBuffer; //buffer for e.g. md5 etc can be reused.

--- End code ---
... this worries me, AFAIU, this will generate a new array. How can I declare the right variable here?

The constructor then goes on

--- Code: ---constructor TDirectoryEntry.Create(FullPath: string; var FileBuffer: TFileBuffer; ReadFileContents: boolean);
begin
...
  FFileBuffer:=FileBuffer;

--- End code ---

Attached complete code for Win/Linux; it creates a firebird embedded db if it doesn't exist (requires fb dll/lib of course)

Thanks!

User137:
The format on dynamic and static array are little different, so it's not directly possible i'd assume, without hacks. Easy solution would be to use array pointer

--- Code: ---type
  PFileBuffer = ^TFileBuffer;
...
private
...
    FFileBuffer: PFileBuffer;
--- End code ---

Leledumbo:
Do as User137 suggests. Even if the parameter is declared by reference, assignment between static arrays does a deep copy. Well actually, even if you don't assign anything to TDirectoryEntry.FFileBuffer, when you create TDirectoryEntry instance, each will already occupy the its own 1 MB space. Assignment only copies the values.

BigChimp:
Thanks a lot, that does seem to work fine!

User137:
Another solution came to mind, that FileBuffer would be a array property, which uses getter function directly to original static array. It has benefit of having simpler syntax when coding with, no pointer confusions with ^ symbols.

Navigation

[0] Message Index

[#] Next page

Go to full version