Implement smart algorithm of avoiding OnCooldown

I really like this approach, as it has only one caveat: memory usage.
We need to keep in memory list of all packages that our account owns, which will result of N * 32bit extra memory usage, where N is equal to number of package licenses the account owns. This results in around 16 KB extra memory usage for my 4k account.
However, apart from that there are no real caveats as checking if we own given packageID is O(1) operation, and I think that apart from this extra memory footprint there can be more benefits of having this field in future, besides, my 16 KB is extreme case, as usually nobody goes that high. Ship it!
This commit is contained in:
JustArchi
2016-07-28 21:20:57 +02:00
parent 5611694b90
commit a90573e0ea
2 changed files with 29 additions and 1 deletions

View File

@@ -64,6 +64,7 @@ namespace ArchiSteamFarm {
private readonly CardsFarmer CardsFarmer;
private readonly ConcurrentHashSet<ulong> HandledGifts = new ConcurrentHashSet<ulong>();
private readonly ConcurrentHashSet<uint> OwnedPackageIDs = new ConcurrentHashSet<uint>();
private readonly SteamApps SteamApps;
private readonly SteamFriends SteamFriends;
private readonly SteamUser SteamUser;
@@ -185,6 +186,7 @@ namespace ArchiSteamFarm {
SteamApps = SteamClient.GetHandler<SteamApps>();
CallbackManager.Subscribe<SteamApps.FreeLicenseCallback>(OnFreeLicense);
CallbackManager.Subscribe<SteamApps.GuestPassListCallback>(OnGuestPassList);
CallbackManager.Subscribe<SteamApps.LicenseListCallback>(OnLicenseList);
SteamFriends = SteamClient.GetHandler<SteamFriends>();
CallbackManager.Subscribe<SteamFriends.ChatInviteCallback>(OnChatInvite);
@@ -971,7 +973,8 @@ namespace ArchiSteamFarm {
}
bool alreadyHandled = false;
foreach (Bot bot in Bots.Values.Where(bot => (bot != this) && bot.SteamClient.IsConnected)) {
foreach (Bot bot in Bots.Values.Where(bot => (bot != this) && bot.SteamClient.IsConnected && result.Items.Keys.Any(packageID => !bot.OwnedPackageIDs.Contains(packageID)))) {
ArchiHandler.PurchaseResponseCallback otherResult = await bot.ArchiHandler.RedeemKey(key).ConfigureAwait(false);
if (otherResult == null) {
response.Append(Environment.NewLine + "<" + bot.BotName + "> Key: " + key + " | Status: Timeout!");
@@ -1619,6 +1622,21 @@ namespace ArchiSteamFarm {
}
}
private void OnLicenseList(SteamApps.LicenseListCallback callback) {
if (callback?.LicenseList == null) {
Logging.LogNullError(nameof(callback) + " || " + nameof(callback.LicenseList), BotName);
return;
}
OwnedPackageIDs.Clear();
foreach (SteamApps.LicenseListCallback.License license in callback.LicenseList) {
OwnedPackageIDs.Add(license.PackageID);
}
OwnedPackageIDs.TrimExcess();
}
private void OnChatInvite(SteamFriends.ChatInviteCallback callback) {
if ((callback?.ChatRoomID == null) || (callback.PatronID == null)) {
Logging.LogNullError(nameof(callback) + " || " + nameof(callback.ChatRoomID) + " || " + nameof(callback.PatronID), BotName);

View File

@@ -100,6 +100,16 @@ namespace ArchiSteamFarm {
}
}
public void TrimExcess() {
Lock.EnterWriteLock();
try {
HashSet.TrimExcess();
} finally {
Lock.ExitWriteLock();
}
}
public void Dispose() => Lock.Dispose();
public void CopyTo(T[] array, int arrayIndex) {