docs: int getNodeId(long nanoTime) {
          // Check if it is a time to check for updated nodeId. We need to recheck, because if duplicate node ID
          // is assigned during a network split, this will be resolved after a cluster merge.
          // We throttle the calls to avoid contention due to the lock+unlock call in getMemberListJoinVersion().
          int nodeId = this.nodeId;
          if (nodeId != NODE_ID_OUT_OF_RANGE && nextNodeIdUpdate <= nanoTime) {
              int newNodeId = getNodeEngine().getClusterService().getMemberListJoinVersion();
              assert newNodeId >= 0 : "newNodeId=" + newNodeId;
              newNodeId += nodeIdOffset;
              nextNodeIdUpdate = nanoTime + NODE_ID_UPDATE_INTERVAL_NS;
              if (newNodeId != nodeId) {
                  nodeId = newNodeId;
  
                  // If our node ID is out of range, assign NODE_ID_OUT_OF_RANGE to nodeId
                  if ((nodeId & -1 << BITS_NODE_ID) != 0) {
                      outOfRangeMembers.add(getNodeEngine().getClusterService().getLocalMember().getUuid());
                      logger.severe("Node ID is out of range (" + nodeId + "), this member won't be able to generate IDs. "
                              + "Cluster restart is recommended.");
                      nodeId = NODE_ID_OUT_OF_RANGE;
                  }
  
                  // we ignore possible double initialization
                  this.nodeId = nodeId;
                  if (logger.isFineEnabled()) {
                      logger.fine("Node ID assigned to '" + name + "': " + nodeId);
                  }
              }
          }
  
          return nodeId;
      }