comp.lang.ada
 help / color / mirror / Atom feed
* Using Ada.Containers.Vector and Limited Private types
@ 2008-07-05 11:53 Dale Stanbrough
  2008-07-05 15:42 ` george.priv
  2008-07-06 18:09 ` Gene
  0 siblings, 2 replies; 18+ messages in thread
From: Dale Stanbrough @ 2008-07-05 11:53 UTC (permalink / raw)


I'm trying to sort a collection of Ada.Directories.Directory_Entry (a 
limited private type) by storing pointers to them in a Vector but am 
having problems with accessibility rules.


Is it possible to do this?


Package Ada.Directories only has procedures that have "in out"/out 
parameters for the Directory_Entry type, so I can't figure out how to 
get a reference to each object as I run through the More_Entries/ 
Get_Next_Entry procedures.


Thanks,

Dale


---------------------------------------
-- Displays directory entries in increasing date/time order


with Ada.Text_IO;            use Ada.Text_IO;
with Ada.Integer_Text_IO;    use Ada.Integer_Text_IO;
with Ada.Containers.Vectors;
with Ada.Directories;        use Ada.Directories;
with Ada.Calendar;           use Ada.Calendar; -- for comparing 
date/times


procedure List_By_Date is

   type Dir_Entry_Ptr is access all Directory_Entry_Type;
   
   package Dir_Vectors is new Ada.Containers.Vectors (Positive, 
Dir_Entry_Ptr);
   use Dir_Vectors;
   
   
   DV : Vector;
   
