#development

1 messages · Page 250 of 1

sharp geyser
#

I see

#

Anyway

#

is it safe to just call _env.Dispose() in my own Dispose method

scenic kelp
#

i think so?

#

if you're writing a wrapper then presumably you have ownership of the resource the whole time so there's no way for it to escape

#

like your wrapper won't give other parts of the code access to the raw db underneath

sharp geyser
#

fair enough

#

Alrighty well, thanks a lot!

scenic kelp
#

ofc i love yapping about c# <3

sharp geyser
#

I am honestly getting more interested in C#

#

dk if you saw me yapping about it, but I have recently taken on the hobby of writing rust plugins (the game not the language)

#

so C# has become my new cup of tea, only thing is my code is hardly performant

#

I wrote something that while worked, was definitely the worst possible way to code it

#

It used multiple loops, some even nested, a lot of if statements that caused other loops

frosty gale
#

i dont think c# has a borrow checker from what ive heard

wheat mesa
#

I’m going to be primarily a C#/ASP.NET developer for my new job and I’m so glad they don’t use dogshit frameworks

naive pulsar
#
const Topgg = require("@top-gg/sdk")
const express = require("express")

const app = express()

const webhook = new Topgg.Webhook("your webhook auth")

app.post("/dblwebhook", webhook.listener(vote => {
  // vote will be your vote object, e.g
  console.log(vote.user) // 395526710101278721 < user who voted\

  // You can also throw an error to the listener callback in order to resend the webhook after a few seconds
}))

app.listen(80)

how i can get my webhook auth

#

no

#

don't ask me for click unknow links please !

#

I don't know, your profile is strange, your server is strange, everything is strange. Thank you for your help

#

No, I just have a mind that thinks someone sent me a server with about 70 people, the same pfp and the same name, and you also sent a strange link asking me to enter the server? Look if you wanna help help

shell tundra
#

do not contact them @naive pulsar

#

@oak cliff scammer @gray plume

#

deleting your messages won't do anything you realise we have logs? @gray plume

naive pulsar
shell tundra
#

they're a scammer, suit yourself

sharp geyser
#

Dont think thats what they meant

#

Also, i already pinged a mod about that exact person

#

how are they still here

#

💀

shell tundra
#

insane

deft wolf
#

crazy

shell tundra
#

reported internally, someone will see

deft wolf
#

We need more mods KEKW

naive pulsar
shell tundra
#

lmao

warm surge
shell tundra
#

no

shell tundra
#

they'll be banned anyway no point

warm surge
naive pulsar
#

http://yourserverip:port/dblwebhook so if i using hosts service etc how i can get then server ip i'm still confused

warm surge
#

but if you’re not using vps, you have to configure your windows host bs

naive pulsar
#

like api.bot.xyz/dblwebhook

warm surge
#

My nginx points to my api

naive pulsar
warm surge
#

Wait

#

Wait

naive pulsar
warm surge
# naive pulsar np dude when you back or anytime you can send it take you time : )

location /api/ {
proxy_redirect http://localhost:8000 https://oliverbot.xyz/api/;
proxy_pass_header Server;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Scheme $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_connect_timeout 5;
proxy_read_timeout 240;
proxy_intercept_errors on;

    proxy_pass              http://127.0.0.1:8000;
}
#

My nginx config

naive pulsar
#

this is

warm surge
#

If you want @real rose if he wants to, he can help you with nginx

naive pulsar
warm surge
raven nexus
quartz kindle
naive pulsar
naive pulsar
#

api

quartz kindle
#

but your bot is not running there is it?

naive pulsar
#

this make me wondreing

#

i must to move

#

all

#

daliy coins code

quartz kindle
#

what do you want to do with the vote?

naive pulsar
#

to

#

my api

naive pulsar
quartz kindle
#

where is the bot's database?

naive pulsar
#

after no request for like 5m

quartz kindle
#

local mongo or mongo atlas?

naive pulsar
quartz kindle
#

then you can connect to atlas from the api directly

#

topgg webhook -> vercel api -> mongo atlas

#

dont need to access the bot

naive pulsar
#

so if you vote you will not get a coins

quartz kindle
#

you will

#

a vote is a request

naive pulsar
#

So I need to add my api to topgg webhook then by express.js get a post of vote ?

solemn latch
#

Does vercel even support express?

#

neato

quartz kindle
#

you dont need topgg lib either

#

a vote webhook is an http request like a page view or route access

#

you just create a route in your vercel app, and put the url in topgg

#

and your vercel app will receive the request in that route

naive pulsar
#

I see now

#

Like

api.bot.xyz/vote

and but it at topgg

quartz kindle
#

yes

naive pulsar
#

Then this will be like post

#

So I can get info of users who posts ?

quartz kindle
#

ye

naive pulsar
#

Thanks dude

#

I'll try it

quartz kindle
#
export async function POST(req) {
  const voteData = await req.json()
}
naive pulsar
surreal sage
#

ok so

#

uhh

#

if you member.roles.cache.get(guildId)

#

is that valid

#

or just no

quartz kindle
naive pulsar
#

so now what happend if someone fake a post

app.post('/vote', async function(req, res) {
  const VoteDate = req.body
  console.log(VoteDate)
});
#

i mean now anyone can get a unllimit votes

#

use postman

#

then fake posts

#

how i can fix it

deft wolf
#

@solemn latch can you pls?

#

Or @harsh nova

naive pulsar
#

scam

deft wolf
naive pulsar
#

but

#

how i can get it

#

amm

deft wolf
naive pulsar
lyric mountain
quartz kindle
#

nvm tons of people already said it lmao

deft wolf
quartz kindle
#

lmao

lyric mountain
#

tim to himself

#

tim to everyone else

neon flicker
#

Is it possible to cancel a collector?

#

Oh nevermind, it is .stop()

naive pulsar
#

or token

#

i didn't get it yet

eternal osprey
#

hey guys my brain is literally not braining today,
// calculate timestamp of log,if it is within 24h, stop,
// if it is within 48h, give points. Outside 48, lose streak.
is this valid logic for achieving the following:

  • user daily streaks.
#

idk, like suppose the timestamp is within 24h compared to the past one, it is still the same day right. So we just break.
But if the timestamp is within 48h, it is the next day, and we then update timestamp.
Buuutttt, if the timestamp is outside 48h the user forgot to maintain their streak right?

quartz kindle
#

topgg sends an "authorization" header

#

the value of the authorization header is the string that you put in your topgg settings (url + auth)

#

for example:
url = api.nuvex-bot.xyz/vote
authorization = abc1234

code (pseudocode):

if(request.headers.authorization !== "abc1234") {
  return request.send("invalid request")
}
quartz kindle
#

but you want to count 24h from where? since last timestamp or something fixed like midnight UTC?

eternal osprey
#

EST

#

i log each time a user performs a certain action

#

that is when the "timer" starts.

lyric mountain
#

What are u trying to do? There might be a better way

eternal osprey
# lyric mountain What are u trying to do? There might be a better way

I have 4 cases, they all work based on a previous timestamp i saved:

user does action x at timestamp t2 -> owh no, t2 is still on the same day! -> error
user does action x at timestamp t3 -> t3 is the next day, Yaaay!
user does action x at timestamp t4 -> t4 is 2 days later, nooooo!

lyric mountain
#

why not store timestamp on database?

eternal osprey
#

i do

lyric mountain
#

then simply compare with current date

eternal osprey
#

i was just figuring if my logic was correct

lyric mountain
#

it's best if u work with millis, this way u dont go into float shenanigans

eternal osprey
#

ah yeah that's true

lyric mountain
#

to get length it's just current_millis - previous_millis

eternal osprey
#

yeah i got everything setup already, but indeed i might move to millis instead of hours

past field
#

question! so what’s a good way for me to get players feedback?

#

basically what i’m thinking

#

i have some responses that the bot sends based on certain keywords via event listener

#

but i want players to have a chance at submitting some funny responses

#

so i was thinking maybe i can send an embed at the end of my clickwar game for ppl to click and submit, but how can i do that and actually get their responses?

#

in the console log?

lyric mountain
#

ticket system

#

doing automatic feedback collecting would be against tos

past field
#

oh

mossy zealot
#

I have this to detect if someone votes on my bot, But it doesn't work..

#

I just added the topgg webhook, I don't have a custom website.

#

I just want to see who voted on my bot, and give them rewards

quartz kindle
#

also, why are you creating an Api instance if you're not using it anywhere?

past field
quartz kindle
#

but you can always link them your server and tell them to go there

past field
solemn latch
quartz kindle
quartz kindle
#

can be console.log, can be fs.writeFile, can be database

past field
quartz kindle
#

like if you want to create text files

#

or something

past field
#

hm

quartz kindle
#

you can also just have your bot post on some channel in your server

mossy zealot
quartz kindle
mossy zealot
quartz kindle
solemn latch
#

The way webhooks will be handled will often depend on the host.

mossy zealot
#

so idk

solemn latch
#

like, at home?

mossy zealot
quartz kindle
#

ask about ip address and port

mossy zealot
#

i have ip adress and port

quartz kindle
mossy zealot
#

how does that make sense if the url doesnt have a /vote

#

idk if u say itll work ig

mossy zealot
#

yeah but i saw this when i looked it up too

#

but i thought it was for websites with custom vote page

solemn latch
#

webhooks, and webhook urls are not for websites.

The way I like to explain it, is it uses the same communication methods as a website, but its for computer to computer communication.

mossy zealot
#

I see

mossy zealot
#

I also forgot what that panel is called

quartz kindle
#

is this pc in your home?

#

or in a server somewhere?

mossy zealot
#

server

#

we host MC servers and discord bots on there

#

for example

quartz kindle
#

alright then just do that, ip address and port, plus whatever path you have in your express listener

mossy zealot
#

how do I know where my express listener path is

#

i dont have access to the server

#

only the panel

solemn latch
#

/vote is the path

mossy zealot
#

the port in my code should be the same as my host?

solemn latch
#

The port in code, in your url needs to be the same.

If the server has any firewalls it must be allowed

past field
#

but now i'm thinking about when i have to restart the bot

#

the accept button wouldn't work anymore

pine willow
#

why shouldnt it work.

past field
#

so i'm guessing i can add this to the database, adding a table to keep it working

past field
#

it's just in the bots memory

#

so if i restart it wouldn't work (i think)

#

im new to databases so idk

mossy zealot
pine willow
#

i can restart my bot. And the buttons still work after. No DB

mossy zealot
pine willow
#

you give them custom IDs? right.

solemn latch
pine willow
#

Should be required

pine willow
mossy zealot
solemn latch
past field
#

interaction failed when bot restart

solemn latch
# mossy zealot

I'm not sure what that is, since we dont know what panel software you're using.
It might work? I'm not sure.

pine willow
#

Doesnt look like ptero

#

i cant identify it

solemn latch
#

I'd suggest reaching out to whoever set it up tbh.

pine willow
#

Or reinstall it. When you are the owner

solemn latch
#

it sounds like the panel is a group thing, with multiple people using it. another person might know.

#

Sadly, its just a guessing game without more information.

pine willow
#

yessir

mossy zealot
#

I will try to find out what kinda host it is

#

@solemn latch omg after long searching

#

PufferPanel

#

VPS connected to PufferPanel

quartz kindle
#

you need to see which ports are open for you to use

#

and whether there is any internal redirection

#

does the panel show any "public url"?

#

or public ip port?

sharp geyser
#

Right so im using lmdb, but I am not sure the approach I want to go for.

#

I can either go nosql route like mongo and it basically just be a json table, or I can go the postgres route and have rows / columns and eventually support relations

quartz kindle
#

although if you have access to sftp, then it might be a full vps, and not an app hosting panel thing

#

if you have access to the full vps, then the port is the one you define inside your code, in express

#

you just need to check if there are any firewalls installed

mossy zealot
#

the master url is the website

quartz kindle
#

just a single app.get("/")

#

and run it on some random port, like 3000

#

then try to access it and see if it works

#

both with ip:3000 and with website:3000

mossy zealot
#

the website port is 8080 tho

quartz kindle
#

you cant use a port that is already used

mossy zealot
#

ohhhh

#

i see

#

does an offline port work?

#

If I take a port of one of the servers that is offline

quartz kindle
#

the program will create the port for you

#

unless there is a firewall that blocks ports that are not configured

mossy zealot
#

yeah there is a firewall which he had to manually add so it could work

past field
#

good website to upload terms of service for bot verification?

mossy zealot
#

You could technically use pastebin

frosty gale
#

free meaning that github can cutely feed your source code to train an LLM

rustic nova
#

Yummy data

#

mmmmmmmmmm

#

Yummy api secrets I'm going to use as examples for others

#

mmmmmmmmmmmm

eternal osprey
#
   console.log("current", timestamp)
    console.log("previous", user[0].last_logged_timestamp)
    const differenceInMs = timestamp - user[0].last_logged_timestamp;
    console.log("difference", differenceInMs)```
is this an overflow that is happening?
numbers don't make sense
pearl trail
#

timestamp is Date.now() ?

sharp geyser
#

Sometimes they are in seconds, other milliseconds

#

that 000 one is a unix timestamp

#

Its in milliseconds

#

As you can see

#

current & difference are in milliseconds

#

previous is in seconds

#

Its not overflow its just different formats of timestamps

small tangle
quartz kindle
#

:^)

pine willow
#

I just created this Auth page for my program and then i noticed that i cant use it because of Spotify copyright and stuff

lyric mountain
#

cant u just remove the logo?

pine willow
#

Isnt the name copyrighted too?

neon leaf
#

thats not how copyright works

pine willow
neon leaf
#

it just means the name is "claimed", you can still use it yourself as long as its clear its not related to you

pine willow
#

okay okay

#

Anyways. Does it look good ??

lyric mountain
#

BUT this only applies to things you make

pine willow
#

I wanted to make the program public. Thats why i ask

lyric mountain
#

if you're using spot's oauth2 then this doesnt apply to that, because it's their site

pine willow
#

Not by spotify

lyric mountain
#

just to make it clear, you're not using oauth2?

pine willow
#

I use this.

#

this is oauth2 i guess

#

and when you link my app with the program

#

you get redirected to the page youve seen

lyric mountain
#

yes that's oauth

pine willow
#

I added it because otherwise nothing would be displayed

lyric mountain
#

you can make references to their name as you've just came from their site

lyric mountain
#

basically, you're only allowed to use their logo/name if it's linking to their site in some way

#

or if they give you permission for other purposes

pine willow
#

Okay. Thanks for you help!

quartz kindle
#

i mean

#

just publish it

#

the most it will happen, if anything, is they ask you to remove it

quartz kindle
#

once i was working on a website for a friend, he had a shop and sold some products

#

and wanted to mention that his shop accepts payment throguh payoneer

#

and he got a c&d email from them

#

lmao

pine willow
#

o.o

#

How do they even find these small projects using their assets

#

😭

earnest phoenix
quartz kindle
#

i replied to that email asking for more details about it, but they never responded. after a month of waiting we just removed the payoneer payment method from the shop

#

they never replied, nor followed up

#

they just use automated bots and scanning shit for copyrighted words

#

and send automated email threats

pine willow
#

I see.

#

Just use Spotfy

#

quartz kindle
#

spoofify

deft wolf
#

Spot!fy

pine willow
#

Goofify

naive pulsar
#

What is the best you to make OTP for my website ? Use nodemail I just wanna a way to block him to send many OTP also if he write many wrong Password and rech limits got ban for like 5m I just will use a Cokies to save times of send and last send was when but if you guys have a better way please say it

quartz kindle
#

i wouldnt use cookies for that

#

use the user account in the database

#

track login attempts there

past field
#

music bot.. is it hard to do? 👀

pine willow
#

when you want a bot with cool features

#

it can be hard

deft wolf
#

Unique*

vagrant veldt
#

this is Fr3e server

deft wolf
#

Nah, we pay Tim monthly to send messages on this channel

quartz kindle
#

Lol

pine willow
earnest phoenix
past field
#

if i defer a button with deferUpdate, could a channel message be the interaction acknowledgement?

lyric mountain
#

the acknowledge is the deferUpdate itself

past field
#

so what would i use to have the button acknowledged and a channel message send as a result of that button tap?

basically in click war, the players have lives. i have a “swap lives” button but i don’t want it to send an ephemeral.i want them to tap it and the bot sends a channel message who the user swapped with. it does that, but it also gives interaction failed, no errors in console logs. so i assume the button works fine, just dk the best way to have it respond without interaction failed.

surreal sage
#
import EventEmitter from 'events';

export interface PlaneWebhookEvent {
  event: 'issue';
  action: 'deleted' | 'updated';
  webhook_id: string;
  workspace_id: string;
  data: Record<string, unknown>;
  activity?: Record<string, unknown>;
}

const webhookEvents = new EventEmitter<{
  'eventHere.actionHere': [PlaneWebhookEvent];
}>();

export default webhookEvents;

How can I make the types on eventemitter like that?

#

dynamic..

#

ok wait

#

got it nvm

sharp geyser
#

Im confused

#

wdym dynamic

quartz kindle
past field
#

so i don’t need to defer

#

because follow-up

quartz kindle
#

you just have to remember this rule:
interaction -> reply -> followup
interaction -> defer -> reply -> followup

past field
#

ok i got you

#

tim u da goat

warm surge
#

@quartz kindle hey tim i need your help here

#

may i slide you a invite real quick, i need you teach a friend how ports 443 and 80 works

sharp geyser
#

uhm

#

port 80 = http

#

443 = https

#

not much more than that tbf

sharp geyser
warm surge
sharp geyser
#

Then he needs to know how nginx works

#

not port 443 and 80

sharp geyser
#

Specifically name based virtual hosting

#

Right I got it partially wrong

#

When a user visits a domain example.com the browser will perform a dns lookup to resolve the IP address behind that domain, it will then send a HTTP request to that ip with the domain in the Host header. Nginx then examines this header to determine which server block to route the request to. It does this by comparing the value in the Host header and the one defined in server_name in your blocks. Once it finds the right one it will serve the content at that location

sharp geyser
#

The reason everything is able to seemingly run on one port is because all of those aren't actually running on a single port

#

Well they are, its just not in the sense you think

#

nginx as the service is listening on port 80 & 443

#

otherwise there would be no need to proxy pass your stuff, and what not.

#

when you are doing listen 80; you are essentially saying have this website listen on the nginx port 80

warm surge
#

thanks misty

sharp geyser
#

👍

#

Some of my explanation may be a bit wrong, but the gist of it is correct

quartz kindle
#

thats what a webserver software does
listen to X port, examine requests that come in, and do somegthing with them

sharp geyser
#

oh tim is here to fill in the holes I left

quartz kindle
#

you could literally run nodejs on port 80 and check headers yourself, and handle multiple websites with a single nodejs program

#

or redirect them elsewhere if you prefer

sharp geyser
#

yuh

#

but

#

nginx better

#

it does it all for me

quartz kindle
#

yeah nginx is better at it because it was made expecially for it

sharp geyser
#

iara_hehe ye

#

btw tim

#

while you are here

#

I has a question regarding my db

#

Since I am using lmdb, I figured why not just try and make a relational database.

#

Problem is, how exactly should I keep track of table structures & relations properly

#

should I just use indexing and what not?

#

Create an additional file alongside the db files that keep track of relations?

random willow
#

anyone looking to get paid for making me a elo bot lmk

#

dm me

quartz kindle
#

store everythign as a key value

#

table structures, relations, indexes, etc

sharp geyser
#

How would that work?

#

Seems like it would be a pain in the ass to make sure everything stays where it should & look it up appropriately

quartz kindle
#

tables -> array of table names
tables:name -> structure for table
index:table:col:value -> index for table col
index:table:col:value2 -> index for table col
index:table:col:value3 -> index for table col

#

etc

#

you can also create seperate lmdb databases for some of those

sharp geyser
#

interesting

#

That wont impact performant will it?

#

As in looking up

proven lantern
#

create keys like this

const eloKey = ({rating_type, leaderboard, versus, teamSize, id}) => {
    if (rating_type === 'distinct_team') {
        return [rating_type, id, leaderboard, versus].join("|")
    }
    if (rating_type === 'combined_team') {
        return [rating_type, id, leaderboard, teamSize].join("|");
    }
    if (rating_type === 'distinct_player') {
        return [rating_type, id, leaderboard, versus].join("|");
    }
    if (rating_type === 'combined_player') {
        return [rating_type, id, leaderboard, teamSize].join("|");
    }
    if (rating_type === 'overall_player') {
        return [rating_type, id, leaderboard].join("|");
    }
    return 'error_invalid_rating_type';
};
module.exports = eloKey;
sharp geyser
proven lantern
#

store keys in the key
["settings", guildId, userId].join("|");

#

like the guild and user ids

#

foreign key

sharp geyser
#

No ty

proven lantern
#

if you store it this way it's the fastest lookup

#

since you lookup by key

#

it's like a composite key

wheat mesa
#

I just discovered datagrip

#

I’ve been living a lie my entire life

prime cliff
quartz kindle
#

loads pretty nicely now

prime cliff
#

Some stuff is a little broken with the design changes but it's gonna be a lot better in the long run

lyric mountain
#

Cuz u get all of datagrip on top of the ide

#

I've been using it to edit in-db scrips with intellisense since forever, couldn't go back to other tools even if I tried

ionic schooner
#

IntelliJ stuff is bussin bussin, really has everything you need and doesn’t cost much

sharp geyser
#

Does that not defeat the point of the key being an index:table:col:row

proven lantern
#

it's so you can paginate through the table in addition to lookups by key

quartz kindle
#

for example you want an index in table users, column id

#

you can do it like index:users:id:374958739487 -> table row

sharp geyser
#

wait

#

isn't the numbers after id the value of that row?

#

Im a little confused on your thought process

quartz kindle
#

the numbers would be the user id

#

the user id is indexed, so it has to be fast to query

#

so it needs to be part of an lmdb key

sharp geyser
quartz kindle
#

and the value for that key is the row you are querying

#

or some sort of unique row id

#

something that links to the desired row

sharp geyser
#

hm

#

So would I have this is a separate lmdb database

quartz kindle
#

basically, database indexes are just a key->value map

sharp geyser
#

and it links to keys in the other one

quartz kindle
#

you could create a separate database for this

#

but lmdb is made to handle data like this

#

similar to redis

sharp geyser
#

what exactly is index actually

#

you append it at the beginning of the key

quartz kindle
#

to separate it from other types of keys that are stored in the same database

sharp geyser
#

icic

quartz kindle
#

for example table structures

#

or whatever else shares the same db

#

you basically create namespaces inside a single db to separate the data

#

and lmdb can do range queries

#

so you can query all keys that start with said prefix, for example

sharp geyser
#

so
index:users(table_name):id(column):11231231233(valueOfId) -> 11231231233
index:users:name:11231231233 -> Jane Doe

lament rock
#

Actually working with it all will make sense

sharp geyser
#

I assume appending the id would make it faster to query since i can look it up based off id

quartz kindle
#

so the value that is being stored has to resolve to the full table row

sharp geyser
#

so it has to resolve to everything for that entry?

quartz kindle
#

yes

sharp geyser
#

if I am storing a name, phone number, email, etc

#

if I look it up, it has to return all that?

quartz kindle
#

yes

#

thats what an index is for

sharp geyser
quartz kindle
#

you dont create an index in a db to find only that column

sharp geyser
#

I wonder how that will work code wise

quartz kindle
#

you create an index to find the row based on that column

sharp geyser
#

is that the point of primary keys?

quartz kindle
#

yes

sharp geyser
#

interesting

quartz kindle
#

but primary keys are also unique row ids

#

which by themselves alrewady are an index

sharp geyser
#

so they have to be unique

quartz kindle
#

just stored in a different namespace

#

for example

#

rows:999999 -> [john doe, 78798942342, abc@xyz.com]
index:users:id:78798942342 -> 999999

sharp geyser
#

Ah

#

So it would just be an array of all the values

quartz kindle
#

yes

sharp geyser
#

interesting

quartz kindle
#

the names of the columns would be defined in yet another namespace

sharp geyser
#

yknow, that makes sense if you look at a db viewer

quartz kindle
#

the full thing can be something like

sharp geyser
#

I assume the order of the values put into the array matter

#

else they will get mixed up

#

what should be the phone number column, ends up having a value from the name column

#

or smth like that

quartz kindle
#

tables:1 -> [id, name, email]
rows:1:79287349823 -> [111111, john doe, abc@xyz.com]
indexes:1:id:111111 -> 79287349823

sharp geyser
quartz kindle
#

the columns are always ordered

sharp geyser
#

icic

#

Well, this gave me some guidance

#

thanks a lot

#

Hopefully I will have smth to show you at the end of the week

quartz kindle
#

good luck!

sharp geyser
#

Im still debating on whether or not to make my own sql language

#

or just pull an EF Core and make a wrapper around the database

#

not even sure where i'd begin writing my own sql language 💀

sharp geyser
#

Whats the difference between IAsyncDisposeable vs IDisposeable? I see some sources recommend using it together but not sure why.

scenic kelp
sharp geyser
#

I never thought to look at the actual page for it

civic scroll
#

did i fail

#

or did i success

deft wolf
civic scroll
#

real

raven nexus
#

HI, i have question possible can we make the embed like this

Name : Test
Detail : Hello world

lyric mountain
#

what do you mean?

raven nexus
#

around the word

#

or like use any custom character to do

lyric mountain
#
Name   : Test
Detail : Hello world
``` like this?
raven nexus
quartz kindle
raven nexus
#

like this but the box outlike replace with -----------------

raven nexus
lyric mountain
#

that's what I did lul

raven nexus
#

something like this

raven nexus
lyric mountain
#

it's the same thing, it's just that embeds make the black bg smaller

raven nexus
#

what can i decoration with it?

lyric mountain
#

well u could add a blank field after CTAF frequency

#

to align the fields

quartz kindle
#

lol

lyric mountain
#

le olde ascii graphics

raven nexus
quartz kindle
lyric mountain
#

if you're on windows, press Win key and search "charmap"

quartz kindle
lyric mountain
#

oooooor there's a site for that ofc

quartz kindle
quartz kindle
#

:^)

raven nexus
#

it still not show for the bot did i miss something?

#

how could i put in the middle line?

lyric mountain
#

you cant do that

raven nexus
#

uh

lyric mountain
#

if you want to make it in a single block, you must use description

#

fields must always have a name and a value, and they are disposed in a 3-column (1-column for mobile) way

raven nexus
#

ok

neon flicker
#

Does Discrod API support the new guild system?

#

Like is it possible to fetch somebody's current guild tag?

pearl trail
#

i love opening trojan and malware sites there

neon flicker
lyric mountain
#

it'll probably support eventually, it's just that it's still in thanos-beta stage

#

banners took a long time to be documented in the api

raven nexus
#

i sometime got bug

#

some time no error

#

is tere a way to fix? the problem only start with when the command was use for 2 time

#

the first run notthing problems

#

is there like completely remove the cooldown? if remove does it will impact anything

lyric mountain
#

yes, the impact will be that it'll have no cooldown

#

who wrote that code?

raven nexus
#

after i edit the last part which is the photo i send before then it crashes

lyric mountain
#

ask your friend to fix the error, you can't really attempt to fix something like that without understanding what the code is doing

#

ah, fortune, I remember you

raven nexus
lyric mountain
#

cooldown isn't about the api

#

it's to prevent people from spamming commands

night lagoon
eternal osprey
#
async function calculateBet(data: any, sportsBook: string): Promise<number> {
  const probability_winning: number = 1 / data.previous_price;
  const probability_losing: number = 1 - probability_winning;
  const bet_return: number = data[sportsBook + "_price"] - 1;
  const base_price: number = (
    (probability_winning - probability_losing / bet_return) *
    100
  ).toFixed(2);
  const recommended = (base_price * (1 / 3)).toFixed(2);
  return recommended;
}

huh base_price is a string according to ts?

lyric mountain
#

toFixed is a string

#

numbers dont have definite decimal count

eternal osprey
#

owh damn that's intersting

lyric mountain
#

for example, 2.0 doesn't have 1 decimal place

#

cuz 2 == 2.0 == 2.000000000000

#

it only has a fixed decimal count when viewed as a string

#

if you want to truncate to a certain precision, you have to multiply, truncate and then divide

#

((value * 100) | 0) / 100 will truncate to 2 decimal places for example

#

add/remove zeroes to 100 to change how many decimals are kept

neon leaf
#

why dont you type the data argument

#
async function calculateBet<Book extends string>(data: Record<'previous_price' | `${Book}_price`, number>, sportsBook: Book): Promise<number> {
lyric mountain
#

holy hell that's big

neon leaf
#

thats not big

eternal osprey
#

way too big to parse it so i just defined it as any

neon leaf
#

yea this accepts any object that contains these things

eternal osprey
#

wait really?

neon leaf
#

yes

eternal osprey
#

new to ts so this is awesome to learn

neon leaf
#

thats how ts types works

#

ts interfaces dont allow this

eternal osprey
#

i like ts as it combines 2 things i like, js and java

lyric mountain
#

eh, the typing system is closer to kotlin

#

which is why I dislike both

eternal osprey
#

okay not really java but idk i find it similar tbf

#

like the whole type system, the objects and classes

frosty gale
#

@quartz kindle how would you speed this up?

for (const entry of entries) {
    const reversed = Buffer.from(entry.bytes_buffer).reverse();
    for (const e of entries) {
        if (e.bytes_buffer.compare(reversed) === 0) {
            console.log("Duplicate found!");
            process.exit(1);
        }
    }
}
#

this function basically goes through each entry, clones & reverses the buffer (since you cant reverse without making a copy of the buffer) and then goes through each entry to see if the reverse matches any other buffer

#

with 100k elements this takes very very very long

#

im guessing its mainly from the buffer copying with Buffer.from and the reverse method

#

i'll try to substitute that first

neon leaf
#
const reversedMap = new Map()

for (const entry of entries) {
    const reversed = Buffer.from(entry.bytes_buffer).reverse()

    if (reversedMap.has(reversed.toString('hex'))) {
        console.log("Duplicate found!")
        process.exit(1)
    }

    reversedMap.set(entry.bytes_buffer.toString('hex'), true)
}
#

could help

#

(will help)

eternal osprey
#

sender.ts:

module.exports = { sendData };```
receiver.ts:
```tsconst { sendData } = require("./sender.js");```

is this allowed/possible?
#

i know ts mainly uses import from

neon leaf
#

its a war crime

frosty gale
eternal osprey
frosty gale
#

only in javascript can you convert bytes to a string and use a map and it becomes much faster

#

although its probably because this only iterates 100k times as opposed to 100k*100k

neon leaf
#

I mean previous solution was O(n²)

eternal osprey
neon leaf
#

this is O(n) yeah

eternal osprey
#

also, should i require from the .ts or the compiled .js

neon leaf
#

why would you want to use require

eternal osprey
#

cuz import from gives me this problem:

sender.ts(7, 16): 'sendData' is declared here.
import sendData
neon leaf
#

why are you importing the js file

eternal osprey
#
module.exports = { sendData };```
i might be ugly and retar3ded though
neon leaf
#

just import from ./sender

#

no file extension

eternal osprey
#

really? I never knew that was a thing

neon leaf
#

and remove module.exports

#

either do export default sendData

eternal osprey
#

wow i deadass suck

neon leaf
#

or export { sendData }

eternal osprey
#

i see, that is both js and ts syntax right?

#

just making a note here

neon leaf
#

yes, its esm

#

(modern js)

eternal osprey
#

i always though that you MUST use module.exports = {...}

#

instead of just export {..}

neon leaf
#

well if you are using cjs yes

#

but cjs is a curse that nodejs brought upon us many years ago

proven lantern
neon leaf
#

this seems pretty slow

#

splitting a string into an array

frosty gale
#
const reversedSet = new Set();
for (const entry of entries) {
    const reversed = Buffer.from(entry.bytes_buffer).reverse().toString();

    if (reversedSet.has(reversed)) {
        console.log("Duplicate found!")
        process.exit(1);
    }

    reversedSet.add(entry.bytes_buffer.toString());
}
#

you can actually just convert the buffer to a string and you can use it as a key for the set/map

#

no need to convert it to hex or anything special

#

it will still hash the same

neon leaf
#

did you test if thats faster?

frosty gale
#

didnt see if its faster but i can benchmark

sharp geyser
#

Im late to the party, but why exit the process if a reversed has been found.

#

Also, sets can't take in duplicates anyway right, so why check if it already exists?

neon leaf
#

I could imagine sha1 hashing the buffer may also be fast

#

since map lookups need less chars

frosty gale
#

and theres code later on that i dont wanna comment out

sharp geyser
#

I see

#

fair enough

frosty gale
neon leaf
#

i want to benchmark four

proven lantern
#

hold on, let me rewrite it in zig

frosty gale
#

great

frosty gale
neon leaf
#

ben,me,you,me but with sha1

frosty gale
#

sha1 should be much slower since it also calls openssl and adds an extra step but sure

#

plus theres a very small chance of collision which would make this unfit for purpose because of the risk

neon leaf
#

hold up lemme just write an sha1 function in pure js

#

ok this is not sha1 but its good enough i think

function rotateLeft(n, s) {
    return (n << s) | (n >>> (32 - s));
}

function toHexStr(n) {
    let s = "", v;
    for (let i = 7; i >= 0; i--) {
        v = (n >>> (i * 4)) & 0x0f;
        s += v.toString(16);
    }

    return s;
}

function sha1(buffer) {
    let words = [];
    let message = new Uint8Array(buffer);
    let messageLen = message.length;

    for (let i = 0; i < messageLen - 3; i += 4) {
        words.push(
            (message[i] << 24) |
            (message[i + 1] << 16) |
            (message[i + 2] << 8) |
            message[i + 3]
        );
    }

    let remainingBytes = (messageLen % 4);
    let lastWord = (remainingBytes === 3 ? (message[messageLen - 3] << 16) : 0) |
        (remainingBytes >= 2 ? (message[messageLen - 2] << 8) : 0) |
        (remainingBytes >= 1 ? message[messageLen - 1] : 0);
    words.push(lastWord << 8 | 0x80);

    while ((words.length % 16) !== 14) {
        words.push(0);
    }

    let h0 = 0x67452301;
    let h1 = 0xefcdab89;
    let h2 = 0x98badcfe;
    let h3 = 0x10325476;
    let h4 = 0xc3d2e1f0;

    words.push(0);
    words.push(messageLen * 8);

    for (let i = 0; i < words.length; i += 16) {
        let w = words.slice(i, i + 16);
        for (let t = 16; t < 80; t++) {
            w[t] = rotateLeft(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);
        }

        let a = h0;
        let b = h1;
        let c = h2;
        let d = h3;
        let e = h4;

        for (let t = 0; t < 80; t++) {
            let temp;
            if (t < 20) {
                temp = (rotateLeft(a, 5) + ((b & c) | (~b & d)) + e + w[t] + 0x5a827999) | 0;
            } else if (t < 40) {
                temp = (rotateLeft(a, 5) + (b ^ c ^ d) + e + w[t] + 0x6ed9eba1) | 0;
            } else if (t < 60) {
                temp = (rotateLeft(a, 5) + ((b & c) | (b & d) | (c & d)) + e + w[t] + 0x8f1bbcdc) | 0;
            } else {
                temp = (rotateLeft(a, 5) + (b ^ c ^ d) + e + w[t] + 0xca62c1d6) | 0;
            }

            e = d;
            d = c;
            c = rotateLeft(b, 30);
            b = a;
            a = temp;
        }

        h0 = (h0 + a) | 0;
        h1 = (h1 + b) | 0;
        h2 = (h2 + c) | 0;
        h3 = (h3 + d) | 0;
        h4 = (h4 + e) | 0;
    }

    return toHexStr(h0) + toHexStr(h1) + toHexStr(h2) + toHexStr(h3) + toHexStr(h4);
}```
frosty gale
#

ill have to benchmark it manually because the benchmark tool i use is only browser js and browser js doesnt have buffer

#

it has uint8array but the .toString() method works differently and likely much slower

proven lantern
#

same thing written in zig

frosty gale
#

this is the improvised benchmark

function chloe() {
    const reversedSet = new Set();
    for (const entry of entries) {
        const reversed = Buffer.from(entry.bytes_buffer).reverse().toString();

        if (reversedSet.has(reversed)) {
            console.log("Duplicate found!")
        }

        reversedSet.add(entry.bytes_buffer.toString());
    }
}

function ben() {
    const reversedSet = new Set();
    for (const entry of entries) {
        const reversedHex = entry.bytes_buffer.toString('hex').split('').reverse().join('');

        if (reversedSet.has(reversedHex)) {
            console.log("Duplicate found!")
        }

        reversedSet.add(entry.bytes_buffer.toString('hex'));
    }
}

function hex_username_man() {
    const reversedMap = new Map()
    for (const entry of entries) {
        const reversed = Buffer.from(entry.bytes_buffer).reverse()
    
        if (reversedMap.has(reversed.toString('hex'))) {
            console.log("Duplicate found!")
        }
    
        reversedMap.set(entry.bytes_buffer.toString('hex'), true)
    }
}

chloe();
console.time("Chloe Function");
chloe();
console.timeEnd("Chloe Function");

ben();
console.time("Ben Function");
ben();
console.timeEnd("Ben Function");

hex_username_man();
console.time("Hex Username Man Function");
hex_username_man();
console.timeEnd("Hex Username Man Function");
#

@neon leaf surprisingly your map function performs faster consistently

Ben Function: 128.123ms
Hex Username Man Function: 82.781ms
Chloe Function: 94.153ms
#

i have no idea why, just doing toString and using a set which has less overhead should be much faster than using a map and converting it to hex twice

proven lantern
#

slowest?

neon leaf
#

yeah what thats the slowest

frosty gale
#

@quartz kindle please explain

neon leaf
#

makes perfect sense

frosty gale
#

what do you mean slowest

proven lantern
#

biggest number = bad

frosty gale
#

yes i posted the benchmark

frosty gale
neon leaf
#

yes ben is clearly 50ms above me

#

yes

frosty gale
#

oh fuck

#

meant to tag you

proven lantern
#
const crypto = require('crypto');

// Generate test data
function generateTestData(size) {
    return Array.from({ length: size }, () => ({
        bytes_buffer: crypto.randomBytes(32)
    }));
}

// Original function
function originalFunction(entries) {
    for (const entry of entries) {
        const reversed = Buffer.from(entry.bytes_buffer).reverse();
        for (const e of entries) {
            if (e.bytes_buffer.compare(reversed) === 0) {
                return "Duplicate found!";
            }
        }
    }
    return "No duplicates found.";
}

// Optimized function
function optimizedFunction(entries) {
    const reversedSet = new Set();

    for (const entry of entries) {
        const reversedHex = entry.bytes_buffer.toString('hex').split('').reverse().join('');

        if (reversedSet.has(reversedHex)) {
            return "Duplicate found!";
        }

        reversedSet.add(entry.bytes_buffer.toString('hex'));
    }

    return "No duplicates found.";
}

// Performance test
function runPerformanceTest(size) {
    const testData = generateTestData(size);

    console.log(`Testing with ${size} entries:`);

    console.time('Original Function');
    originalFunction(testData);
    console.timeEnd('Original Function');

    console.time('Optimized Function');
    optimizedFunction(testData);
    console.timeEnd('Optimized Function');

    console.log('---');
}

// Run tests with different sizes
[100, 1000, 10000].forEach(runPerformanceTest);
#

that's the test i ran

neon leaf
#

robert  ~/projects  node sha1.js
Chloe Function: 122.715ms
Ben Function: 144.211ms
Hex Username Man Function: 83.672ms
Hex Username But With SHA1 Function: 277.187ms

#

woops

frosty gale
#

everything about js is opposite

#

something that should logically be faster is actually slower

neon leaf
#

i mean the results make perfect sense to me

#

doing 2 array actions instead of 1 is obv slower

#

Buffer.from doesnt actually clone the data

#

it just points it to the old position and slices modified data

frosty gale
#

well bens benchmark yes but yours one convert the string to hex and uses a map which has extra steps but its much faster

frosty gale
#

but it doesnt matter here

neon leaf
#

well in js you wont see that

#

v8 doesnt clone though

#

thats why you always use the offsets when converting to ArrayBuffers

#

since those are not building on top of the original

proven lantern
#

hex_username_man wins

eternal osprey
#
helpers/parsing.ts:1:20 - error TS2732: Cannot find module '../config.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.

1 import config from "../config.json";
                     ~~~~~~~~~~~~~~~~```
huh why error men waddafuck men
neon leaf
#

wait I just realized something

#

why is it even reversing

frosty gale
#

hold on ill convert yours to a set and see how it performs

neon leaf
#

my function is 10ms faster without reversal

#

I dont see why reversal is needed

frosty gale
#

about 2ms faster

frosty gale
#

are you just comparing it backwards?

neon leaf
#

Hex Username Man Function: 8.431ms

#

🔥

neon leaf
#

all are reversed anyway

#

so if none are reversed its the same effect

frosty gale
#

lmao i specified the encoding in my toString() and its faster than yours

#

not by much though

neon leaf
#

and if I dont reverse I can use the v8 object id

#
function hex_username_man() {
    const reversedMap = new Map()
    for (const entry of entries) {    
            if (reversedMap.has(entry.bytes_buffer)) {
                    console.log("Duplicate found!")
            }
    
            reversedMap.set(entry.bytes_buffer, true)
    }
}```
#

try this

frosty gale
#

9.908ms

#

oh wait you dont understand

#

it has to be reversed

neon leaf
#

but the value isnt used anywhere?

frosty gale
#

with this youre just seeing if theres any duplicates

#

i want to see if the reverse of any of the buffer bytes matches each one

neon leaf
#

or are the entries themselves reversed

frosty gale
#

so if you have an array [[1,2,3], [3,2,1]]
the function should return duplicate found

#

because 1,2,3 reversed is 3,2,1

neon leaf
#

robert  ~/projects  node sha1.js
Duplicate found!

#

works fine

#

ah wait

#

i called the wrong fn

eternal osprey
#

why does my tsc add .default to each imported value?

frosty gale
#
function chloe() {
    const reversedSet = new Set();
    for (const entry of entries) {
        const reversed = Buffer.from(entry.bytes_buffer).reverse();

        if (reversedSet.has(reversed.toString("ascii"))) {
            console.log("Duplicate found!")
        }

        reversedSet.add(entry.bytes_buffer.toString("ascii"));
    }
}

function hex_username_man() {
    const reversedMap = new Map()
    for (const entry of entries) {
        const reversed = Buffer.from(entry.bytes_buffer).reverse()
    
        if (reversedMap.has(reversed.toString('hex'))) {
            console.log("Duplicate found!")
        }
    
        reversedMap.set(entry.bytes_buffer.toString('hex'), true)
    }
}
Chloe Function: 71.578ms (from 95.693ms)
Hex Username Man Function: 80.589ms

all i changed was that in my .toString() i specified the encoding of ascii and now it performs faster than hex mans, does v8 try to guess the encoding by any chance if i dont specify it as a parameter which could make it slower? @quartz kindle

neon leaf
#

default encoding is utf8

frosty gale
#

specifying utf8 makes it much slower now

#

that makes sense then

#

although im not sure why utf8 is much slower

#

ascii and utf8 arent too different

#

both buffers should be able to be represented in a single byte with little conversion

#

anyways ive had enough of this language for a day

neon leaf
#

uh wtf

#
function chloe() {
    const reversedSet = new Set();
    for (const entry of entries) {
            const reversed = Buffer.from(entry.bytes_buffer).reverse();

            if (reversedSet.has(reversed.toString("ascii"))) {
                    console.log("Duplicate found!")
            }

            reversedSet.add(entry.bytes_buffer.toString("ascii"));
    }
}

function hex_username_man() {
    const set = new Set()
    for (const entry of entries) {    
        // also check for reverse
        const reversed = Buffer.from(entry.bytes_buffer).reverse().toString('ascii');
            if (set.has(reversed)) {
                    console.log("Duplicate found!")
            }
    
            set.add(entry.bytes_buffer.toString('ascii'))
    }
}```


 robert  ~/projects  node sha1.js 
chloe: 1.376ms
hex_username: 1.233ms

 robert  ~/projects  node sha1.js 
chloe: 1.189ms
hex_username: 1.207ms

 robert  ~/projects  node sha1.js 
chloe: 1.009ms
hex_username: 0.832ms

 robert  ~/projects  node sha1.js 
chloe: 1.162ms
hex_username: 1.689ms

 robert  ~/projects  node sha1.js 
chloe: 1.299ms
hex_username: 0.873ms
#

this is cursed

frosty gale
#

if all of this was written in Rust™️ we wouldnt be having this discussion

lyric mountain
#
function reverse() {
  const arr = entries // ffs
  const len = arr.length

  for (let i = 0, l = len / 2; i < l; i++) {
      const reflex = (len - 1) - i

      arr[i] += arr[reflex]
      arr[reflex] = arr[i] - arr[reflex]
      arr[i] -= arr[reflex]
  }
}
lyric mountain
#

oh wait, we're not benchmarking reverse algos?

neon leaf
#

correct

#

finding duplicate buffers while reversing

lyric mountain
#

what for?

#

btw a set and a map are exactly the same

neon leaf
#

idk ask chloe

frosty gale
lyric mountain
#

sets can store a value in fact

frosty gale
#

since when

lyric mountain
#

sets are just an abstracted map

lyric mountain
#

usually null

frosty gale
#

still faster though since you dont deal with the value anymore from the javascript perspective so the native code can do all of that stuff

#

but performance suggests so

lyric mountain
#

the performance difference is probably from js typecheck

frosty gale
#

@lyric mountain ive had a look at v8 internal code and v8 does differentiate between them

#

they are technically 2 separate classes but they do extend from the same classes

#

both extend from JSCollection which extends from JSObject so basically both are objects

#

i feel deceived

lyric mountain
#

is there anything in js that isn't an object?

neon leaf
#

isnt undefined not an object

frosty gale
#

hashmaps in js are clearly a scam theyre just objects

frosty gale
#

checked the internals its a standalone class

lyric mountain
#

dw we can fix that

frosty gale
#

null also isnt an object

#

NaN isnt one either but its a very unique type

#

theres different variations of NaN which appear identical in js

neon leaf
#

typeof NaN === 'number' // true smh

frosty gale
#

v8 source code is so modular you have to go through like 20 different functions to find what you need

frosty gale
#

each thing in js is assigned a tag so the nan type is probably assigned a tag of number

#

which is why you need to use isNaN method

#

hold on NaN might actually be a number

#

isNaN checks if something is a number and then does the c++ isNaN on its value

eternal osprey
#

hey is my logic correct?

function getDatePart(timestamp) {
    const date = new Date(timestamp);
    return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
}

const timestamp = estDate.getTime();  
let previous = Number(user[0].last_logged_timestamp);
const differenceInMs = timestamp - previous;
const currentDatePart = getDatePart(timestamp);
const previousDatePart = getDatePart(previous);
const oneDayInMs = 86400000; 
const differenceInDays = (currentDatePart - previousDatePart) / oneDayInMs;

if (differenceInDays >= 1 && differenceInDays < 2) {
  // it is the next day!
    }else if (differenceInMs < 1){
// it is still the same day
     
    } else if (differenceInMs >= 2){
//it is 2 days later..
    }
quartz kindle
#

what is going on lmao

eternal osprey
#

i don't know 😭

quartz kindle
quartz kindle
lyric mountain
#

actually why are u constraining to the same day, instead of 24h?

#

timezones exist, you'll lock your bot to a specific region of the globe

#
switch ((differenceInMs / oneDayInMs)|0) { // to int
  case 0: // within 1 day (not inclusive)
    ...
    break;
  case 1: // within 2 days (not inclusive)
    ...
    break;
  default: // anything else
    ...
    break;
}
quartz kindle
neon leaf
scenic kelp
#

it's an IEEE 754 thing

wheat mesa
#

yeah NaN is just a magic value

#

Same with "Infinity"

frosty gale
#

i dont agree with this

#

who do i complain to

frosty gale
quartz kindle
#

but what exactly were you doing

#

i still dont get it

#

why reverse the buffers?

neon leaf
#

3,2,1 should also be a duplicate of 1,2,3

quartz kindle
neon leaf
#

idk

quartz kindle
#

what about 3,1,2 or 2,1,3?

#

omg, this dude keeps dming me about how to use may api, he claims to be a developer who's building a system for a client

#

but everything he does is ai+nocode

#

"developer" smh

neon leaf
#

smhsmh

#

do you even have openapi docs

quartz kindle
#

nop

neon leaf
#

time to make some then

#

those keep everyone away from asking you

quartz kindle
#

i have docs

#

just not in openapi

neon leaf
#

well

#

the benefit of openapi is that ai coders can feed it to the llm

#

and get real output

quartz kindle
#

i dont know if i wanna support ai devs

#

:^)

neon leaf
#

and nerds can generate their sdks using openapi

#

so they dont need to use any website

frosty gale
#

my initial no sleep solution was to do it in a squared time complexity because i overestimated the computing capacity of my cpu

quartz kindle
#

how large are the buffers?

rustic nova
#

The client probably goes "yeah we need a bit of ai and some of that API"

#

Both equally stupid

frosty gale
quartz kindle
neon leaf
#

oh not again

quartz kindle
#

btw, i copied the functions you guys posted so far, but apparently they are not finding any duplicates? let me douple check my data set lol

neon leaf
#

whats your data

#

make sure its not a buffer array and not a pure 2d number array

#
function generateTestData(size) {
    return Array.from({ length: size }, () => ({
        bytes_buffer: crypto.randomBytes(32)
    }));
}```
quartz kindle
#

nvm its just ben's function is not detecting duplicates

neon leaf
#

okay

#

this is the best I can do

function best_possible_optimizations() {
    const set = new Set()
    const buffer = Buffer.allocUnsafe(32)
    for (const entry of entries) {
        for (let i = 0; i < 32; i++) {
            buffer[i] = entry.bytes_buffer[31 - i]
        }
        const reversed = buffer.toString('binary')
        if (set.has(reversed)) {
            console.log("Duplicate found!")
        }
        const str = entry.bytes_buffer.toString('binary')
        set.add(str)
    }
}```
#
hex_username: 65.929ms
best_possible_optimizations: 42.636ms```
#

this only works if the data is proper though (32 bytes)

frosty gale
#

bros converting it to text binary

neon leaf
#

7ms faster

frosty gale
#

if js sets/maps supported buffers as keys i wouldnt even convert it to a string at all but ascii encoding is the closest i can get

neon leaf
#

they do support any object as key

frosty gale
#

i tried using a buffer and it seems to be by reference

neon leaf
#

but comparing only works if its the same reference

frosty gale
#

the keys should just be hashes under the hood so it shouldnt matter whether you give it a string or number or anything

#

but js just chooses to hash the reference address likely

neon leaf
#

robert  ~/projects  node sha1.js
chloe: 62.837ms
hex_username: 62.182ms
best_possible_optimizations: 19.6ms

#

mmmmmmm

#

looks like i found a way

#
function generate_unique_int_from_32_bytes(buffer) {
    let result = 0;
    for (let i = 0; i < 32; i++) {
        result = (result << 8) | buffer[i];
    }
    return result;
}

function best_possible_optimizations() {
    const set = new Set()
    const buffer = Buffer.allocUnsafe(32)
    for (const entry of entries) {
        for (let i = 0; i < 32; i++) {
            buffer[i] = entry.bytes_buffer[31 - i]
        }
        const reversed = generate_unique_int_from_32_bytes(buffer)
        if (set.has(reversed)) {
            console.log("Duplicate found!")
        }
        set.add(generate_unique_int_from_32_bytes(entry.bytes_buffer))
    }
}```
#

ok this is probably actually it

lament rock
neon leaf
#

I dont see any reason why anything could be more than 5ms faster than that

#

@quartz kindle

frosty gale
#

but your generate unique int i would imagine wouldnt be guaranteed to be unique 100% of the time

neon leaf
#

it is always unique

#

unless its over 32 bytes

#

it just bitshifts a number from the 32 bytes

quartz kindle
neon leaf
#

lemme look at it again

quartz kindle
#

you're just taking the last 4 bytes basically

neon leaf
#

o wait yeah

#
function generate_unique_int_from_32_bytes(buffer) {
    let result = 0;
    for (let i = 0; i < 32; i++) {
        result = result * 256 + buffer[i];
    }
    return result;
}```
quartz kindle
#

thats basically a hashing approach, you need a good number hasher for that

quartz kindle
neon leaf
#
hex_username: 1.029s
best_possible_optimizations: 661.657ms```

1000000 entries
neon leaf
quartz kindle
#

32 bytes into a single number is basically a bigint

#

256bit bigint

frosty gale
quartz kindle
#

but you can try a number hasher like djb2 or fnv

frosty gale
#

so the numbers cant be reliable

quartz kindle
#

but its not guaranteed to be unique

frosty gale
#

yeah no hash is

#

with something like this id want it to be guaranteed to always be unique

#

if one hash happens to collide with one entry and have a false positive thats already not acceptable for 90% of use cases

neon leaf
frosty gale
#

so you can should be able to feed the buffer into a big int

neon leaf
#

bigint was 100% slower than my other code

frosty gale
#

thats guaranteed to always be unique

#

yeah because they use strings under the hood

#

theyre very slow

quartz kindle
neon leaf
#

🤔

quartz kindle
#

not that much difference

#

but still

neon leaf
#

what did you change

quartz kindle
#

different approach, no strings

frosty gale
#

strings suck

#

what is your code

quartz kindle
#
function tim2() {
    debugger
    const rope = Array(255);
    for(let i = 0; i < entries.length; i++) {
        const buffer = entries[i].bytes_buffer;
        let current = rope;
        for(let n = 0; n < buffer.length; n++) {
            const entry = current[buffer[buffer.length - n - 1]];
            if(Buffer.isBuffer(entry)) {
                if(n < buffer.length -1) {
                    const next = Array(255);
                    next[entry[n+1]] = entry;
                    next[buffer[n+1]] = buffer;
                    current = current[buffer[n]] = next;
                } else {
                    console.log("duplicate found");
                }
            } else if(Array.isArray(entry)) {
                current = entry;
            } else {
                current[buffer[n]] = buffer;
                break;
            }
        }
    }
}
#

basically a byte rope

frosty gale
#

cursed code detected

#

but this is the path to performance in js

quartz kindle
#

not sure how reliable it is, ropes are hell to work with (as you can see from the debugger statement lmao)

frosty gale
#

i got 3ms faster by converting my for const loop to for i

#

gonna see if i can get rid of converting to strings or sets

quartz kindle
#

for..of is bad, avoid at all costs

neon leaf
quartz kindle
#

if you dont mind having your code a bit slower :)

neon leaf
#

still faster than forEach

quartz kindle
#

tbh i do use for..of quite a lot

frosty gale
#

wonder what this does under the hood https://www.npmjs.com/package/buffer-map

quartz kindle
#

for non-performance critical work

neon leaf
#

in binary format

frosty gale
#

yeah to binary

#

this npm package is useless

#

you can implement everything it does in just a few more characters of code

#

not even extra lines

#

this is basically the is-odd package

quartz kindle
#

if you wanna squeeze some extra mileage from converting buffers to strings

#

use node's built in string_decoder

frosty gale
#

does this relate to the browser TextDecoder

#

ill try it though

quartz kindle
#

sort of

#

node:string_decoder is basically the decoder that is used under the hood for both buffer.toString and TextDecoder

#

but you get better performance if you use it directly for course, less checks and overhead

#

although is mostly focused on utf8, since its a more complex format

neon leaf
#

tf

#

chloe: 69.182ms
best_possible_optimizations: 41.754ms
best_possible_optimizations_2: 24.044ms
tim2: 34.596ms

#

js just died for a sec

#

its now same as the first again

quartz kindle
#

fluctuations :)

neon leaf
#

yeah string decoder made it ~5ms faster