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

Return a map when asking for multiple resources #18

Open
ikjahaa opened this issue Oct 2, 2016 · 7 comments
Open

Return a map when asking for multiple resources #18

ikjahaa opened this issue Oct 2, 2016 · 7 comments

Comments

@ikjahaa
Copy link

ikjahaa commented Oct 2, 2016

GW2 api Accessing_resources guidelines

In my case, i want to add the ItemInfo to my Item object, instead of sending a http request per item we can make use of the ?ids=.... endpoint. The only problem now is that the api returns me an array of ItemInfo's. It would enhance my application's speed if it would return a Map based on the id of the ItemInfo as key, and the itemInfo itself as the value @ time of parsing instead of it having to be done by me.

@Nithanim
Copy link
Owner

Nithanim commented Oct 9, 2016

I am afraid I see no way to do this currently since the parsing is done by an external library where I think it is not possible for me to hook into the parsing to create a map. Since I want to keep the results of this wrapper as close to the results of the official api, it seems not so bad to return it as an array, but I do see your point.

However, since I have never used my api and checked the official results I am not really sure, but i really hope for you that the order of the ids you provide is reflected in the order of the results. This would enable you to to lookup the item in the result array with the same index of the id in the request array.

int[] req = { 6678, 3456, 25657};
ItemInfo[] res = ...;
Assert.assertTrue(req[0] == res[0].getId());
Assert.assertTrue(req[1] == res[1].getId());
Assert.assertTrue(req[2] == res[2].getId());

In case that really works and you decide to use it, I advice you to add a fallback mechanism in case this fails since I cannot guarantee the results from the official api and the deserialization library.
I might add such a map as an additional feature in the future but I really don't have the time currently to put any work into this library, sadly.

@ikjahaa
Copy link
Author

ikjahaa commented Oct 9, 2016

I'm not always fetching every single id, so the index isn't mapped to the right id. I ended-up pumping it into a map by using JAVA 8 Streams, which doesn't affect my performance that much.

on a side note, i find your api very pleasant to work with.

Regards,
Koen

@Nithanim
Copy link
Owner

Thank you for your kind words, I really appreciate that!

So I found some time in between and tinkered around with gson. Lucky this project rewarded me with a lot of experience with it so I managed to decode the json array as a IntObjectMap. However, as I like to avoid boxing in a normal map, I coded it against koloboke which conveniently has a HashIntObjMap using the primitve int while maintaining the compatibility to the boxed interface of java.util.Map.

My current proof-of-concept version has additional methods that provide the "ids" parameter as a such a map. It seems (but I am still not sure) that the jvm ignores the missing class in the classdefinition and load it without any problem which would make the integration possible without adding it as a required dependency. Anyone using this method however would need to manually declare the dependency. The gw2api checks for the availability of the dependency and ignores the functionality completely if not available.

The bad news is that this dependency is extremely large (around 18MB) so I would like to ship a stripped down version that include the necessary parts only. I still need to figure out what is needed for this to work and what legal implication this has. This version would simply be available with its own classifier.

@leventov
Copy link

@Nithanim Koloboke Compile project addresses the dependency size issue: https://koloboke.com

@Nithanim
Copy link
Owner

Nithanim commented Oct 31, 2016

Some time ago I stumbled upon Koloboke Compile but I somehow dropped the idea of using it immediately since you make your own map that is not compatible with any other similar maps (I think) except if it used primitive interfaces (which I don't know) (edit2: just realised that I am the one in charge of supplying the interface. derp. I am pretty sure I could use the ones already existing). That's why I only kept the original collection in mind because it is at least interchangeable for all using the same library.
Just thinking out loud: If I used the whole library it would be too big, but stripping it down without relocation could result in weird errors later on and with relocation we would have the same problem... So Koloboke Compile would not be a bad idea after all.

A "couple" (edit: I lied, it was 2 at most; too much to do is not helping perceiving time I guess) of days ago I found some time to try it out but it greeted me with an exception specific to Netbeans immediately. Turns out that it goes not well with my IDE forcing me to work with apparently non-compilable code that in fact does compile. I mean I could try to live with the constant errors all over the place for the time being if you really want the

HashIntObjMap<ItemInfo> getMap(int[] ids);

for the ItemsResource :)
I still have to report the error though. I am honored seeing you here @leventov! Did I accidentally notify you with the link?

@leventov
Copy link

@Nithanim

make your own map that is not compatible with any other similar maps (I think) except if it used primitive interfaces

No, ubiquitous compatibility was one of the goals of Koloboke Compile. You can use java.util.Map or almost any other non-standard interface. For example, I've made a PoC implementation of Trove's interfaces using Koloboke Compile: https://github.com/leventov/trove-over-koloboke-compile (no cheat, real Trove's interfaces, passing Trove's unit tests).

greeted me with an exception specific to Netbeans immediately. Turns out that it goes not well with my IDE forcing me to work with apparently non-compilable code that in fact does compile.

This is very sad. I spend a lot of time making Koloboke Compile compatible with Eclipse. Couldn't something similar to this be done in Netbeans? Specifying annotation processing Jar manually in IDE settings.

I mean I could try to live with the constant errors all over the place for the time being if you really want the

I don't understand why errors will be "all over the place". In the worst case, only constructors calls in static factory methods should be "errors", but all other code should use those static factory methods.

Did I accidentally notify you with the link?

No, I periodically monitor mentions of koloboke in github issues.

@Nithanim
Copy link
Owner

@leventov

No, ubiquitous compatibility was one of the goals of Koloboke Compile. You can use java.util.Map or almost any other non-standard interface.

Yes, I know that it is compatible with the java collections but I wanted it to have it also compatible with a general primitive map interface if that would be possible. I figured (afterwards) that I could still use the interfaces of the full Koloboke library which I think are not that big (only its implementation).

This is very sad. I spend a lot of time making Koloboke Compile compatible with Eclipse. Couldn't something similar to this be done in Netbeans? Specifying annotation processing Jar manually in IDE settings.

I would not call that sad, but rather unfortunate. I seems weird to me that no-one reported/testet it till now. Annotation processing works out of the box with Netbeans, flawlessy. I can't even specify if I want to use annotation processing or not when using a maven project, a choice is only available for ant projects.

For this project, I am using Lombok in nearly all of the source files without any issue. However, Koloboke Compile greeted me with

Koloboke Compile annotation processor threw an exception while processing this type,
  please report this on https://github.com/leventov/Koloboke/issues:
  java.lang.ClassCastException: org.netbeans.modules.java.source.parsing.CachingArchiveClassLoader cannot be cast to java.net.URLClassLoader
    at com.koloboke.compile.processor.KolobokeCollectionProcessor.getClassPathStrings(KolobokeCollectionProcessor.kt:1606)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor.createLauncher$compile_compileKotlin(KolobokeCollectionProcessor.kt:98)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor$ProcessingCxt$GenerationCxt.<init>(KolobokeCollectionProcessor.kt:624)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor$ProcessingCxt$MapGenerationCxt.<init>(KolobokeCollectionProcessor.kt:512)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor$ProcessingCxt.mapGenerationCxt(KolobokeCollectionProcessor.kt:492)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor$ProcessingCxt.<init>(KolobokeCollectionProcessor.kt:320)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor$process$1.invoke(KolobokeCollectionProcessor.kt:206)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor$process$1.invoke(KolobokeCollectionProcessor.kt:79)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor.safeTypeProcess(KolobokeCollectionProcessor.kt:232)
    at com.koloboke.compile.processor.KolobokeCollectionProcessor.process(KolobokeCollectionProcessor.kt:205)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:856)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:752)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$2200(JavacProcessingEnvironment.java:99)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1081)
    at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1157)
    at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1210)
    at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1099)
    at com.sun.tools.javac.api.JavacTaskImpl.enter(JavacTaskImpl.java:374)
    at com.sun.tools.javac.api.JavacTaskImpl.enter(JavacTaskImpl.java:311)
    at org.netbeans.modules.java.source.parsing.JavacParser.moveToPhase(JavacParser.java:630)
    at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:496)
    at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:163...

which was pretty straight forward in telling me what has happened instead in failing silently and screwing everything up and wasting time.

I don't understand why errors will be "all over the place". In the worst case, only constructors calls in static factory methods should be "errors", but all other code should use those static factory methods.

That's how it has been at first (which makes sense) which I thought would not be such a problem. But for some reason, after restarting my IDE, some classes are no longer processed by Lombok and are now missing all methods resulting in errors in other classes since nothing can be found anymore. Most of the classes seem to be fine though and I do not understand that either. After some more testing and completely removing Koloboke again the errors persisted, and after some restarts Netbeans refuses to start altogether now.

That was a nice adventure and I will continue it in some days/weeks when I find time again, sorry.

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

No branches or pull requests

3 participants