begin

   -- collect the entries
   declare
      Directory     : constant Filter_Type := (true,  false, false);
      Ordinary_File : constant Filter_Type := (false, true,  false);
      

      Results : Search_Type; -- used to hold the result of a search
      Directory_Entry : aliased Directory_Entry_Type;

   begin
      Start_Search ( Results,
               Directory => Current_Directory,
               Pattern   => "", -- select all files
               Filter    => Directory or Ordinary_File
             );
      
       
      while More_Entries (Results) loop
         Get_Next_Entry (Results, Directory_Entry);
         DV.Append (Directory_Entry'access);
            -- ******************************************************
            -- this is of course incorrect, but how to get around it?
            -- ******************************************************
      end loop;

   end;


   -- sort the entries
   declare
      function My_Sorter (Left, Right : Dir_Entry_Ptr) return boolean
      is
      begin
         return Ada.Directories.Modification_Time (Left.all) <
                Ada.Directories.Modification_Time (Right.all);
      end;
      
      package Dir_Vector_Sorting is new Generic_Sorting (My_Sorter);
       
   begin
      Dir_Vector_Sorting.Sort (DV);
   end;
   
   
   -- display the entries
   declare
      procedure Display_Entry (C : Cursor)
      is
         Directory_Entry_Ptr : constant Dir_Entry_Ptr := Element (C);
      begin
         Put (Simple_Name (Directory_Entry_Ptr.all));
      end;
   begin
      DV.iterate (Display_Entry'access);
   end;
   
end List_By_Date;

-- 
dstanbro@spam.o.matic.bigpond.net.au



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-05 11:53 Using Ada.Containers.Vector and Limited Private types Dale Stanbrough
@ 2008-07-05 15:42 ` george.priv
  2008-07-06 18:09 ` Gene
  1 sibling, 0 replies; 18+ messages in thread
From: george.priv @ 2008-07-05 15:42 UTC (permalink / raw)


On Jul 5, 7:53 am, Dale Stanbrough <MrNoS...@bigpoop.net.au> wrote:
> I'm trying to sort a collection of Ada.Directories.Directory_Entry (a
> limited private type) by storing pointers to them in a Vector but am
> having problems with accessibility rules.
>
> Is it possible to do this?
>
> Package Ada.Directories only has procedures that have "in out"/out
> parameters for the Directory_Entry type, so I can't figure out how to
> get a reference to each object as I run through the More_Entries/
> Get_Next_Entry procedures.
>
> Thanks,
>
> Dale
>
> ---------------------------------------
> -- Displays directory entries in increasing date/time order
>
> with Ada.Text_IO;            use Ada.Text_IO;
> with Ada.Integer_Text_IO;    use Ada.Integer_Text_IO;
> with Ada.Containers.Vectors;
> with Ada.Directories;        use Ada.Directories;
> with Ada.Calendar;           use Ada.Calendar; -- for comparing
> date/times
>
> procedure List_By_Date is
>
>    type Dir_Entry_Ptr is access all Directory_Entry_Type;
>
>    package Dir_Vectors is new Ada.Containers.Vectors (Positive,
> Dir_Entry_Ptr);
>    use Dir_Vectors;
>
>    DV : Vector;
>
> begin
>
>    -- collect the entries
>    declare
>       Directory     : constant Filter_Type := (true,  false, false);
>       Ordinary_File : constant Filter_Type := (false, true,  false);
>
>       Results : Search_Type; -- used to hold the result of a search
>       Directory_Entry : aliased Directory_Entry_Type;
>
>    begin
>       Start_Search ( Results,
>                Directory => Current_Directory,
>                Pattern   => "", -- select all files
>                Filter    => Directory or Ordinary_File
>              );
>
>       while More_Entries (Results) loop
>          Get_Next_Entry (Results, Directory_Entry);
>          DV.Append (Directory_Entry'access);
>             -- ******************************************************
>             -- this is of course incorrect, but how to get around it?
>             -- ******************************************************
>       end loop;
>
>    end;
>
>    -- sort the entries
>    declare
>       function My_Sorter (Left, Right : Dir_Entry_Ptr) return boolean
>       is
>       begin
>          return Ada.Directories.Modification_Time (Left.all) <
>                 Ada.Directories.Modification_Time (Right.all);
>       end;
>
>       package Dir_Vector_Sorting is new Generic_Sorting (My_Sorter);
>
>    begin
>       Dir_Vector_Sorting.Sort (DV);
>    end;
>
>    -- display the entries
>    declare
>       procedure Display_Entry (C : Cursor)
>       is
>          Directory_Entry_Ptr : constant Dir_Entry_Ptr := Element (C);
>       begin
>          Put (Simple_Name (Directory_Entry_Ptr.all));
>       end;
>    begin
>       DV.iterate (Display_Entry'access);
>    end;
>
> end List_By_Date;
>
> --
> dstan...@spam.o.matic.bigpond.net.au

You are attempting to create vector with pointers each pointing to the
same instance of Directory_Entry.  You need to allocate new
directory_entry_type objects as you traverse the directory (before
calling Get_Next_Entry).  Off course you have to free these objects
after use.

George.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-05 11:53 Using Ada.Containers.Vector and Limited Private types Dale Stanbrough
  2008-07-05 15:42 ` george.priv
@ 2008-07-06 18:09 ` Gene
  2008-07-06 19:18   ` Dmitry A. Kazakov
  2008-07-10  0:16   ` Dale Stanbrough
  1 sibling, 2 replies; 18+ messages in thread
From: Gene @ 2008-07-06 18:09 UTC (permalink / raw)


On Jul 5, 7:53 am, Dale Stanbrough <MrNoS...@bigpoop.net.au> wrote:
> I'm trying to sort a collection of Ada.Directories.Directory_Entry (a
> limited private type) by storing pointers to them in a Vector but am
> having problems with accessibility rules.
>
> Is it possible to do this?
>
> Package Ada.Directories only has procedures that have "in out"/out
> parameters for the Directory_Entry type, so I can't figure out how to
> get a reference to each object as I run through the More_Entries/
> Get_Next_Entry procedures.
>
> Thanks,
>
> Dale
>
> ---------------------------------------
> -- Displays directory entries in increasing date/time order
>
> with Ada.Text_IO;            use Ada.Text_IO;
> with Ada.Integer_Text_IO;    use Ada.Integer_Text_IO;
> with Ada.Containers.Vectors;
> with Ada.Directories;        use Ada.Directories;
> with Ada.Calendar;           use Ada.Calendar; -- for comparing
> date/times
>
> procedure List_By_Date is
>
>    type Dir_Entry_Ptr is access all Directory_Entry_Type;
>
>    package Dir_Vectors is new Ada.Containers.Vectors (Positive,
> Dir_Entry_Ptr);
>    use Dir_Vectors;
>
>    DV : Vector;
>
> begin
>
>    -- collect the entries
>    declare
>       Directory     : constant Filter_Type := (true,  false, false);
>       Ordinary_File : constant Filter_Type := (false, true,  false);
>
>       Results : Search_Type; -- used to hold the result of a search
>       Directory_Entry : aliased Directory_Entry_Type;
>
>    begin
>       Start_Search ( Results,
>                Directory => Current_Directory,
>                Pattern   => "", -- select all files
>                Filter    => Directory or Ordinary_File
>              );
>
>       while More_Entries (Results) loop
>          Get_Next_Entry (Results, Directory_Entry);
>          DV.Append (Directory_Entry'access);
>             -- ******************************************************
>             -- this is of course incorrect, but how to get around it?
>             -- ******************************************************
>       end loop;
>
>    end;
>
>    -- sort the entries
>    declare
>       function My_Sorter (Left, Right : Dir_Entry_Ptr) return boolean
>       is
>       begin
>          return Ada.Directories.Modification_Time (Left.all) <
>                 Ada.Directories.Modification_Time (Right.all);
>       end;
>
>       package Dir_Vector_Sorting is new Generic_Sorting (My_Sorter);
>
>    begin
>       Dir_Vector_Sorting.Sort (DV);
>    end;
>
>    -- display the entries
>    declare
>       procedure Display_Entry (C : Cursor)
>       is
>          Directory_Entry_Ptr : constant Dir_Entry_Ptr := Element (C);
>       begin
>          Put (Simple_Name (Directory_Entry_Ptr.all));
>       end;
>    begin
>       DV.iterate (Display_Entry'access);
>    end;
>
> end List_By_Date;
>
> --
> dstan...@spam.o.matic.bigpond.net.au

You'll need to allocate a fresh directory entry to "fill in" with each
call to Get_Next_Entry, as George suggested.

I believe that declaring the pointer type as "access" rather than
"access all" will cause the allocated entries to be automatically
freed with the storage pool when the procedure exits.  (Of course in
this 1-procedure program that's irrelevant, but not if used as part of
something larger.)

This works fine on my system:

---------------------------------------
-- Displays directory entries in increasing date/time order

with Ada.Text_IO;            use Ada.Text_IO;
with Ada.Integer_Text_IO;    use Ada.Integer_Text_IO;
with Ada.Containers.Vectors;
with Ada.Directories;        use Ada.Directories;
with Ada.Calendar;           use Ada.Calendar; -- for comparing  date/
times

procedure List_By_Date is

   type Dir_Entry_Ptr is access Directory_Entry_Type;

   package Dir_Vectors is new Ada.Containers.Vectors (
      Positive,
      Dir_Entry_Ptr);
   use Dir_Vectors;

   DV : Vector;

begin

   -- collect the entries
   declare
      Directory : constant Filter_Type := (True, False, False);
      Ordinary_File : constant Filter_Type := (False, True, False);
      Results : Search_Type; -- used to hold the result of a search
   begin
      Start_Search
        (Results,
         Directory => Current_Directory,
         Pattern   => "", -- select all files
         Filter    => Directory or Ordinary_File);

      while More_Entries (Results) loop
         declare
            Directory_Entry : Dir_Entry_Ptr := new
Directory_Entry_Type;
         begin
            Get_Next_Entry (Results, Directory_Entry.all);
            DV.Append (Directory_Entry);
         end;
      end loop;

   end;

   -- sort the entries
   declare
      function My_Sorter (Left, Right : Dir_Entry_Ptr) return Boolean
is
      begin
         return Ada.Directories.Modification_Time (Left.all) <
                Ada.Directories.Modification_Time (Right.all);
      end My_Sorter;

      package Dir_Vector_Sorting is new Generic_Sorting (My_Sorter);

   begin
      Dir_Vector_Sorting.Sort (DV);
   end;

   -- display the entries
   declare
      procedure Display_Entry (C : Cursor) is
      begin
         Put_Line (Simple_Name (Element (C).all));
      end Display_Entry;
   begin
      DV.Iterate (Display_Entry'Access);
   end;

end List_By_Date;



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-06 18:09 ` Gene
@ 2008-07-06 19:18   ` Dmitry A. Kazakov
  2008-07-07 13:29     ` Gene
  2008-07-10  0:16   ` Dale Stanbrough
  1 sibling, 1 reply; 18+ messages in thread
From: Dmitry A. Kazakov @ 2008-07-06 19:18 UTC (permalink / raw)


On Sun, 6 Jul 2008 11:09:58 -0700 (PDT), Gene wrote:

> You'll need to allocate a fresh directory entry to "fill in" with each
> call to Get_Next_Entry, as George suggested.

I think it is not a good idea to have collections of Directory_Entry_Type.
Depending on the implementation, Directory_Entry_Type might use some system
resources, locked until Directory_Entry_Type finalization.

> I believe that declaring the pointer type as "access" rather than
> "access all" will cause the allocated entries to be automatically
> freed with the storage pool when the procedure exits.

Yes, storage pools is an excellent tool to construct containers of limited
objects. It is a pity that Ada.Containers does not use this opportunity.

Another solution, used in the Simple components, is to have specialized
containers of  pointers. The container becomes responsible to free pointed
elements upon removal or replacing.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-06 19:18   ` Dmitry A. Kazakov
@ 2008-07-07 13:29     ` Gene
  2008-07-07 14:15       ` Dmitry A. Kazakov
  0 siblings, 1 reply; 18+ messages in thread
From: Gene @ 2008-07-07 13:29 UTC (permalink / raw)


On Jul 6, 3:18 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Sun, 6 Jul 2008 11:09:58 -0700 (PDT), Gene wrote:
> > You'll need to allocate a fresh directory entry to "fill in" with each
> > call to Get_Next_Entry, as George suggested.
>
> I think it is not a good idea to have collections of Directory_Entry_Type.
> Depending on the implementation, Directory_Entry_Type might use some system
> resources, locked until Directory_Entry_Type finalization.
>

Really?  I can easily see why the "Search" structure would contain a
handle or lock, but it's hard to see why a directory entry would do
so.  At any rate, the GNAT implementation doesn't.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-07 13:29     ` Gene
@ 2008-07-07 14:15       ` Dmitry A. Kazakov
  2008-07-07 18:39         ` Gene
  0 siblings, 1 reply; 18+ messages in thread
From: Dmitry A. Kazakov @ 2008-07-07 14:15 UTC (permalink / raw)


On Mon, 7 Jul 2008 06:29:16 -0700 (PDT), Gene wrote:

> On Jul 6, 3:18�pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:

>> I think it is not a good idea to have collections of Directory_Entry_Type.
>> Depending on the implementation, Directory_Entry_Type might use some system
>> resources, locked until Directory_Entry_Type finalization.
> 
> Really?  I can easily see why the "Search" structure would contain a
> handle or lock, but it's hard to see why a directory entry would do
> so.

For example, in order to get a notification when the target gets changed
(or removed), or else in order to prevent such changes.

At least the choice to make Directory_Entry_Type limited indicates that it
is not just a "value."

> At any rate, the GNAT implementation doesn't.

Well, writing GNAT-specific programs is not a good idea either.

Anyways, if the collection were intended to contain directory item names,
then it would be better and cleaner to design it in just this way.
Ada.Container.Indefinite_Ordered_Maps : String -> File_Kind or a similar
collection would perfectly do the job.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-07 14:15       ` Dmitry A. Kazakov
@ 2008-07-07 18:39         ` Gene
  0 siblings, 0 replies; 18+ messages in thread
From: Gene @ 2008-07-07 18:39 UTC (permalink / raw)


On Jul 7, 10:15 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Mon, 7 Jul 2008 06:29:16 -0700 (PDT), Gene wrote:
> > On Jul 6, 3:18 pm, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
> >> I think it is not a good idea to have collections of Directory_Entry_Type.
> >> Depending on the implementation, Directory_Entry_Type might use some system
> >> resources, locked until Directory_Entry_Type finalization.
>
> > Really?  I can easily see why the "Search" structure would contain a
> > handle or lock, but it's hard to see why a directory entry would do
> > so.
>
> At least the choice to make Directory_Entry_Type limited indicates that it
> is not just a "value."
>

Great point.  Thanks.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-06 18:09 ` Gene
  2008-07-06 19:18   ` Dmitry A. Kazakov
@ 2008-07-10  0:16   ` Dale Stanbrough
  2008-07-10  7:31     ` Dmitry A. Kazakov
  2008-07-10 22:59     ` Gene
  1 sibling, 2 replies; 18+ messages in thread
From: Dale Stanbrough @ 2008-07-10  0:16 UTC (permalink / raw)


Gene <gene.ressler@gmail.com> wrote:


[as did others] a solution to my problem. Thanks!

My sticking point was in thinking an allocated limited object could not 
be reassigned a value. Apparently not true for a heap/storage pool 
allocated object.


Dale

-- 
dstanbro@spam.o.matic.bigpond.net.au



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-10  0:16   ` Dale Stanbrough
@ 2008-07-10  7:31     ` Dmitry A. Kazakov
  2008-07-10 22:59     ` Gene
  1 sibling, 0 replies; 18+ messages in thread
From: Dmitry A. Kazakov @ 2008-07-10  7:31 UTC (permalink / raw)


On Thu, 10 Jul 2008 00:16:06 GMT, Dale Stanbrough wrote:

> My sticking point was in thinking an allocated limited object could not 
> be reassigned a value. Apparently not true for a heap/storage pool 
> allocated object.

Well, they aren't reassigned, and there is no official "value" of a limited
object. Formally Get_Next_Entry changes the state of a Directory_Entry_Type
object, it does not assign it. 

However if the states of a limited object do not depend on anything else
outside, then they can be treated as a "values."

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-10  0:16   ` Dale Stanbrough
  2008-07-10  7:31     ` Dmitry A. Kazakov
@ 2008-07-10 22:59     ` Gene
  2008-07-11 22:06       ` Jeffrey R. Carter
  2008-07-12  7:53       ` Dmitry A. Kazakov
  1 sibling, 2 replies; 18+ messages in thread
From: Gene @ 2008-07-10 22:59 UTC (permalink / raw)


On Jul 9, 8:16 pm, Dale Stanbrough <MrNoS...@bigpoop.net.au> wrote:
> Gene <gene.ress...@gmail.com> wrote:
>
> [as did others] a solution to my problem. Thanks!
>

But as Dmitry pointed out, what I wrote has some portability risk.  To
avoid this, just copy the bits you need into your own (non-limited)
data structure.

with Ada.Text_IO;            use Ada.Text_IO;
with Ada.Integer_Text_IO;    use Ada.Integer_Text_IO;
with Ada.Containers.Vectors;
with Ada.Directories;        use Ada.Directories;
with Ada.Calendar;           use Ada.Calendar; -- for comparing  date/
times

procedure List_By_Date is

   type String_Ptr_Type is access String;
   type File_Info_Type is
      record
         Modification_Time : Time;
         Simple_Name : String_Ptr_Type; -- Freed with storage pool!
      end record;

   package File_Info_Vectors is
     new Ada.Containers.Vectors (Positive, File_Info_Type);
   use File_Info_Vectors;
   DV : Vector;

begin
   declare
      Directory     : constant Filter_Type := (True, False, False);
      Ordinary_File : constant Filter_Type := (False, True, False);
      Results        : Search_Type; -- used to hold the result of a
search
      Directory_Entry : Directory_Entry_Type;
   begin
      Start_Search(Results,
                   Directory => Current_Directory,
                   Pattern   => "", -- select all files
                   Filter    => Directory or Ordinary_File);

      while More_Entries (Results) loop
         Get_Next_Entry (Results, Directory_Entry);
         DV.Append(File_Info_Type'(
           Modification_Time => Modification_Time(Directory_Entry),
           Simple_Name => new String'(Simple_Name(Directory_Entry))));
      end loop;
   end;

   -- sort the entries
   declare
      function "<" (Left, Right : in File_Info_Type) return Boolean is
      begin
         return Left.Modification_Time < Right.Modification_Time;
      end "<";

      package Dir_Vector_Sorting is new Generic_Sorting ("<");
   begin
      Dir_Vector_Sorting.Sort (DV);
   end;

   -- display the entries
   declare
      procedure Display_Entry (C : Cursor) is
      begin
         Put_Line (Element (C).Simple_Name.all);
      end Display_Entry;
   begin
      DV.Iterate (Display_Entry'Access);
   end;

end List_By_Date;



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-10 22:59     ` Gene
@ 2008-07-11 22:06       ` Jeffrey R. Carter
  2008-07-12  2:45         ` Gene
  2008-07-12  7:53       ` Dmitry A. Kazakov
  1 sibling, 1 reply; 18+ messages in thread
From: Jeffrey R. Carter @ 2008-07-11 22:06 UTC (permalink / raw)


Gene wrote:
> 
> But as Dmitry pointed out, what I wrote has some portability risk.  To
> avoid this, just copy the bits you need into your own (non-limited)
> data structure.
> 
> with Ada.Text_IO;            use Ada.Text_IO;
> with Ada.Integer_Text_IO;    use Ada.Integer_Text_IO;
> with Ada.Containers.Vectors;
> with Ada.Directories;        use Ada.Directories;
> with Ada.Calendar;           use Ada.Calendar; -- for comparing  date/
> times
> 
> procedure List_By_Date is
> 
>    type String_Ptr_Type is access String;
>    type File_Info_Type is
>       record
>          Modification_Time : Time;
>          Simple_Name : String_Ptr_Type; -- Freed with storage pool!

I would recommend using Ada.Strings.Unbounded.Unbounded_String with its 
automatic and tested memory management over implementing new and untested memory 
allocation and management yourself.

-- 
Jeff Carter
"Well, a gala day is enough for me. I don't think
I can handle any more."
Duck Soup
93



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-11 22:06       ` Jeffrey R. Carter
@ 2008-07-12  2:45         ` Gene
  2008-07-12  4:41           ` Jeffrey R. Carter
  2008-07-12  8:02           ` Dmitry A. Kazakov
  0 siblings, 2 replies; 18+ messages in thread
From: Gene @ 2008-07-12  2:45 UTC (permalink / raw)


On Jul 11, 6:06 pm, "Jeffrey R. Carter"
<spam.jrcarter....@spam.acm.org> wrote:
> Gene wrote:
>
> > But as Dmitry pointed out, what I wrote has some portability risk.  To
> > avoid this, just copy the bits you need into your own (non-limited)
> > data structure.
>
> > with Ada.Text_IO;            use Ada.Text_IO;
> > with Ada.Integer_Text_IO;    use Ada.Integer_Text_IO;
> > with Ada.Containers.Vectors;
> > with Ada.Directories;        use Ada.Directories;
> > with Ada.Calendar;           use Ada.Calendar; -- for comparing  date/
> > times
>
> > procedure List_By_Date is
>
> >    type String_Ptr_Type is access String;
> >    type File_Info_Type is
> >       record
> >          Modification_Time : Time;
> >          Simple_Name : String_Ptr_Type; -- Freed with storage pool!
>
> I would recommend using Ada.Strings.Unbounded.Unbounded_String with its
> automatic and tested memory management over implementing new and untested memory
> allocation and management yourself.
>
> --
> Jeff Carter
> "Well, a gala day is enough for me. I don't think
> I can handle any more."
> Duck Soup
> 93- Hide quoted text -
>
> - Show quoted text -

Right.  I initially did it with UBS and changed it. Unbounded_String,
at least in the GNAT implementation, is a super heavyweight.  In this
case, you call Simple_Name to get a string and then convert it to an
unbounded string.  In Ada 95 you'd have to convert back to a simple
String for printing; fortunately that's fixed in 2005.  Nonetheless
the syntax and the compiled code are both unsatisfying.  Barnes seems
to agree:

... conversion between bounded and unbounded strings and the raw type
String is required rather a lot and is both ugly and inefficient.

I do not find that relying on a simple new' and storage pool for
release to be a very intimidating form of memory management.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-12  2:45         ` Gene
@ 2008-07-12  4:41           ` Jeffrey R. Carter
  2008-07-13 15:30             ` Gene
  2008-07-12  8:02           ` Dmitry A. Kazakov
  1 sibling, 1 reply; 18+ messages in thread
From: Jeffrey R. Carter @ 2008-07-12  4:41 UTC (permalink / raw)


Gene wrote:
> 
> Right.  I initially did it with UBS and changed it. Unbounded_String,
> at least in the GNAT implementation, is a super heavyweight.  In this
> case, you call Simple_Name to get a string and then convert it to an
> unbounded string.  In Ada 95 you'd have to convert back to a simple
> String for printing; fortunately that's fixed in 2005.  Nonetheless
> the syntax and the compiled code are both unsatisfying.  Barnes seems
> to agree:
> 
> ... conversion between bounded and unbounded strings and the raw type
> String is required rather a lot and is both ugly and inefficient.

Premature optimization is the root of all evil. In your little program, which 
gathers and displays some information, the overhead of Unbounded_String is not 
going to be a problem; in a larger system, only if it does prove to be the 
reason for not meeting the timing requirements should an alternative approach be 
considered.

I am currently working on a large, soft-real-time system which makes extensive 
use of Unbounded_String and uses GNAT Pro; we have no problem meeting our timing 
requirements.

> I do not find that relying on a simple new' and storage pool for
> release to be a very intimidating form of memory management.

There are many misconceptions about access types, storage pools, and memory 
management. I probably hold some of them. My understanding is that it is legal 
for the memory allocated for an access type such as you declared to not be 
reclaimed until the program ends (I welcome comments from the compiler writers 
out there). This is not a problem in your program, where the life of the access 
type ends at the same time as the life of the program. It probably would be a 
problem in a larger system that calls a similar subprogram repeatedly, expecting 
the memory to be reclaimed when the subprogram returns.

-- 
Jeff Carter
"Well, a gala day is enough for me. I don't think
I can handle any more."
Duck Soup
93



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-10 22:59     ` Gene
  2008-07-11 22:06       ` Jeffrey R. Carter
@ 2008-07-12  7:53       ` Dmitry A. Kazakov
  1 sibling, 0 replies; 18+ messages in thread
From: Dmitry A. Kazakov @ 2008-07-12  7:53 UTC (permalink / raw)


On Thu, 10 Jul 2008 15:59:30 -0700 (PDT), Gene wrote:
 
> procedure List_By_Date is
> 
>    type String_Ptr_Type is access String;
>    type File_Info_Type is
>       record
>          Modification_Time : Time;
>          Simple_Name : String_Ptr_Type; -- Freed with storage pool!
>       end record;
> 
>    package File_Info_Vectors is
>      new Ada.Containers.Vectors (Positive, File_Info_Type);

I am using a different design in such cases, which are a kind of cached
data store with sorted items.

I would make a descriptor type containing all data of an item:

   type File_Info (Length : Natural) is record
      Modification_Time : Time;
      Simple_Name : String (1..Length);
      ...
   end record;

File_Info can be allocated in an arena or mark-and-release pool. That is no
matter. Then comparison operations are defined on the pointers rather than
the descriptors:

   type File_Info_By_Date is access all File_Info;
   function "<" (Left, Right : File_Info_By_Date) return Boolean;

   type File_Info_By_Name is access all File_Info;
   function "<" (Left, Right : File_Info_By_Name) return Boolean;

   type File_Info_By_Size is access all File_Info;
   function "<" (Left, Right : File_Info_By_Size) return Boolean;

etc.

Then I would create ordered sets of File_Info_By_Date, File_Info_By_Name
and so on. All this I put into a controlled object which takes care about
inserting and removing items. Indexes of pointers are kept sorted. This is
exactly the design I used for a persistency layer.

(I don't use Ada.Containers, but I think this approach should work with
them too.)

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-12  2:45         ` Gene
  2008-07-12  4:41           ` Jeffrey R. Carter
@ 2008-07-12  8:02           ` Dmitry A. Kazakov
  1 sibling, 0 replies; 18+ messages in thread
From: Dmitry A. Kazakov @ 2008-07-12  8:02 UTC (permalink / raw)


On Fri, 11 Jul 2008 19:45:47 -0700 (PDT), Gene wrote:

> I do not find that relying on a simple new' and storage pool for
> release to be a very intimidating form of memory management.

Yes, if you put the pool into the object that manages the cache of file
items. There are advantages and disadvantages of arenas. One disadvantage
is that you should somehow know the pool size in advance. (I use segmented
pools for such cases with variable segment sizes.) Another disadvantage is
that arenas do not do well with controlled types.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-12  4:41           ` Jeffrey R. Carter
@ 2008-07-13 15:30             ` Gene
  2008-07-13 18:10               ` Jeffrey R. Carter
  2008-07-16 21:23               ` Simon Wright
  0 siblings, 2 replies; 18+ messages in thread
From: Gene @ 2008-07-13 15:30 UTC (permalink / raw)


On Jul 12, 12:41 am, "Jeffrey R. Carter"
<spam.jrcarter....@spam.acm.org> wrote:
> Gene wrote:
>
> > Right.  I initially did it with UBS and changed it. Unbounded_String,
> > at least in the GNAT implementation, is a super heavyweight.  In this
> > case, you call Simple_Name to get a string and then convert it to an
> > unbounded string.  In Ada 95 you'd have to convert back to a simple
> > String for printing; fortunately that's fixed in 2005.  Nonetheless
> > the syntax and the compiled code are both unsatisfying.  Barnes seems
> > to agree:
>
> > ... conversion between bounded and unbounded strings and the raw type
> > String is required rather a lot and is both ugly and inefficient.
>
> Premature optimization is the root of all evil.

Well, evil for sure, but _all_ evil is a bit dramatic. ;-)  I agree.
It is nice that 2005 has a Text_IO variant for UBS.  I had not
realized that before this discussion.  Thanks for making me read the
LRM.

In your little program, which
> I am currently working on a large, soft-real-time system which makes extensive
> use of Unbounded_String and uses GNAT Pro; we have no problem meeting our timing
> requirements.

You might want to be careful about this. I guess it depends how soft
soft is. Internally it looks like GNAT ends up calling gcc malloc/free
for UBS.  Implementations of malloc/free can have wildly varying
performance depending on current heap structure.  Your app may meet
time requirements today on test data and fail tomorrow because the
heap has fragmented in a different way.




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-13 15:30             ` Gene
@ 2008-07-13 18:10               ` Jeffrey R. Carter
  2008-07-16 21:23               ` Simon Wright
  1 sibling, 0 replies; 18+ messages in thread
From: Jeffrey R. Carter @ 2008-07-13 18:10 UTC (permalink / raw)


Gene wrote:
> 
> You might want to be careful about this. I guess it depends how soft
> soft is. Internally it looks like GNAT ends up calling gcc malloc/free
> for UBS.  Implementations of malloc/free can have wildly varying
> performance depending on current heap structure.  Your app may meet
> time requirements today on test data and fail tomorrow because the
> heap has fragmented in a different way.

We are aware of the potential problems with Unbounded_String, but so far we are 
in actual use without problems. Since Unbounded_String is, conceptually at 
least, just a controlled wrapper around a pointer to String, we would expect to 
have to deal with the same problems if we manipulated such pointers directly. If 
we do encounter problems, we will probably replace Unbounded_String with some 
sort of bounded string.

-- 
Jeff Carter
"What lazy lout left these wires all over the lawn?"
Poppy
98



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Using Ada.Containers.Vector and Limited Private types
  2008-07-13 15:30             ` Gene
  2008-07-13 18:10               ` Jeffrey R. Carter
@ 2008-07-16 21:23               ` Simon Wright
  1 sibling, 0 replies; 18+ messages in thread
From: Simon Wright @ 2008-07-16 21:23 UTC (permalink / raw)


Gene <gene.ressler@gmail.com> writes:

> You might want to be careful about this. I guess it depends how soft
> soft is. Internally it looks like GNAT ends up calling gcc
> malloc/free for UBS.  Implementations of malloc/free can have wildly
> varying performance depending on current heap structure.  Your app
> may meet time requirements today on test data and fail tomorrow
> because the heap has fragmented in a different way.

I can support this! malloc/free in VxWorks 5.5, for example, can
behave very badly if you have even a small leak amidst a lot of memory
churn.



^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2008-07-16 21:23 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-07-05 11:53 Using Ada.Containers.Vector and Limited Private types Dale Stanbrough
2008-07-05 15:42 ` george.priv
2008-07-06 18:09 ` Gene
2008-07-06 19:18   ` Dmitry A. Kazakov
2008-07-07 13:29     ` Gene
2008-07-07 14:15       ` Dmitry A. Kazakov
2008-07-07 18:39         ` Gene
2008-07-10  0:16   ` Dale Stanbrough
2008-07-10  7:31     ` Dmitry A. Kazakov
2008-07-10 22:59     ` Gene
2008-07-11 22:06       ` Jeffrey R. Carter
2008-07-12  2:45         ` Gene
2008-07-12  4:41           ` Jeffrey R. Carter
2008-07-13 15:30             ` Gene
2008-07-13 18:10               ` Jeffrey R. Carter
2008-07-16 21:23               ` Simon Wright
2008-07-12  8:02           ` Dmitry A. Kazakov
2008-07-12  7:53       ` Dmitry A. Kazakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox