-
Notifications
You must be signed in to change notification settings - Fork 13
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
Manifest (performance improvement) #182
Conversation
Convert to lowercase, lol. AO should've adopted a standard for content spelling years ago. |
@Salanto That's what I ended up doing. |
5181804
to
e1feede
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
holy shit it actually became real
the windows command is |
@stonedDiscord You said manfred's sprites don't load anymore after you add the manifest? |
confirmed, I guess? |
I'm closing this. 24 Megs per WebAO session is not tolerable. |
@@ -11,7 +13,7 @@ const getAnimLength = async (url) => { | |||
const extensions = ['.gif', '.webp', '.apng']; | |||
for (const extension of extensions) { | |||
const urlWithExtension = url + extension; | |||
const exists = await fileExists(urlWithExtension); | |||
const exists = await fileExistsManifest(urlWithExtension); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's some extra spacing here
* Otherwise, look it up in the manifest */ | ||
const fileExistsManifest = async (url) => | ||
new Promise((resolve, reject) => { | ||
if(client.manifest.length == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
===
here please
resolve(fileExists(url)); | ||
return; | ||
} | ||
const c_url = encodeURI(canonicalizePath(decodeURI(url.slice(AO_HOST.length)))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, JS uses camel case, so it may be a good idea to stick with that schema. Also calling it the full canonical.
Kinda nitpicking that since c
has to be slightly interpreted
} else { | ||
url = `${characterFolder}${encodeURI(charactername)}/${encodeURI( | ||
prefix | ||
)}${encodeURI(emotename)}${extension}`; | ||
} | ||
const exists = await fileExists(url); | ||
|
||
const exists = await fileExistsManifest(url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to update the unit tests for setEmote
else if (comparison < 0) | ||
start = middle + 1; | ||
else | ||
end = middle - 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we get unit tests for this file and can you also convert it to TS?
} | ||
const c_url = encodeURI(canonicalizePath(decodeURI(url.slice(AO_HOST.length)))); | ||
|
||
if(binarySearch(client.manifest, c_url) != null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!==
/* Removes `/./`, `/../`, and `//`. | ||
* Does not add a leading `/` or `./`. | ||
* Does not add a trailing `/`. */ | ||
export function canonicalizePath(path: string): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure to update the unit tests please
* Does not add a leading `/` or `./`. | ||
* Does not add a trailing `/`. */ | ||
export function canonicalizePath(path: string): string { | ||
const path_elements = path.split("/"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
camelCasing here please
@@ -10,11 +10,11 @@ const tryUrls = async (url: string) => { | |||
for (let i = 0; i < urlExtensionsToTry.length; i++) { | |||
const extension = urlExtensionsToTry[i] | |||
const fullFileUrl = url + extension | |||
const exists = await fileExists(fullFileUrl); | |||
const exists = await fileExistsManifest(fullFileUrl); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unit tests for this please
I would suggest making separate manifests in these places:
Then make a file that instructs webAO where each manifest is located, and to preload each manifest (except for the character manifests). This would be useful for a more general mount system where there are multiple sources of assets. There is a more esoteric approach that focuses on your particular need, which is to use filename hashes and also use their byte representation instead of text. You could also try to encode it in a tree structure like Huffman coding, e.g.
|
Getting some air conditioning vibes rn : |
WIP
This will probably be replaced by a hash-based manifest given the official site has 530K files.....
This PR will add support for the
manifest.txt
proposed in #85. It's expected to bring performance improvements. Closes #85.Description
The manifest is optional. It must located at the root of the base URL, with the name
manifest.txt
. It must contain a list of LF, CRLF, LFCR, or CR-terminated paths, relative to the base URL. A path is made up of components, separated by either/
or\
. Each path component must not include any of the bytes/
,\
, LF, or CR. If the manifest is present, it must contain paths of all files and directories accessible to the client. A manifest may include a leading empty path component or a leading.
path component. However, this is discouraged. The manifest should be sorted in ascending order.Design issues
find . >manifest.txt
or whatever the Windows equivalent is. To fix this, escaping and/or zero-termination may be used instead.\
is a valid path separator. Thus,/
-separated path components may not contain\
. This is done for compatibility with Windows.\
and/
path component separators is allowed. This is inelegant, but easy to process.Implementation issues
log2(n)+1
comparisons in the worst case. This is not an issue for vanilla, a vanilla manifest is about 3000 paths and the worst case number of comparisons is 13. Also, storing all the flle paths wastes space and causes a bunch of cache misses. Consider using a hash set.fileExists
to not break the API. Look into removing it.Practical issues