comparison core.lua @ 87:9fea75b0927b

If deleting a history entry results in an empty player table, remove that as well. Change g_uniques to store player's name rather than index as the history field, and indirect through the byname table.
author Farmbuyer of US-Kilrogg <farmbuyer@gmail.com>
date Fri, 22 Jun 2012 00:58:59 +0000
parents 703bbe61d12d
children c9f955f9a285
comparison
equal deleted inserted replaced
86:703bbe61d12d 87:9fea75b0927b
521 addon.instance_tag = instance_tag -- grumble 521 addon.instance_tag = instance_tag -- grumble
522 addon.latest_instance = nil -- spelling reminder, assigned elsewhere 522 addon.latest_instance = nil -- spelling reminder, assigned elsewhere
523 523
524 -- Memoizing cache of unique IDs as we generate or search for them. Keys are 524 -- Memoizing cache of unique IDs as we generate or search for them. Keys are
525 -- the uniques, values are the following: 525 -- the uniques, values are the following:
526 -- 'history' active index into self.history 526 -- 'history' active player name in self.history
527 -- 'history_may' index into player's uniques list, CAN QUICKLY BE OUTDATED 527 -- 'history_may' index into player's uniques list, CAN QUICKLY BE OUTDATED
528 -- and will instantly be wrong after manual insertion 528 -- and will instantly be wrong after manual insertion
529 -- 'loot' active index into g_loot 529 -- 'loot' active index into g_loot
530 -- with all but the history entry optional. Values of g_uniqes.NOTFOUND 530 -- with all but the history entry optional. Values of g_uniqes.NOTFOUND
531 -- indicate a known missing status. Use g_uniques:RESET() to wipe the cache 531 -- indicate a known missing status. Use g_uniques:RESET() to wipe the cache
553 -- If it's active, try looking through that player's history first. 553 -- If it's active, try looking through that player's history first.
554 if L then 554 if L then
555 local hi,h = addon:get_loot_history (loot.person) 555 local hi,h = addon:get_loot_history (loot.person)
556 for ui,u in ipairs(h.unique) do 556 for ui,u in ipairs(h.unique) do
557 if k == u then 557 if k == u then
558 H, HU = hi, ui 558 H, HU = h.name, ui
559 break 559 break
560 end 560 end
561 end 561 end
562 else 562 else
563 -- No luck? Ugh, may have been reassigned and we're probing from 563 -- No luck? Ugh, may have been reassigned and we're probing from
564 -- older data. Search the rest of current realm's history. 564 -- older data. Search the rest of current realm's history.
565 for hi,h in ipairs(addon.history) do 565 for hi,h in ipairs(addon.history) do
566 for ui,u in ipairs(h.unique) do 566 for ui,u in ipairs(h.unique) do
567 if k == u then 567 if k == u then
568 H, HU = hi, ui 568 H, HU = h.name, ui
569 break 569 break
570 end 570 end
571 end 571 end
572 end 572 end
573 end 573 end
1324 end 1324 end
1325 return false, u 1325 return false, u
1326 end 1326 end
1327 addon.dprint('loot',"verified unique tag ("..u..")") 1327 addon.dprint('loot',"verified unique tag ("..u..")")
1328 else 1328 else
1329 -- Need to *find* an unused value. For now use a range of 1329 -- Need to *find* an unused value. For now use a range of J*10^4
1330 -- J*10^4 where J is Jenny's Constant. Thank you, xkcd.com/1047. 1330 -- where J is Jenny's Constant. Thank you, <xkcd.com/1047>.
1331 prefix = prefix or 'n' 1331 prefix = prefix or 'n'
1332 repeat 1332 repeat
1333 u = prefix .. random(8675309) 1333 u = prefix .. random(8675309)
1334 until g_uniques:TEST(u).history == g_uniques.NOTFOUND 1334 until g_uniques:TEST(u).history == g_uniques.NOTFOUND
1335 addon.dprint('loot',"created unique tag ("..u..")") 1335 addon.dprint('loot',"created unique tag ("..u..")")
2502 pprint('improv', "Um.", looti, g_loot[looti].unique, winning_index) 2502 pprint('improv', "Um.", looti, g_loot[looti].unique, winning_index)
2503 end 2503 end
2504 2504
2505 -- History 2505 -- History
2506 if hi ~= g_uniques.NOTFOUND then 2506 if hi ~= g_uniques.NOTFOUND then
2507 hi = addon.history.byname[hi]
2507 local hist = addon.history[hi] 2508 local hist = addon.history[hi]
2508 if ui and hist.unique[ui] == exist then 2509 if ui and hist.unique[ui] == exist then
2509 -- ui is valid 2510 -- ui is valid
2510 else 2511 else
2511 ui = nil 2512 ui = nil
2794 local before = GetAddOnMemoryUsage(nametag) 2795 local before = GetAddOnMemoryUsage(nametag)
2795 local trouble 2796 local trouble
2796 local count = 0 2797 local count = 0
2797 for hi,player in ipairs(self.history) do 2798 for hi,player in ipairs(self.history) do
2798 for ui,u in ipairs(player.unique) do 2799 for ui,u in ipairs(player.unique) do
2799 g_uniques[u] = { history = hi, history_may = ui } 2800 g_uniques[u] = { history = player.name, history_may = ui }
2800 count = count + 1 2801 count = count + 1
2801 end 2802 end
2802 end 2803 end
2803 for i,e in self:filtered_loot_iter('loot') do 2804 for i,e in self:filtered_loot_iter('loot') do
2804 if e.unique and e.unique ~= "" then 2805 if e.unique and e.unique ~= "" then
2888 local e = g_loot[lootindex] 2889 local e = g_loot[lootindex]
2889 if e.kind ~= 'loot' then return end 2890 if e.kind ~= 'loot' then return end
2890 2891
2891 local i,h = self:get_loot_history(e.person) 2892 local i,h = self:get_loot_history(e.person)
2892 local when = self:format_timestamp (g_today, e) 2893 local when = self:format_timestamp (g_today, e)
2894 assert(h.name==e.person)
2893 2895
2894 -- If any of these change, update the end of history_handle_disposition. 2896 -- If any of these change, update the end of history_handle_disposition.
2895 if (not e.unique) or (#e.unique==0) then 2897 if (not e.unique) or (#e.unique==0) then
2896 e.unique = e.id .. e.person .. when 2898 e.unique = e.id .. e.person .. when
2897 end 2899 end
2899 tinsert (h.unique, 1, U) 2901 tinsert (h.unique, 1, U)
2900 h.when[U] = when 2902 h.when[U] = when
2901 h.id[U] = e.id 2903 h.id[U] = e.id
2902 h.count[U] = e.count 2904 h.count[U] = e.count
2903 2905
2904 g_uniques[U] = { loot = lootindex, history = i } 2906 g_uniques[U] = { loot = lootindex, history = e.person }
2905 end 2907 end
2906 2908
2907 -- Create new history table based on current loot. 2909 -- Create new history table based on current loot.
2908 function addon:rewrite_history (realmname) 2910 function addon:rewrite_history (realmname)
2909 local r = assert(realmname) 2911 local r = assert(realmname)
2986 if cache.history == g_uniques.NOTFOUND then 2988 if cache.history == g_uniques.NOTFOUND then
2987 -- 1) loot an item, 2) clear old history, 3) reassign from current loot 2989 -- 1) loot an item, 2) clear old history, 3) reassign from current loot
2988 -- Bah. Anybody that tricky is already recoding the tables directly anyhow. 2990 -- Bah. Anybody that tricky is already recoding the tables directly anyhow.
2989 errtxt = "There is no record of %s ever having been assigned!" 2991 errtxt = "There is no record of %s ever having been assigned!"
2990 else 2992 else
2991 player_i = cache.history 2993 player_i = addon.history.byname[cache.history]
2992 player_h = addon.history[player_i] 2994 player_h = addon.history[player_i]
2993 if cache.history_may 2995 if cache.history_may
2994 and needle == player_h.unique[cache.history_may] 2996 and needle == player_h.unique[cache.history_may]
2995 then 2997 then
2996 return player_i, player_h, cache.history_may 2998 return player_i, player_h, cache.history_may
3080 -- from_h here is the formatted error text 3082 -- from_h here is the formatted error text
3081 self:Print(from_h .. " Loot will be reassigned, but history will NOT be updated.", e.itemlink) 3083 self:Print(from_h .. " Loot will be reassigned, but history will NOT be updated.", e.itemlink)
3082 end 3084 end
3083 else 3085 else
3084 -- XXX do some sanity checks here? from_name == from_h.name, etc? 3086 -- XXX do some sanity checks here? from_name == from_h.name, etc?
3087 -- If something were wrong at this point, what could we do?
3085 3088
3086 local U = tremove (from_h.unique, hist_i) 3089 local U = tremove (from_h.unique, hist_i)
3087 -- The loot master giveth... 3090 -- The loot master giveth...
3088 to_h.unique[#to_h.unique+1] = U 3091 to_h.unique[#to_h.unique+1] = U
3089 to_h.when[U] = from_h.when[U] 3092 to_h.when[U] = from_h.when[U]
3093 -- ...and the loot master taketh away. 3096 -- ...and the loot master taketh away.
3094 from_h.when[U] = nil 3097 from_h.when[U] = nil
3095 from_h.id[U] = nil 3098 from_h.id[U] = nil
3096 from_h.count[U] = nil 3099 from_h.count[U] = nil
3097 -- Blessed be the lookup cache of the loot master. 3100 -- Blessed be the lookup cache of the loot master.
3098 g_uniques[U] = { loot = index, history = to_i } 3101 g_uniques[U] = { loot = index, history = to_name }
3099 end 3102 end
3100 local from_person_class = e.person_class or from_h.person_class 3103 local from_person_class = e.person_class or from_h.person_class
3101 or (g_loot.raiders[from_name] and g_loot.raiders[from_name].class) 3104 or (g_loot.raiders[from_name] and g_loot.raiders[from_name].class)
3102 or select(2,_G.UnitClass(from_name)) 3105 or select(2,_G.UnitClass(from_name))
3103 e.person = to_name 3106 e.person = to_name
3140 assert(#u>0) 3143 assert(#u>0)
3141 tremove (player.unique, i) 3144 tremove (player.unique, i)
3142 player.when[u], player.id[u], player.count[u] = nil, nil, nil 3145 player.when[u], player.id[u], player.count[u] = nil, nil, nil
3143 g_uniques[u] = nil 3146 g_uniques[u] = nil
3144 addon.hist_clean = nil 3147 addon.hist_clean = nil
3148 return #player.unique
3145 end 3149 end
3146 3150
3147 -- Mirror of _addHistoryEntry. Arguments are either: 3151 -- Mirror of _addHistoryEntry. Arguments are either:
3148 -- E - loot entry 3152 -- E - loot entry
3149 -- U,ITEM - unique tag, and a name/itemlink for errors 3153 -- U,ITEM - unique tag, and a name/itemlink for errors
3150 -- Returns true on success. 3154 -- If this entry was the only one for that player, will also remove that
3151 function addon:_delHistoryEntry (first, second) 3155 -- player's tables from the history array.
3156 --
3157 -- On success, returns the number of remaining history entries for that
3158 -- player (potentially zero). On failure, returns nil+error.
3159 function addon:_delHistoryEntry (first, item)
3152 if type(first) == 'table' then 3160 if type(first) == 'table' then
3153 second = first.itemlink or second 3161 item = first.itemlink or item
3154 --elseif type(first) == 'string' then 3162 --elseif type(first) == 'string' then
3155 end 3163 end
3156 3164
3157 local from_i, from_h, hist_i = _history_by_loot_id (first, "delete") 3165 local from_i, from_h, hist_i = _history_by_loot_id (first, "delete")
3158 3166
3159 if not from_i then 3167 if not from_i then
3160 -- from_h is the formatted error text 3168 -- from_h is the formatted error text
3161 return nil, (from_h 3169 return nil, (from_h
3162 .." Loot will be deleted, but history will NOT be updated." 3170 .." Loot will be deleted, but history will NOT be updated."
3163 ):format(second) 3171 ):format(item)
3164 end 3172 end
3165 3173
3166 expunge (from_h, hist_i) 3174 local remaining = expunge (from_h, hist_i)
3167 return true 3175 if not remaining then
3176 return nil, "Something bizarre happening trying to delete "..item
3177 elseif remaining > 0 then
3178 return remaining
3179 end
3180 tremove (self.history, from_i)
3181 self:_build_history_names()
3182 return 0
3168 end 3183 end
3169 3184
3170 -- Any extra work for the "Mark as <x>" dropdown actions. The 3185 -- Any extra work for the "Mark as <x>" dropdown actions. The
3171 -- corresponding <x> will already have been assigned in the loot entry. 3186 -- corresponding <x> will already have been assigned in the loot entry.
3172 local deleted_cache = {} 3187 local deleted_cache = {}
3227 name_h.unique[#name_h.unique+1] = U 3242 name_h.unique[#name_h.unique+1] = U
3228 name_h.when[U] = c and c.when or when or date("%Y/%m/%d %H:%M",e.stamp) 3243 name_h.when[U] = c and c.when or when or date("%Y/%m/%d %H:%M",e.stamp)
3229 name_h.id[U] = e.id -- c.id 3244 name_h.id[U] = e.id -- c.id
3230 name_h.count[U] = c and c.count or e.count 3245 name_h.count[U] = c and c.count or e.count
3231 sort_player(name_h) 3246 sort_player(name_h)
3232 g_uniques[U] = { loot = index, history = name_i } 3247 g_uniques[U] = { loot = index, history = name }
3233 self.hist_clean = nil 3248 self.hist_clean = nil
3234 3249
3235 if c then flib.del(c) end 3250 if c then flib.del(c) end
3236 3251
3237 return 3252 return