Coder Social home page Coder Social logo

Comments (13)

MaksymZavershynskyi avatar MaksymZavershynskyi commented on June 14, 2024 1

The other major issue with PersistentOrderedMap is that it has expected O(log n) time complexity. Which means it is possible that if some contract uses it the user of the contract might accidentally encounter the worst case and pay O(n) gas, which can be quite high. For instance if we use skip list for token implementation, and lets say we have 10k accounts in this token, on average users would pay gas for 13 access to storage, but when they hit the worst case they would pay for 10k accesses to storage, which is 1000 times more gas, which does not make a good UX and might actually create issues for the contract. Once AVL tree is implemented we should remove SkipList and SkipList-based implementation.

Also, let's add lowerOrEq and greaterOrEq to the API list.

from near-sdk-as.

willemneal avatar willemneal commented on June 14, 2024

I agree that this is better for consistency and to not use skip lists at all, but I just want to point out that if you do have randomness, it would require (1-p)^10000, so p = 1/e: (1-1/e)^10000 = 9.8 * 10^-1993, which while possible is insanely unlikely. The one issue with skip lists is that deleting elements can mess up the balance, so to fix this you have to reflip the height of a neighbor and I don't think you have to do it every time.

from near-sdk-as.

gitcoinbot avatar gitcoinbot commented on June 14, 2024

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


This issue now has a funding of 300.0 DAI (300.0 USD @ $1.0/DAI) attached to it.

from near-sdk-as.

gitcoinbot avatar gitcoinbot commented on June 14, 2024

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


Work has been started.

These users each claimed they can complete the work by 1 month from now.
Please review their action plans below:

1) kaiba42 has been approved to start work.

  1. Create skeleton for AVLTree implementation following the given API, matching the rust-sdk implementation.
  2. Implement set of tests based on rust-sdk tests. Tests should provide full coverage of public and internal methods, in addition to testing the invariants of an AVL tree. Need to also find an alternative to quickcheck for AssemblyScript for fuzz/prop testing (any suggestions would be great!). Or at least use as-pect tests similar to those mentioned above.
  3. Implement AVLTree.
  4. Confirm that tests are all passing, and implemented correctly.

Learn more on the Gitcoin Issue Details page.

from near-sdk-as.

kaiba42 avatar kaiba42 commented on June 14, 2024

Is there an API for iteration that should be followed? Put another way, what is the API for iterating through existing collections like persistentMap or persistentSet? Thanks!

from near-sdk-as.

willemneal avatar willemneal commented on June 14, 2024

I'm about to merge a new PR that creates a new Unordered map, #85, which uses a persistent vector to hold the keys. The keys are then ordered until a key before than the last two is deleted, which causes the last key to be swapped with the index of the key being removed. The AVL tree will remove this limitation.

