PageRenderTime 20ms CodeModel.GetById 12ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lib/storage/low_level/string_recycling_pool.e

http://github.com/tybor/Liberty
Specman e | 157 lines | 106 code | 12 blank | 39 comment | 9 complexity | 49b0e1379abca0a0698258c74393f11c MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4class STRING_RECYCLING_POOL
  5   --
  6   -- Remember that STRING_RECYCLING_ITEM is expanded. It explains that some algorithms look like they could
  7   -- be simplified. In fact they '''cannot'''.
  8   --
  9
 10insert
 11   PLATFORM
 12      export
 13         {STRING_RECYCLING_POOL} all
 14      end
 15   MEMORY
 16      export
 17         {STRING_RECYCLING_POOL} all
 18      end
 19   STRING_HANDLER
 20      export
 21         {STRING_RECYCLING_POOL} all
 22      end
 23
 24create {ANY}
 25   make
 26
 27feature {ANY}
 28   new: STRING
 29         -- A brand new STRING with a small default capacity.
 30      do
 31         Result := best_fit(32)
 32      ensure
 33         Result.is_empty
 34      end
 35
 36   best_fit (capacity: INTEGER): STRING
 37         -- A STRING with a capacity at least as great as the given `capacity'.
 38      local
 39         i: INTEGER; gc: BOOLEAN
 40         item: STRING_RECYCLING_ITEM
 41      do
 42         gc := collecting
 43         collection_off
 44         if not strings.is_empty then
 45            item.set_capacity(capacity)
 46            i := items_comparator.insert_index(strings, item)
 47            if strings.valid_index(i) then
 48               from
 49                  Result := strings.item(i).item
 50               until
 51                  (Result /= Void and then Result.capacity >= capacity) or else i = strings.lower
 52               loop
 53                  i := i - 1
 54                  Result := strings.item(i).item
 55               end
 56               if Result /= Void then
 57                  -- remember STRING_RECYCLING_ITEM is expanded
 58                  item := strings.item(i)
 59                  item.set_item(Void)
 60                  strings.put(item, i)
 61                  if Result.capacity < capacity then
 62                     -- Rmk, 2015-12-20: wouldn't it be good to have
 63                     -- the GC active already here?
 64                     Result.ensure_capacity(capacity)
 65                  end
 66               end
 67            end
 68         end
 69         if gc then
 70            -- restore the GC ''before'' creating Result (if need be) to let it do its work
 71            collection_on
 72         end
 73         if Result = Void then
 74            create Result.make(capacity)
 75         end
 76      ensure
 77         Result.is_empty
 78         Result.capacity >= capacity
 79      end
 80
 81   new_twin (string: STRING): STRING
 82         -- A copy of the given `string'.
 83      require
 84         string /= Void
 85      do
 86         Result := best_fit(string.count)
 87         Result.copy(string)
 88      ensure
 89         Result /= string
 90         Result.is_equal(string)
 91      end
 92
 93   recycle (string: STRING)
 94         -- Recycles the `string'. Note that you should not use the `string' again ''(don't keep any reference
 95         -- on it)'', but use `new', `best_fit' or `new_twin' to obtain a new STRING.
 96      local
 97         i: INTEGER
 98         item: STRING_RECYCLING_ITEM
 99      do
100         -- I think there is no need to stop the GC
101         string.recycle
102         recycling_item.set_item(string)
103         if strings.is_empty then
104            strings.add_last(recycling_item)
105            recycling_item := item -- a brand new one (because we need to reset the weak reference)
106         else
107            i := items_comparator.insert_index(strings, recycling_item)
108            if strings.valid_index(i) and then strings.item(i).item = Void then
109               -- remember STRING_RECYCLING_ITEM is expanded
110               item := strings.item(i)
111               item.set_item(string)
112               strings.put(item, i)
113               recycling_item.set_item(Void) -- will be reused
114            else
115               strings.add(item, i)
116               recycling_item := item -- a brand new one (because we need to reset the weak reference)
117            end
118         end
119      end
120
121feature {}
122   recycling_item: STRING_RECYCLING_ITEM
123
124   strings: FAST_ARRAY[STRING_RECYCLING_ITEM]
125         -- The recycled strings
126
127   make
128      do
129         create strings.make(0)
130      end
131
132   items_comparator: STRING_RECYCLING_ITEM_SORTER
133
134invariant
135   items_comparator.is_sorted(strings)
136
137end -- class STRING_RECYCLING_POOL
138--
139-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
140--
141-- Permission is hereby granted, free of charge, to any person obtaining a copy
142-- of this software and associated documentation files (the "Software"), to deal
143-- in the Software without restriction, including without limitation the rights
144-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
145-- copies of the Software, and to permit persons to whom the Software is
146-- furnished to do so, subject to the following conditions:
147--
148-- The above copyright notice and this permission notice shall be included in
149-- all copies or substantial portions of the Software.
150--
151-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
152-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
153-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
154-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
155-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
156-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
157-- THE SOFTWARE.