# How can I obtain the sorting order of the current key at once through the ordered\_st type of ETS?

**URL:** <https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908>\
**Category:** Questions / Help\
**Tags:** erlang, ets\
**Created:** [August 15, 2024, 4:16am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908 "2024-08-15T04:16:13Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![SmallTuring](https://erlangforums.com/user_avatar/erlangforums.com/smallturing/32/1176_2.png) [@SmallTuring](https://erlangforums.com/u/SmallTuring)\
**Post date:** [August 15, 2024, 4:16am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/1 "2024-08-15T04:16:13Z")

</div>

When I use ETS of ordered-set type  
I want to use ets: lookup/2 to query a key and also know its current sorting position  
Similar to using ets: select\_count/2, but select\_count is too slow. Is there any good solution?

---

<div class="post-metadata">

**Author:** ![max-au](https://erlangforums.com/user_avatar/erlangforums.com/max-au/32/1627_2.png) [@max-au](https://erlangforums.com/u/max-au)\
**Post date:** [August 15, 2024, 4:50am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/2 "2024-08-15T04:50:26Z")

</div>

There are two different kinds of `ordered_set`: one without `write_concurrency` (AVL tree), and one with (CA-Tree). Neither one currently implements rank/order operation.

I can imagine repurposing BIT/Fenwick tree for this, but can’t imagine doing that in ETS with concurrent access.

---

<div class="post-metadata">

**Author:** ![SmallTuring](https://erlangforums.com/user_avatar/erlangforums.com/smallturing/32/1176_2.png) [@SmallTuring](https://erlangforums.com/u/SmallTuring)\
**Post date:** [August 15, 2024, 6:52am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/3 "2024-08-15T06:52:26Z")

</div>

(╥﹏╥)  
My current code is roughly like this  
There are 100000 pieces of data in ETS  
It takes approximately 10-50ms to complete  
Is there a way to optimize it?

```erlang
Ms = ets:fun2ms( fun(#ets_rank_atk_record{compare_tuple = C1} = R) when C1 >= CompareTuple->R end),
Rank = ets:select_count(?ETS_RANK_ATK, Ms),

```

---

<div class="post-metadata">

**Author:** ![Maria-12648430](https://erlangforums.com/user_avatar/erlangforums.com/maria-12648430/32/604_2.png) [@Maria-12648430](https://erlangforums.com/u/Maria-12648430)\
**Post date:** [August 15, 2024, 11:11am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/4 "2024-08-15T11:11:40Z")

</div>

What are you actually trying to do here? 😅

---

<div class="post-metadata">

**Author:** ![mikpe](https://erlangforums.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@mikpe](https://erlangforums.com/u/mikpe)\
**Post date:** [August 15, 2024, 1:00pm UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/5 "2024-08-15T13:00:09Z")

</div>

> What are you actually trying to do here?

My thoughts exactly. Knowing the position is pretty useless (there is `ets:slot/2` but it’s not something I’d expect to see in normal code), and furthermore the position is invalidated if anything is inserted or deleted before the key in question.

Perhaps there is a use case, but if so I suspect a different data structure should be used.

---

<div class="post-metadata">

**Author:** ![SmallTuring](https://erlangforums.com/user_avatar/erlangforums.com/smallturing/32/1176_2.png) [@SmallTuring](https://erlangforums.com/u/SmallTuring)\
**Post date:** [August 16, 2024, 2:07am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/6 "2024-08-16T02:07:51Z")

</div>

I use points as a key to save in an ordered ETS, and I hope to  
Can I obtain the ranking of my current points through my key  
I don’t know if there’s a problem with doing this  
If other options should be used, I would greatly appreciate it if you could let me know. Thank you

---

<div class="post-metadata">

**Author:** ![mikpe](https://erlangforums.com/letter_avatar_proxy/v4/letter/m/b487fb/32.png) [@mikpe](https://erlangforums.com/u/mikpe)\
**Post date:** [August 16, 2024, 11:36am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/7 "2024-08-16T11:36:23Z")

</div>

> I use points as a key to save in an ordered ETS

If I understand you correctly, this means that you:

1. Have a set table, T1, containing records with some unspecified key type.
2. Have a second set table, T2, with integer keys being the positions of records in T1.

This is a really odd approach. First of all, you could just use the original T1 key to also index T2, there is no reason to take a detour over integer positions for Erlang ETS tables. Secondly the mapping from key to position is invalidated whenever keys are inserted in or deleted from T1, which means T2 would have to be rebuilt.

What are you actually trying to achieve here?

---

<div class="post-metadata">

**Author:** ![SmallTuring](https://erlangforums.com/user_avatar/erlangforums.com/smallturing/32/1176_2.png) [@SmallTuring](https://erlangforums.com/u/SmallTuring)\
**Post date:** [August 16, 2024, 11:49am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/8 "2024-08-16T11:49:03Z")

</div>

Thank you for your reply 😶‍🌫️  
I don’t know if it’s a translation issue, which may have caused my description to be inaccurate,

My requirement is to create a ranking list of 100000 people with points, and the points data will change,

So my idea is to save the points as keys in order\_cets,

But if I want to know the ranking of my current points, it seems difficult to quickly obtain it?

Or should I use other data structures? What should I do in Erlang?

---

<div class="post-metadata">

**Author:** ![Maria-12648430](https://erlangforums.com/user_avatar/erlangforums.com/maria-12648430/32/604_2.png) [@Maria-12648430](https://erlangforums.com/u/Maria-12648430)\
**Post date:** [August 18, 2024, 7:49am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/9 "2024-08-18T07:49:51Z")

</div>

> [@SmallTuring](#):
>
> My requirement is to create a ranking list of 100000 people with points, and the points data will change,
> 
> So my idea is to save the points as keys in order\_cets

The key value of an object can’t be changed.

---

<div class="post-metadata">

**Author:** ![juhlig](https://erlangforums.com/user_avatar/erlangforums.com/juhlig/32/837_2.png) [@juhlig](https://erlangforums.com/u/juhlig)\
**Post date:** [August 20, 2024, 9:35am UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/10 "2024-08-20T09:35:09Z")

</div>

Your approach has several flaws.

One is that, as @Maria-12648430 pointed out, you cannot change (via `update_counter` or `update_element`) the value in the key position of a record. So if you want to change the points value, you have to read the current record, delete it, then re-insert it with the updated value (or the other way round, first insert the updated and then delete the old).

Also, think of what would happen if two (or more) people have the same points value. Since you are using a `set` table here (ordered or not), there can only be _ **1** _ record per key. Ie, if you would try to insert a record with a point value that some other person already has, you would either be unable to do so (when using `insert`) or the person currently having the same number of points would be evicted (when using `insert_new`).

> [@SmallTuring](#):
>
> My current code is roughly like this  
> There are 100000 pieces of data in ETS  
> It takes approximately 10-50ms to complete  
> Is there a way to optimize it?
> 
> ```erlang
> Ms = ets:fun2ms( fun(#ets_rank_atk_record{compare_tuple = C1} = R) when C1 >= CompareTuple->R end),
> Rank = ets:select_count(?ETS_RANK_ATK, Ms),
> 
> ```

This won’t work, that is `Rank` will always be `0`. The reason is that your match spec returns the _record_ (`... -> R`) when `C1 >= CompareTuple`. However, the documentation says that a record is counted if the match spec returns `true` for it:

> If the match specification returns `true` for an object, that object considered a match and is counted. For any other result from the match specification the object is not considered a match and is therefore not counted.

> [@SmallTuring](#):
>
> Or should I use other data structures? What should I do in Erlang?

There is no general answer to this. It depends on the larger picture, and what operations are more important to be fast than whatever else. There will always be a tradeoff, for some things to be faster other things have to be slower, or more resource-hungry.

---

<div class="post-metadata">

**Author:** ![SmallTuring](https://erlangforums.com/user_avatar/erlangforums.com/smallturing/32/1176_2.png) [@SmallTuring](https://erlangforums.com/u/SmallTuring)\
**Post date:** [August 20, 2024, 12:44pm UTC](https://erlangforums.com/t/how-can-i-obtain-the-sorting-order-of-the-current-key-at-once-through-the-ordered-st-type-of-ets/3908/11 "2024-08-20T12:44:25Z")

</div>

Thank you, I understand now ☕
