getKey in FoundationDB returns unexpected result












1















I trying to find a key in some Subspace at FoundationDB with getKey and KeySelector. In case if result exists in Subspace it works pretty well.



val key      = new Tuple().add(3)
val subspace = new Subspace(new Tuple().add("test-subspace"))

tr.set(key.pack(), new Tuple().pack())
tr.set(subspace.pack(key), new Tuple().pack())

tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
.thenApply[Tuple] { result =>
println(Tuple.fromBytes(result)) // ("test-subspace", 3)
subspace.unpack(result) // (3)
}


In the same time, if key does not exist in target subspace, it returns me key that was found in default subspace. Which is not what I expected...



val key      = new Tuple().add(3)
val subspace = new Subspace(new Tuple().add("test-subspace"))

tr.set(key.pack(), new Tuple().pack())

tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
.thenApply[Tuple] { result =>
println(Tuple.fromBytes(result)) // (3)
subspace.unpack(result) // Cannot unpack key that is not contained in subspace.
}


Also, if db empty, getKey instead of returning null, returns some weird byte array which cannot be parsed by Tuple.fromBytes.



val key = new Tuple().add("my-key")    

tr.getKey(KeySelector.firstGreaterOrEqual(key.pack()))
.thenApply[Tuple] { result =>
println(result == null) // false
Tuple.fromBytes(result) // throws java.lang.IllegalArgumentException: Unknown tuple data type -1 at index 0
}


How should I handle situations when target subspaces do not contain the search result?










share|improve this question





























    1















    I trying to find a key in some Subspace at FoundationDB with getKey and KeySelector. In case if result exists in Subspace it works pretty well.



    val key      = new Tuple().add(3)
    val subspace = new Subspace(new Tuple().add("test-subspace"))

    tr.set(key.pack(), new Tuple().pack())
    tr.set(subspace.pack(key), new Tuple().pack())

    tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
    .thenApply[Tuple] { result =>
    println(Tuple.fromBytes(result)) // ("test-subspace", 3)
    subspace.unpack(result) // (3)
    }


    In the same time, if key does not exist in target subspace, it returns me key that was found in default subspace. Which is not what I expected...



    val key      = new Tuple().add(3)
    val subspace = new Subspace(new Tuple().add("test-subspace"))

    tr.set(key.pack(), new Tuple().pack())

    tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
    .thenApply[Tuple] { result =>
    println(Tuple.fromBytes(result)) // (3)
    subspace.unpack(result) // Cannot unpack key that is not contained in subspace.
    }


    Also, if db empty, getKey instead of returning null, returns some weird byte array which cannot be parsed by Tuple.fromBytes.



    val key = new Tuple().add("my-key")    

    tr.getKey(KeySelector.firstGreaterOrEqual(key.pack()))
    .thenApply[Tuple] { result =>
    println(result == null) // false
    Tuple.fromBytes(result) // throws java.lang.IllegalArgumentException: Unknown tuple data type -1 at index 0
    }


    How should I handle situations when target subspaces do not contain the search result?










    share|improve this question



























      1












      1








      1








      I trying to find a key in some Subspace at FoundationDB with getKey and KeySelector. In case if result exists in Subspace it works pretty well.



      val key      = new Tuple().add(3)
      val subspace = new Subspace(new Tuple().add("test-subspace"))

      tr.set(key.pack(), new Tuple().pack())
      tr.set(subspace.pack(key), new Tuple().pack())

      tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
      .thenApply[Tuple] { result =>
      println(Tuple.fromBytes(result)) // ("test-subspace", 3)
      subspace.unpack(result) // (3)
      }


      In the same time, if key does not exist in target subspace, it returns me key that was found in default subspace. Which is not what I expected...



      val key      = new Tuple().add(3)
      val subspace = new Subspace(new Tuple().add("test-subspace"))

      tr.set(key.pack(), new Tuple().pack())

      tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
      .thenApply[Tuple] { result =>
      println(Tuple.fromBytes(result)) // (3)
      subspace.unpack(result) // Cannot unpack key that is not contained in subspace.
      }


      Also, if db empty, getKey instead of returning null, returns some weird byte array which cannot be parsed by Tuple.fromBytes.



      val key = new Tuple().add("my-key")    

      tr.getKey(KeySelector.firstGreaterOrEqual(key.pack()))
      .thenApply[Tuple] { result =>
      println(result == null) // false
      Tuple.fromBytes(result) // throws java.lang.IllegalArgumentException: Unknown tuple data type -1 at index 0
      }


      How should I handle situations when target subspaces do not contain the search result?










      share|improve this question
















      I trying to find a key in some Subspace at FoundationDB with getKey and KeySelector. In case if result exists in Subspace it works pretty well.



      val key      = new Tuple().add(3)
      val subspace = new Subspace(new Tuple().add("test-subspace"))

      tr.set(key.pack(), new Tuple().pack())
      tr.set(subspace.pack(key), new Tuple().pack())

      tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
      .thenApply[Tuple] { result =>
      println(Tuple.fromBytes(result)) // ("test-subspace", 3)
      subspace.unpack(result) // (3)
      }


      In the same time, if key does not exist in target subspace, it returns me key that was found in default subspace. Which is not what I expected...



      val key      = new Tuple().add(3)
      val subspace = new Subspace(new Tuple().add("test-subspace"))

      tr.set(key.pack(), new Tuple().pack())

      tr.getKey(KeySelector.firstGreaterOrEqual(subspace.pack(key)))
      .thenApply[Tuple] { result =>
      println(Tuple.fromBytes(result)) // (3)
      subspace.unpack(result) // Cannot unpack key that is not contained in subspace.
      }


      Also, if db empty, getKey instead of returning null, returns some weird byte array which cannot be parsed by Tuple.fromBytes.



      val key = new Tuple().add("my-key")    

      tr.getKey(KeySelector.firstGreaterOrEqual(key.pack()))
      .thenApply[Tuple] { result =>
      println(result == null) // false
      Tuple.fromBytes(result) // throws java.lang.IllegalArgumentException: Unknown tuple data type -1 at index 0
      }


      How should I handle situations when target subspaces do not contain the search result?







      java scala foundationdb






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 13 '18 at 15:39







      Arthur Kushka

















      asked Nov 13 '18 at 15:15









      Arthur KushkaArthur Kushka

      556




      556
























          2 Answers
          2






          active

          oldest

          votes


















          1














          This is expected behavior. Keyselector returns you the key that matches the condition - in this case first key that is greater or equal to the passed byte. You would need to check if returned key is valid as per your subspace requirement - by using subspace.contains() or any other validation on the returned key.



          Same explanation for the second question- the returned key could be some special pre-existing row in the db, that is not created using tuple layer. Hence it cannot be parsed using tuple layer. You need to check for key validity by using subspace.contains or some similar check.






          share|improve this answer
























          • yea, probably, but tbh, it makes awful user experience, cause there are no docs that describe such kind of behavior and in general it's very tricky logic

            – Arthur Kushka
            Nov 15 '18 at 9:29











          • you could use start and end keys generated subspace.range() methods to restrict the returned keys to the intended workspace. KeySelectors are a bit tricky, but they make advanced scan cases possible.

            – Gaurav Agarwal
            Nov 15 '18 at 10:24



















          2














          To add on to what Guarav said, when a key selector resolves to a key before the beginning of the database, it returns the empty key (''). If the key resolves past the end of the database, you'll get 'xff' in a normal transaction or 'xffxff' if your transaction is allowed to read system keys. This is mentioned briefly at the end of the key selector documentation here.



          As for not returning a result outside of your subspace, to do so would probably require getKey accepting a bound key parameter that restricts searches beyond that key. It doesn't currently have that parameter, but getRange does and can be used to perform the same query if you use a limit of 1. For example, you could do:



          tr.getRange(KeySelector.firstGreaterOrEqual(subspace.pack(key)), subspace.range().end, 1)


          In this case, the result will either have a key if one could be found in the subspace matching your key selector or will be empty if one could not. Of course, you'll also get back the value in this query.






          share|improve this answer























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284066%2fgetkey-in-foundationdb-returns-unexpected-result%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            This is expected behavior. Keyselector returns you the key that matches the condition - in this case first key that is greater or equal to the passed byte. You would need to check if returned key is valid as per your subspace requirement - by using subspace.contains() or any other validation on the returned key.



            Same explanation for the second question- the returned key could be some special pre-existing row in the db, that is not created using tuple layer. Hence it cannot be parsed using tuple layer. You need to check for key validity by using subspace.contains or some similar check.






            share|improve this answer
























            • yea, probably, but tbh, it makes awful user experience, cause there are no docs that describe such kind of behavior and in general it's very tricky logic

              – Arthur Kushka
              Nov 15 '18 at 9:29











            • you could use start and end keys generated subspace.range() methods to restrict the returned keys to the intended workspace. KeySelectors are a bit tricky, but they make advanced scan cases possible.

              – Gaurav Agarwal
              Nov 15 '18 at 10:24
















            1














            This is expected behavior. Keyselector returns you the key that matches the condition - in this case first key that is greater or equal to the passed byte. You would need to check if returned key is valid as per your subspace requirement - by using subspace.contains() or any other validation on the returned key.



            Same explanation for the second question- the returned key could be some special pre-existing row in the db, that is not created using tuple layer. Hence it cannot be parsed using tuple layer. You need to check for key validity by using subspace.contains or some similar check.






            share|improve this answer
























            • yea, probably, but tbh, it makes awful user experience, cause there are no docs that describe such kind of behavior and in general it's very tricky logic

              – Arthur Kushka
              Nov 15 '18 at 9:29











            • you could use start and end keys generated subspace.range() methods to restrict the returned keys to the intended workspace. KeySelectors are a bit tricky, but they make advanced scan cases possible.

              – Gaurav Agarwal
              Nov 15 '18 at 10:24














            1












            1








            1







            This is expected behavior. Keyselector returns you the key that matches the condition - in this case first key that is greater or equal to the passed byte. You would need to check if returned key is valid as per your subspace requirement - by using subspace.contains() or any other validation on the returned key.



            Same explanation for the second question- the returned key could be some special pre-existing row in the db, that is not created using tuple layer. Hence it cannot be parsed using tuple layer. You need to check for key validity by using subspace.contains or some similar check.






            share|improve this answer













            This is expected behavior. Keyselector returns you the key that matches the condition - in this case first key that is greater or equal to the passed byte. You would need to check if returned key is valid as per your subspace requirement - by using subspace.contains() or any other validation on the returned key.



            Same explanation for the second question- the returned key could be some special pre-existing row in the db, that is not created using tuple layer. Hence it cannot be parsed using tuple layer. You need to check for key validity by using subspace.contains or some similar check.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 14 '18 at 18:33









            Gaurav AgarwalGaurav Agarwal

            514




            514













            • yea, probably, but tbh, it makes awful user experience, cause there are no docs that describe such kind of behavior and in general it's very tricky logic

              – Arthur Kushka
              Nov 15 '18 at 9:29











            • you could use start and end keys generated subspace.range() methods to restrict the returned keys to the intended workspace. KeySelectors are a bit tricky, but they make advanced scan cases possible.

              – Gaurav Agarwal
              Nov 15 '18 at 10:24



















            • yea, probably, but tbh, it makes awful user experience, cause there are no docs that describe such kind of behavior and in general it's very tricky logic

              – Arthur Kushka
              Nov 15 '18 at 9:29











            • you could use start and end keys generated subspace.range() methods to restrict the returned keys to the intended workspace. KeySelectors are a bit tricky, but they make advanced scan cases possible.

              – Gaurav Agarwal
              Nov 15 '18 at 10:24

















            yea, probably, but tbh, it makes awful user experience, cause there are no docs that describe such kind of behavior and in general it's very tricky logic

            – Arthur Kushka
            Nov 15 '18 at 9:29





            yea, probably, but tbh, it makes awful user experience, cause there are no docs that describe such kind of behavior and in general it's very tricky logic

            – Arthur Kushka
            Nov 15 '18 at 9:29













            you could use start and end keys generated subspace.range() methods to restrict the returned keys to the intended workspace. KeySelectors are a bit tricky, but they make advanced scan cases possible.

            – Gaurav Agarwal
            Nov 15 '18 at 10:24





            you could use start and end keys generated subspace.range() methods to restrict the returned keys to the intended workspace. KeySelectors are a bit tricky, but they make advanced scan cases possible.

            – Gaurav Agarwal
            Nov 15 '18 at 10:24













            2














            To add on to what Guarav said, when a key selector resolves to a key before the beginning of the database, it returns the empty key (''). If the key resolves past the end of the database, you'll get 'xff' in a normal transaction or 'xffxff' if your transaction is allowed to read system keys. This is mentioned briefly at the end of the key selector documentation here.



            As for not returning a result outside of your subspace, to do so would probably require getKey accepting a bound key parameter that restricts searches beyond that key. It doesn't currently have that parameter, but getRange does and can be used to perform the same query if you use a limit of 1. For example, you could do:



            tr.getRange(KeySelector.firstGreaterOrEqual(subspace.pack(key)), subspace.range().end, 1)


            In this case, the result will either have a key if one could be found in the subspace matching your key selector or will be empty if one could not. Of course, you'll also get back the value in this query.






            share|improve this answer




























              2














              To add on to what Guarav said, when a key selector resolves to a key before the beginning of the database, it returns the empty key (''). If the key resolves past the end of the database, you'll get 'xff' in a normal transaction or 'xffxff' if your transaction is allowed to read system keys. This is mentioned briefly at the end of the key selector documentation here.



              As for not returning a result outside of your subspace, to do so would probably require getKey accepting a bound key parameter that restricts searches beyond that key. It doesn't currently have that parameter, but getRange does and can be used to perform the same query if you use a limit of 1. For example, you could do:



              tr.getRange(KeySelector.firstGreaterOrEqual(subspace.pack(key)), subspace.range().end, 1)


              In this case, the result will either have a key if one could be found in the subspace matching your key selector or will be empty if one could not. Of course, you'll also get back the value in this query.






              share|improve this answer


























                2












                2








                2







                To add on to what Guarav said, when a key selector resolves to a key before the beginning of the database, it returns the empty key (''). If the key resolves past the end of the database, you'll get 'xff' in a normal transaction or 'xffxff' if your transaction is allowed to read system keys. This is mentioned briefly at the end of the key selector documentation here.



                As for not returning a result outside of your subspace, to do so would probably require getKey accepting a bound key parameter that restricts searches beyond that key. It doesn't currently have that parameter, but getRange does and can be used to perform the same query if you use a limit of 1. For example, you could do:



                tr.getRange(KeySelector.firstGreaterOrEqual(subspace.pack(key)), subspace.range().end, 1)


                In this case, the result will either have a key if one could be found in the subspace matching your key selector or will be empty if one could not. Of course, you'll also get back the value in this query.






                share|improve this answer













                To add on to what Guarav said, when a key selector resolves to a key before the beginning of the database, it returns the empty key (''). If the key resolves past the end of the database, you'll get 'xff' in a normal transaction or 'xffxff' if your transaction is allowed to read system keys. This is mentioned briefly at the end of the key selector documentation here.



                As for not returning a result outside of your subspace, to do so would probably require getKey accepting a bound key parameter that restricts searches beyond that key. It doesn't currently have that parameter, but getRange does and can be used to perform the same query if you use a limit of 1. For example, you could do:



                tr.getRange(KeySelector.firstGreaterOrEqual(subspace.pack(key)), subspace.range().end, 1)


                In this case, the result will either have a key if one could be found in the subspace matching your key selector or will be empty if one could not. Of course, you'll also get back the value in this query.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 26 '18 at 17:20









                A.J.A.J.

                462




                462






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284066%2fgetkey-in-foundationdb-returns-unexpected-result%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Full-time equivalent

                    Bicuculline

                    さくらももこ