From d7a310a7c0c01c3e36d44b9fdf9f7a2c830a9aa9 Mon Sep 17 00:00:00 2001 From: Manuel Simon Hirsig Date: Mon, 8 Feb 2016 04:13:54 +0100 Subject: [PATCH] new history, changed sorting of names for autocompletion --- Aux-AddOn.toc | 2 +- completion.lua | 37 ++++++------ history.lua | 150 ++++++++++++++++++++++-------------------------- persistence.lua | 19 ++---- slash.lua | 6 ++ test.lua | 16 ++++++ util.lua | 4 +- 7 files changed, 119 insertions(+), 115 deletions(-) diff --git a/Aux-AddOn.toc b/Aux-AddOn.toc index b345a28..f86f801 100644 --- a/Aux-AddOn.toc +++ b/Aux-AddOn.toc @@ -1,7 +1,7 @@ ## Interface: 11200 ## Title: Aux ## Notes: A lightweight addon designed to help manage auctions -## SavedVariablesPerCharacter: aux_recent_searches, aux_favorite_searches, aux_price_per_unit, aux_scale +## SavedVariablesPerCharacter: aux_recent_searches, aux_favorite_searches, aux_price_per_unit, aux_market_value_type, aux_scale ## SavedVariables: aux_database, aux_auctionable_items slash.lua diff --git a/completion.lua b/completion.lua index b0e3cce..36c725b 100644 --- a/completion.lua +++ b/completion.lua @@ -1,6 +1,22 @@ local m = {} Aux.completion = m +do + local sorted_item_names + function m.sorted_item_names() + if not sorted_item_names then + sorted_item_names = {} + for key, value in Aux.static.auctionable_items do + if type(key) == 'number' then + tinsert(sorted_item_names, value.name) + end + end + sort(sorted_item_names, function(a, b) return strlen(a) < strlen(b) or (strlen(a) == strlen(b) and a < b) end) + end + return sorted_item_names + end +end + function m:complete() if IsControlKeyDown() then -- TODO problem is ctrl-v, maybe find a better solution return @@ -75,15 +91,8 @@ function m:complete() -- item names if not completed_filter_string then - local item_filters = {} - for key, value in Aux.static.auctionable_items do - if type(key) == 'number' then - tinsert(item_filters, value.name..'/exact') - end - end - sort(item_filters) - for _, item_name in ipairs(item_filters) do - tinsert(options, item_name) + for _, name in ipairs(m.sorted_item_names()) do + tinsert(options, name..'/exact') end end @@ -107,15 +116,7 @@ function m:complete_item() local text = this:GetText() - local item_names = {} - for key, value in Aux.static.auctionable_items do - if type(key) == 'number' then - tinsert(item_names, value.name) - end - end - sort(item_names) - - for _, item_name in ipairs(item_names) do + for _, item_name in ipairs(m.sorted_item_names()) do if string.sub(strupper(item_name), 1, strlen(text)) == strupper(text) then this:SetText(strlower(item_name)) this:HighlightText(strlen(text), -1) diff --git a/history.lua b/history.lua index fde3cfb..e131066 100644 --- a/history.lua +++ b/history.lua @@ -3,53 +3,59 @@ Aux.history = public private.PUSH_INTERVAL = 57600 -local item_records, next_push +aux_market_value_type = 'buyout' -function private.encode_item_records(item_records) - local record_strings = {} - for item_key, record in pairs(item_records) do - tinsert(record_strings, private.encode_item_record(item_key, record)) - end - return Aux.persistence.serialize(record_strings, '|') +local data + +function private.load_data() + local dataset = Aux.persistence.load_dataset() + dataset.history = dataset.history or { + item_records = {}, + next_push = time() + private.PUSH_INTERVAL, + } + return dataset.history end -function private.encode_item_record(item_key, record) +function public.on_login() + data = private.load_data() + for item_key, _ in pairs(data.item_records) do + data.item_records[item_key] = private.deserialize_item_record(data.item_records[item_key]) + end +end + +function public.on_logout() + for item_key, _ in pairs(data.item_records) do + data.item_records[item_key] = private.serialize_item_record(data.item_records[item_key]) + end +end + +function private.serialize_item_record(item_record) return Aux.persistence.serialize({ - item_key, - Aux.persistence.serialize(record.daily_bid_values, ';'), - Aux.persistence.serialize(record.daily_buyout_values, ';'), - Aux.persistence.serialize(record.bids_of_today:values(), ';'), - Aux.persistence.serialize(record.buyouts_of_today:values(), ';'), + Aux.persistence.serialize(item_record.daily_bid_values, ';'), + Aux.persistence.serialize(item_record.daily_buyout_values, ';'), + Aux.persistence.serialize(item_record.bids_of_today:values(), ';'), + Aux.persistence.serialize(item_record.buyouts_of_today:values(), ';'), }, '#') end -function private.decode_item_records(data_string) - local item_records = {} - for _, record_string in Aux.persistence.deserialize(data_string, '|') do - local item_key, record = private.decode_item_record(record_string) - item_records[item_key] = record - end - return item_records -end - -function private.decode_item_record(data_string) +function private.deserialize_item_record(data_string) local fields = Aux.persistence.deserialize(data_string, '#') local bids_of_today = Aux.util.set() - bids_of_today:add_all(Aux.util.map(Aux.persistence.deserialize(fields[4], ';'), function(value) + bids_of_today:add_all(Aux.util.map(Aux.persistence.deserialize(fields[3], ';'), function(value) return tonumber(value) end)) local buyouts_of_today = Aux.util.set() - buyouts_of_today:add_all(Aux.util.map(Aux.persistence.deserialize(fields[5], ';'), function(value) + buyouts_of_today:add_all(Aux.util.map(Aux.persistence.deserialize(fields[4], ';'), function(value) return tonumber(value) end)) - return fields[1], { - daily_bid_values = Aux.util.map(Aux.persistence.deserialize(fields[2], ';'), function(value) + return { + daily_bid_values = Aux.util.map(Aux.persistence.deserialize(fields[1], ';'), function(value) return tonumber(value) end), - daily_buyout_values = Aux.util.map(Aux.persistence.deserialize(fields[3], ';'), function(value) + daily_buyout_values = Aux.util.map(Aux.persistence.deserialize(fields[2], ';'), function(value) return tonumber(value) end), bids_of_today = bids_of_today, @@ -57,38 +63,36 @@ function private.decode_item_record(data_string) } end -function public.on_login() - local dataset = Aux.persistence.load_dataset() - local fields = Aux.persistence.deserialize(dataset.history, '/') - next_push = tonumber(fields[1]) or time() + private.PUSH_INTERVAL - item_records = private.decode_item_records(fields[2]) -end - -function public.on_logout() - local dataset = Aux.persistence.load_dataset() - dataset.history = Aux.util.join({ next_push, private.encode_item_records(item_records) }, '/') -end - function private.new_item_record() return { daily_bid_values = {}, daily_buyout_values = {}, bids_of_today = Aux.util.set(), buyouts_of_today = Aux.util.set() } end +function private.price_class(price) + return Aux.round(math.log(price) / math.log(1.1)) +end + +function private.price_class_price(class) + return 1.1^class +end + function public.process_auction(auction_info) - if next_push < time() then + if data.next_push < time() then private.push_data() end if auction_info.high_bid > 0 then - item_records[auction_info.item_key] = item_records[auction_info.item_key] or private.new_item_record() + data.item_records[auction_info.item_key] = data.item_records[auction_info.item_key] or private.new_item_record() local bid = Aux.round(auction_info.high_bid / auction_info.aux_quantity) - item_records[auction_info.item_key].bids_of_today:add(bid) + data.item_records[auction_info.item_key].bids_of_today:add(bid) +-- data.item_records[auction_info.item_key].bids_of_today:add(private.price_class(auction_info.high_bid / auction_info.aux_quantity)) end if auction_info.buyout_price > 0 then - item_records[auction_info.item_key] = item_records[auction_info.item_key] or private.new_item_record() + data.item_records[auction_info.item_key] = data.item_records[auction_info.item_key] or private.new_item_record() local buyout = Aux.round(auction_info.buyout_price / auction_info.aux_quantity) - item_records[auction_info.item_key].buyouts_of_today:add(buyout) + data.item_records[auction_info.item_key].buyouts_of_today:add(buyout) +-- data.item_records[auction_info.item_key].buyouts_of_today:add(private.price_class(auction_info.buyout_price / auction_info.aux_quantity)) end end @@ -98,21 +102,27 @@ end --end function public.market_value(item_key) - local record = item_records[item_key] + local record = data.item_records[item_key] if not record then return end - if getn(record.daily_buyout_values) == 0 then - return private.daily_buyout_value(item_key) + local daily_values = aux_market_value_type == 'buyout' and record.daily_buyout_values or record.daily_bid_values + + if getn(daily_values) == 0 then + if aux_market_value_type == 'buyout' then + return private.daily_buyout_value(item_key) + elseif aux_market_value_type == 'bid' then + return private.daily_bid_value(item_key) + end else - return private.median(record.daily_buyout_values) + return private.median(daily_values) end end function private.daily_bid_value(item_key) - local prices = item_records[item_key].bids_of_today:values() + local prices = data.item_records[item_key].bids_of_today:values() if getn(prices) == 0 then return @@ -123,13 +133,15 @@ function private.daily_bid_value(item_key) local cutoff = ceil(getn(prices) * 0.2) for i=1,cutoff do acc = acc + prices[i] +-- acc = acc + private.price_class_price(prices[i]) end return acc / cutoff end function private.daily_buyout_value(item_key) - local prices = item_records[item_key].buyouts_of_today:values() + local data = private.load_data() + local prices = data.item_records[item_key].buyouts_of_today:values() if getn(prices) == 0 then return @@ -140,36 +152,12 @@ function private.daily_buyout_value(item_key) local cutoff = ceil(getn(prices) * 0.2) for i=1,cutoff do acc = acc + prices[i] +-- acc = acc + private.price_class_price(prices[i]) end return acc / cutoff end ---function private.daily_market_value(histogram) --- --- local auction_count = 0 --- for _, frequency in ipairs(histogram) do --- auction_count = auction_count + frequency --- end --- --- if auction_count == 0 then --- return 0 --- end --- --- -- average of lowest 25% --- local sum, count = 0, 0 --- local limit = auction_count * 0.25 --- for i, frequency in ipairs(histogram) do --- local limited_frequency = min(frequency, limit - count) --- sum = sum + 1.1 ^ (i - 1) * 1.05 * limited_frequency --- count = count + limited_frequency --- if count >= limit then --- break --- end --- end --- return sum / limit ---end - function private.median(list) if getn(list) == 0 then return @@ -185,9 +173,9 @@ function private.median(list) return (sorted_list[floor(middle)] + sorted_list[ceil(middle)]) / 2 end -function private.push_data() +function public.push_data() - for item_key, record in pairs(item_records) do + for item_key, record in pairs(data.item_records) do local daily_bid_value = private.daily_bid_value(item_key) if daily_bid_value then @@ -196,7 +184,7 @@ function private.push_data() while getn(record.daily_bid_values) > 11 do tremove(record.daily_bid_values, 1) end - record.bids_of_today = {} + record.bids_of_today = Aux.util.set() local daily_buyout_value = private.daily_buyout_value(item_key) if daily_buyout_value then @@ -205,9 +193,9 @@ function private.push_data() while getn(record.daily_buyout_values) > 11 do tremove(record.daily_buyout_values, 1) end - record.buyouts_of_today = {} + record.buyouts_of_today = Aux.util.set() end - next_push = time() + private.PUSH_INTERVAL + data.next_push = time() + private.PUSH_INTERVAL end \ No newline at end of file diff --git a/persistence.lua b/persistence.lua index 7aecfe2..cf5bf32 100644 --- a/persistence.lua +++ b/persistence.lua @@ -1,17 +1,9 @@ -local DATABASE_VERSION = 0 - local private, public = {}, {} Aux.persistence = public aux_database = {} function public.on_load() - private.perform_migration(aux_database) - aux_database.version = DATABASE_VERSION -end - -function private.perform_migration() - end function private.get_dataset_key() @@ -30,13 +22,14 @@ function public.serialize(data, separator, compactor) local data_string = '' local i = 1 while i <= getn(data) do - local element, count = data[i], 0 - repeat + local element, count = data[i], 1 + while compactor and data[i + 1] == element do count = count + 1 i = i + 1 - until (not compactor) or data[i] ~= element - local part = (count > 1 and compactor) and element..compactor..count or element - data_string = data_string..(data_string == '' and '' or separator)..part + end + local part = count > 1 and element..compactor..count or element + data_string = data_string..(i == 1 and '' or separator)..part + i = i + 1 end return data_string diff --git a/slash.lua b/slash.lua index a06e669..a31b6d5 100644 --- a/slash.lua +++ b/slash.lua @@ -11,5 +11,11 @@ function SlashCmdList.AUX(parameter) elseif parameter == 'delete item cache' then aux_auctionable_items = nil Aux.log('Item cache deleted; falling back to the default.') + elseif parameter == 'market bid' then + aux_market_value_type = 'bid' + Aux.log('Set Market Value to bid based.') + elseif parameter == 'market buyout' then + aux_market_value_type = 'buyout' + Aux.log('Set Market Value to buyout based.') end end \ No newline at end of file diff --git a/test.lua b/test.lua index f1308ed..23849db 100644 --- a/test.lua +++ b/test.lua @@ -1,6 +1,22 @@ local m = {} Aux.test = m +function m.test_history() + for i=1,5000 do + for j=1, 100 do + Aux.history.process_auction({item_key = i..':0', buyout_price = j, high_bid = j, aux_quantity=1}) + end + end +end + +function m.key_count(table) + local count = 0 + for _, _ in pairs(table) do + count = count + 1 + end + return count +end + --StaticPopupDialogs["CANCEL_AUCTION"] = { -- text = TEXT(CANCEL_AUCTION_CONFIRMATION), -- button1 = TEXT(ACCEPT), diff --git a/util.lua b/util.lua index 1608112..191f5f6 100644 --- a/util.lua +++ b/util.lua @@ -258,7 +258,7 @@ function Aux.util.set() function self:add_all(values) for _, value in ipairs(values) do - self.add(value) + self:add(value) end end @@ -268,7 +268,7 @@ function Aux.util.set() function self:remove_all(values) for _, value in ipairs(values) do - self.remove(value) + self:remove(value) end end