Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(*): Method.Random[Key] behavior #269

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

RealShadowNova
Copy link
Member

@RealShadowNova RealShadowNova commented Jun 30, 2023

packages/maria/src/lib/MariaProvider.ts Outdated Show resolved Hide resolved
packages/sqlite/src/lib/SQLiteProvider.ts Outdated Show resolved Hide resolved
@WilsontheWolf
Copy link
Member

Looks good other than the issues above. Will have to make sure the tests pass.

@codecov
Copy link

codecov bot commented Jul 1, 2023

Codecov Report

Merging #269 (dd7f4e0) into main (dde9733) will increase coverage by 5.41%.
The diff coverage is 92.30%.

@@            Coverage Diff             @@
##             main     #269      +/-   ##
==========================================
+ Coverage   88.11%   93.52%   +5.41%     
==========================================
  Files           3        2       -1     
  Lines        1228     1019     -209     
  Branches      218      211       -7     
==========================================
- Hits         1082      953     -129     
+ Misses         80       39      -41     
+ Partials       66       27      -39     
Impacted Files Coverage Δ
packages/mongo/src/lib/MongoProvider.ts 93.50% <92.30%> (ø)

... and 4 files with indirect coverage changes

WilsontheWolf
WilsontheWolf previously approved these changes Jul 8, 2023
Copy link
Member

@WilsontheWolf WilsontheWolf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its okay

@WilsontheWolf WilsontheWolf force-pushed the fix/random-behaviour branch from 9f04fce to 68f2e4b Compare July 8, 2023 23:35
@WilsontheWolf WilsontheWolf marked this pull request as ready for review July 8, 2023 23:36
Copy link
Member

@dan-online dan-online left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of optimization questions

packages/json/src/lib/JSONProvider.ts Show resolved Hide resolved
payload.data.push(this.cache.get(key)!);
}
} else {
if (unique) {
const randomKeys = new Set<string>();

while (randomKeys.size < count) randomKeys.add(keys[Math.floor(Math.random() * keys.length)]);

for (const key of randomKeys) payload.data.push(this.cache.get(key)!);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to not need 2 loops here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could probably just payload.data = randomKeys

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to get the value with the keys, so yes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could probably get the key and fetch the value in the same loop though

payload.data.push((await this.handler.get(key))!);
}
} else {
if (unique) {
const randomKeys = new Set<string>();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does mariadb have any way to query random that would be faster than this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like it does have some kind of random query but its somehow worse than ours
https://mariadb.com/kb/en/rand/

Note, however, that this technique should never be used on a large table as it will be extremely slow. MariaDB will read all rows in the table, generate a random value for each of them, order them, and finally will apply the LIMIT clause.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we test this, it's possible while not the best it's better than the current solution

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean you can. My Maria doesn't work.
However just based off that description, it sounds to me like that is slower. It has to fetch all the keys, generate a random value for each key in the table, sort them and then choose the top x
Whereas ours is fetch all the keys, and repeat the amount of times we need to get, picking a random index

packages/mongo/src/lib/MongoProvider.ts Outdated Show resolved Hide resolved
payload.data.push((await this.handler.get(key))!);
}
} else {
if (unique) {
const randomKeys = new Set<string>();

while (randomKeys.size < count) randomKeys.add(keys[Math.floor(Math.random() * keys.length)]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as Maria, any cool database things we can do to make this more optimized?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the same as maria, where it can generate a random number, but not efficently get random keys.
https://www.techonthenet.com/postgresql/functions/random.php

if (unique) {
const randomKeys = new Set<string>();

while (randomKeys.size < docCount) randomKeys.add(keys.data[Math.floor(Math.random() * keys.data.length)]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm very sure redis has a random way of getting documents

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

@WilsontheWolf WilsontheWolf Jul 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm this appears to be for a set stored in redis. There is randomKey but it just gets one so its probably just as simple to do this (https://redis.io/commands/randomkey/)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dan-online can you do this, this is your provider after all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep of course

payload.data.push(this.handler.get(key)!);
}
} else {
if (unique) {
const randomKeys = new Set<string>();

while (randomKeys.size < count) randomKeys.add(keys[Math.floor(Math.random() * keys.length)]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same optimization question

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems the same as the other 2 sql languages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants