Home / Class/ DnsQueryIdSpace Class — netty Architecture

DnsQueryIdSpace Class — netty Architecture

Architecture documentation for the DnsQueryIdSpace class in DnsQueryIdSpace.java from the netty codebase.

Entity Profile

Dependency Diagram

graph TD
  7fd57a0f_a8fa_aafd_24b0_9510d2efbadc["DnsQueryIdSpace"]
  21716c15_3bc6_ee9f_25cf_7032b72484c7["DnsQueryIdSpace.java"]
  7fd57a0f_a8fa_aafd_24b0_9510d2efbadc -->|defined in| 21716c15_3bc6_ee9f_25cf_7032b72484c7
  94bb0907_2912_2818_deed_5797b043f18c["DnsQueryIdSpace()"]
  7fd57a0f_a8fa_aafd_24b0_9510d2efbadc -->|method| 94bb0907_2912_2818_deed_5797b043f18c
  6a637868_c6ba_ffdc_b53b_e78cfea66ea0["DnsQueryIdRange()"]
  7fd57a0f_a8fa_aafd_24b0_9510d2efbadc -->|method| 6a637868_c6ba_ffdc_b53b_e78cfea66ea0
  36354315_78f9_d7b6_6c63_9f282125f564["nextId()"]
  7fd57a0f_a8fa_aafd_24b0_9510d2efbadc -->|method| 36354315_78f9_d7b6_6c63_9f282125f564
  20a7aee7_30f1_992d_adbd_6eb3a0f5c471["pushId()"]
  7fd57a0f_a8fa_aafd_24b0_9510d2efbadc -->|method| 20a7aee7_30f1_992d_adbd_6eb3a0f5c471
  5f78c1cb_35ba_d688_bc73_8211642b15ff["usableIds()"]
  7fd57a0f_a8fa_aafd_24b0_9510d2efbadc -->|method| 5f78c1cb_35ba_d688_bc73_8211642b15ff
  de5f784f_7418_b2ef_1b73_5e45804acc7b["maxUsableIds()"]
  7fd57a0f_a8fa_aafd_24b0_9510d2efbadc -->|method| de5f784f_7418_b2ef_1b73_5e45804acc7b

Relationship Graph

Source Code

resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryIdSpace.java lines 28–212

final class DnsQueryIdSpace {
    private static final int MAX_ID = 65535;
    private static final int BUCKETS = 4;
    // Each bucket is 16kb of size.
    private static final int BUCKET_SIZE = (MAX_ID + 1) / BUCKETS;

    // If there are other buckets left that have at least 500 usable ids we will drop an unused bucket.
    private static final int BUCKET_DROP_THRESHOLD = 500;
    private final DnsQueryIdRange[] idBuckets = new DnsQueryIdRange[BUCKETS];

    DnsQueryIdSpace() {
        assert idBuckets.length == MathUtil.findNextPositivePowerOfTwo(idBuckets.length);
        // We start with 1 bucket.
        idBuckets[0] = newBucket(0);
    }

    private static DnsQueryIdRange newBucket(int idBucketsIdx) {
        return new DnsQueryIdRange(BUCKET_SIZE, idBucketsIdx * BUCKET_SIZE);
    }

    /**
     * Returns the next ID to use for a query or {@code -1} if there is none left to use.
     *
     * @return next id to use.
     */
    int nextId() {
        int freeIdx = -1;
        for (int bucketIdx = 0; bucketIdx < idBuckets.length; bucketIdx++) {
            DnsQueryIdRange bucket = idBuckets[bucketIdx];
            if (bucket != null) {
                int id = bucket.nextId();
                if (id != -1) {
                    return id;
                }
            } else if (freeIdx == -1 ||
                    // Let's make it somehow random which free slot is used.
                    ThreadLocalRandom.current().nextBoolean()) {
                // We have a slot that we can use to create a new bucket if we need to.
                freeIdx = bucketIdx;
            }
        }
        if (freeIdx == -1) {
            // No ids left and no slot left to create a new bucket.
            return -1;
        }

        // We still have some slots free to store a new bucket. Let's do this now and use it to generate the next id.
        DnsQueryIdRange bucket = newBucket(freeIdx);
        idBuckets[freeIdx] = bucket;
        int id = bucket.nextId();
        assert id >= 0;
        return id;
    }

    /**
     * Push back the id, so it can be used again for the next query.
     *
     * @param id the id.
     */
    void pushId(int id) {
        int bucketIdx = id / BUCKET_SIZE;
        if (bucketIdx >= idBuckets.length) {
            throw new IllegalArgumentException("id too large: " + id);
        }
        DnsQueryIdRange bucket = idBuckets[bucketIdx];
        assert bucket != null;
        bucket.pushId(id);

        if (bucket.usableIds() == bucket.maxUsableIds()) {
            // All ids are usable in this bucket. Let's check if there are other buckets left that have still
            // some space left and if so drop this bucket.
            for (int idx = 0; idx < idBuckets.length; idx++) {
                if (idx != bucketIdx) {
                    DnsQueryIdRange otherBucket = idBuckets[idx];
                    if (otherBucket != null && otherBucket.usableIds() > BUCKET_DROP_THRESHOLD) {
                        // Drop bucket on the floor to reduce memory usage, there is another bucket left we can
                        // use that still has enough ids to use.
                        idBuckets[bucketIdx] = null;
                        return;
                    }
                }

Frequently Asked Questions

What is the DnsQueryIdSpace class?
DnsQueryIdSpace is a class in the netty codebase, defined in resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryIdSpace.java.
Where is DnsQueryIdSpace defined?
DnsQueryIdSpace is defined in resolver-dns/src/main/java/io/netty/resolver/dns/DnsQueryIdSpace.java at line 28.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free