View Single Post
07-07-19, 12:53 PM   #10
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,322
Originally Posted by doofus View Post
5) I tried to use wipe() but it failed because it does not help with tables inside tables.
Here's a drycoded example of table.wipe() that runs recursively and preserves links to nested tables.
Lua Code:
  1. local NestSafeWipe; do--    function NestSafeWipe(tbl)
  2. --  Local References (finds these faster than calling from global)
  3.     local pairs=pairs;
  4.     local table_insert=table.insert;
  5.     local table_remove=table.remove;
  6.     local table_wipe=table.wipe;
  7.     local type=type;
  8.  
  9. --  Local Variables (mitigates memory usage if used often)
  10.     local SeenTables={};--  Helps keep track of recursion and looped references (don't want to clean what we've alreay cleaned, also prevents infinite loops)
  11.     local SavedLinks={};
  12.     local TableQueue={};
  13.  
  14.     function NestSafeWipe(tbl)
  15.         SeenTables[tbl]=true;-- Mark table as "seen"
  16.         table_insert(TableQueue,tbl);-- Add current table to queue (to initiate loop)
  17.  
  18.         repeat
  19.             local curtbl=table_remove(TableQueue);--    Fetch from queue (doesn't matter which end)
  20.  
  21.             for key,val in pairs(curtbl) do--   Find nested tables
  22.                 if type(val)=="table" then
  23.                     SavedLinks[key]=val;--  Save key and table
  24.                     if not SeenTables[val] then--   Queue if not "seen"
  25.                         SeenTables[val]=true;-- Mark as "seen"
  26.                         table_insert(TableQueue,val);-- Add to queue
  27.                     end
  28.                 end
  29.             end
  30.  
  31.             table_wipe(curtbl);--   Wipe current table
  32.             for key,val in pairs(SavedLinks) do curtbl[key]=val; end--  Restore nested tables
  33.             table_wipe(SavedLinks)--    Done with this data
  34.         until #TableQueue<=0--  Exits when queue is empty
  35.         table_wipe(SeenTables);--   Done with this data
  36.     end
  37. end
Note: The outer do...end is used to explicitly define a variable scope to prevent accidental tampering with the function's persistent variables. To allow the function's presence outside this scope, the function prototype is defined immediately preceding it.



Originally Posted by doofus View Post
It also makes the code cumbersome and weird to read.
Think of the languages that don't have a GC and require complex memory structures to be allocated and freed manually. "Just run the GC more" is a poor excuse for not optimizing your code.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 07-07-19 at 01:10 PM.
  Reply With Quote