As for iteration, AssemblyScript is missing iteration (it's a work in progress) and so in #85, which also updates persistentSet, there are methods for ranges that return arrays of values, keys, and entries. So frontend code can get the size of the map and then perform the iteration by using these methods. An Ordered map will use this tree to provide the same API.

from near-sdk-as.

kaiba42 avatar kaiba42 commented on June 14, 2024

Got it. Does this API for an AVLTree look good to you then? It swaps range() for values(), keys(), and entries(), following your API for the new Unordered map implementation.

API

class AVLTree<K, V> {
    private _elementPrefix: string;

    /**
     * A string name is used as a prefix for writing keys to storage.
     */
    constructor(name: string) {
        this._elementPrefix = name + collections._KEY_ELEMENT_SUFFIX;
    }
  
    /**
     * @returns Number of elements in the tree.
     */
    get size(): u32 {
        // TODO implement size()
        throw new Error("TODO implement size()")
    }

    /**
     * @returns Root key of the tree.
     */
    get root(): K {
        // TODO make private
        // TODO implement root()
        throw new Error("TODO implement root()")
    }
  
    /**
     * @returns Whether the key is present in the tree.
     */
    has(key: K): boolean {
        // TODO implement has()
        throw new Error("TODO implement has()")
    }
    //alias to match rust sdk
    containsKey(key: K): boolean {
        return this.has(key);
    }
  
    /**
     * If key is not present in the tree, a new node is added with the value.
     * Otherwise update the node with the new value.
     * 
     * @param key Key of the element.
     * @param value The new value of the element. 
     */
    set(key: K, value: V): void {
        // TODO implement set()
        throw new Error("TODO implement set()")
    }
    //alias to match rust sdk
    insert(key: K, value: V): void {
        this.set(key, value);
    }
  
    /**
     * Retrieves a related value for a given key or throws error "key not found"
     * 
     * @param key Key of the element.
     * @returns Value for the given key or the default value.
     */
    get(key: K): V {
        // TODO implement get()
        throw new Error("TODO implement get()")
    }
  
    /**
     * Retrieves the related value for a given key, or uses the `defaultValue` if not key is found
     * 
     * @param key Key of the element.
     * @param defaultValue The default value if the key is not present.
     * @returns Value for the given key or the default value.
     */
    getSome(key: K, defaultValue: V): V {
        try {
            return this.get(key);
        } catch(err) { // TODO check that this is key not found error
            return defaultValue;
        }
    }
  
    /**
     * Delete element with key if present, otherwise do nothing.
     * 
     * @param key Key to remove.
     */
    delete(key: K): void {
        // TODO implement delete()
        throw new Error("TODO implement delete()")
    }
    //alias to match rust sdk
    remove(key: K): void {
        this.delete(key);
    }
  
  
    /**
     * Get a range of values from a start key to an end key exclusive.
     * If end is greater than max key, include start to max inclusive.
     * 
     * @param start Key for lower bound (inclusive).
     * @param end Key for upper bound (exclusive).
     * @returns Range of values corresponding to keys within start and end bounds.
     */
    values(start: K, end: K): V[] {
        // TODO implement range()
        throw new Error("TODO implement values()");
    }

    /**
     * Get a range of keys from a start key to an end key exclusive.
     * If end is greater than max key, include start to max inclusive.
     * 
     * @param start Key for lower bound (inclusive).
     * @param end Key for upper bound (exclusive).
     * @returns Range of keys within start and end bounds.
     */
    keys(start: K, end: K): K[] {
        // TODO implement range()
        throw new Error("TODO implement range()");
    }

    /**
     * Get a range of entries from a start key to an end key exclusive.
     * If end is greater than max key, include start to max inclusive.
     * 
     * @param start Key for lower bound (inclusive).
     * @param end Key for upper bound (exclusive).
     * @returns Range of entries corresponding to keys within start and end bounds.
     */
    entries(start: K, end: K): MapEntry<K, V>[] {
        // TODO implement range()
        throw new Error("TODO implement range()");
    }
  
    /**
     * Returns minimum key.
     * Throws if tree is empty.
     * @returns Minimum key.
     */
    min(): K {
        // TODO implement min()
        throw new Error("TODO implement min()");
    }
  
    /**
     * Returns maximum key.
     * Throws if tree is empty.
     * @returns Maximum key.
     */
    max(): K {
        // TODO implement max()
        throw new Error("TODO implement max()");
    }
  
    /**
     * Returns the maximum key that is strictly less than the key.
     * Throws if empty or if key is lower than or equal to `this.min()`.
     * @param key Key for lower bound (exclusive).
     * @returns Maximum key that is strictly less than given key.
     */
    lower(key: K): K {
        // TODO implement lower()
        throw new Error("TODO implement lower()");
    }
  
    /**
     * Returns the minimum key that is strictly greater than the key.
     * Throws if empty or if key is higher than or equal to `this.max()`.
     * @param key Key for upper bound (exclusive).
     * @returns Minimum key that is strictly greater than given key.
     */
    higher(key: K): K {
        // TODO implement higher()
        throw new Error("TODO implement higher()");
    }
  
    /**
     * Returns the maximum key that is less or equal than the key.
     * Throws if empty or if key is lower than `this.min()`.
     * @param key Key for lower bound (inclusive).
     * @returns Maximum key that is less than or equal to given key.
     */
    lowerOrEqual(key: K): K {
        // TODO implement lowerOrEqual()
        throw new Error("TODO implement lowerOrEqual()");
    }
    //alias to match rust sdk
    floorKey(key: K): K {
        return this.lowerOrEqual(key);
    }
  
    /**
     * Returns the minimum key that is greater or equal than the key.
     * Throws if empty or if key is higher than `this.max()`.
     * @param key Key for upper bound (inclusive).
     * @returns Minimum key that is greater or equal to given key.
     */
    higherOrEqual(key: K): K {
        // TODO implement higherOrEqual()
        throw new Error("TODO implement lowerOrEqual()");
    }
    //alias to match rust sdk
    ceilKey(key: K): K {
        return this.higherOrEqual(key);
    }

    /**
     * Removes all key-value pairs from the tree
     */
    clear(): void {
        // TODO implement clear()
        throw new Error("TODO implement clear()")
    }
}

from near-sdk-as.

willemneal avatar willemneal commented on June 14, 2024

Sounds good, but keep an alias for range, since we want to match the Rust API.

from near-sdk-as.

gitcoinbot avatar gitcoinbot commented on June 14, 2024

@kaiba42 Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!

  • reminder (3 days)
  • escalation to mods (6 days)

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

from near-sdk-as.

gitcoinbot avatar gitcoinbot commented on June 14, 2024

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


@kaiba42 due to inactivity, we have escalated this issue to Gitcoin's moderation team. Let us know if you believe this has been done in error!

  • reminder (3 days)
  • escalation to mods (6 days)

Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days

from near-sdk-as.

kaiba42 avatar kaiba42 commented on June 14, 2024

^ thinking I need to add a comment to address this...

from near-sdk-as.

gitcoinbot avatar gitcoinbot commented on June 14, 2024

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


Work for 300.0 DAI (300.0 USD @ $1.0/DAI) has been submitted by:

  1. @kaiba42

@nearmax please take a look at the submitted work:


from near-sdk-as.

gitcoinbot avatar gitcoinbot commented on June 14, 2024

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


The funding of 300.0 DAI (300.0 USD @ $1.0/DAI) attached to this issue has been approved & issued to @kaiba42.

from near-sdk-as.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.