Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: 多次反序列化结果不一致 #8519

Open
cnsource opened this issue Feb 4, 2025 · 0 comments
Open

[Bug]: 多次反序列化结果不一致 #8519

cnsource opened this issue Feb 4, 2025 · 0 comments

Comments

@cnsource
Copy link

cnsource commented Feb 4, 2025

Image

结果错误:
-2202
-2202
-2202
-2202
-2202
-2202
10
-2202
-2202
-2202

其中一次是10,循环调用serializeTree会出现该问题。

`
namespace com.test;

table TreeNodeFB {
id:string;
name:string;
owner_id: string;
}

table TreeNodeArrayContainer {
nodes: [TreeNodeFB];
}

root_type TreeNodeArrayContainer;

`

package com.test;

import java.util.List;

public class TreeNode {
    private String id;
    private String name;
    private String ownerId;
    private List<TreeNode> children;

    public TreeNode() {
    }

    public TreeNode(String id, String name, String ownerId, List<TreeNode> children) {
        this.id = id;
        this.name = name;
        this.ownerId = ownerId;
        this.children = children;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getOwnerId() {
        return ownerId;
    }

    public void setOwnerId(String ownerId) {
        this.ownerId = ownerId;
    }

    public List<TreeNode> getChildren() {
        return children;
    }

    public void setChildren(List<TreeNode> children) {
        this.children = children;
    }
}

public class TreeGenerator {
    public static List<TreeNode> generateTree(int totalNodes, int maxDepth, int maxChildrenPerNode) {
        if (totalNodes <= 0 || maxDepth <= 0 || maxChildrenPerNode <= 0) {
            throw new IllegalArgumentException("Invalid parameters");
        }

        List<TreeNode> allNodes = new ArrayList<>();
        TreeNode root = new TreeNode(UUID.randomUUID().toString(), "Root", null, new ArrayList<>());
        allNodes.add(root);

        int nodesCreated = 1;
        int currentDepth = 0;

        // 使用队列来处理每一层的节点
        List<TreeNode> currentNodes = new ArrayList<>();
        currentNodes.add(root);

        while (nodesCreated < totalNodes && currentDepth < maxDepth) {
            List<TreeNode> nextLevelNodes = new ArrayList<>();
            for (TreeNode node : currentNodes) {
                // 每个节点随机生成 0 到 maxChildrenPerNode 个子节点
                int childCount = (int) (Math.random() * (maxChildrenPerNode + 1));
                for (int i = 0; i < childCount && nodesCreated < totalNodes; i++) {
                    TreeNode child = new TreeNode(UUID.randomUUID().toString(), "Node-" + nodesCreated, node.getId(), null);
                    allNodes.add(child);
                    nextLevelNodes.add(child);
                    nodesCreated++;
                }
            }
            currentNodes = nextLevelNodes;
            currentDepth++;
        }

        return allNodes;
    }
}

public class TreeService {
    public byte[] serializeTree(List<TreeNode> treeNodes) {
        FlatBufferBuilder builder = new FlatBufferBuilder();

        int[] offsets = new int[treeNodes.size()];

        for (int i = 0; i < treeNodes.size(); i++) {
            TreeNode treeNode = treeNodes.get(i);

            int idOffset = builder.createString(treeNode.getId());
            int nameOffset = builder.createString(treeNode.getName());
            int ownerOffset = builder.createString(ObjectUtils.isEmpty(treeNode.getOwnerId()) ? "0" : treeNode.getOwnerId());

            int treeNodeOffset = TreeNodeFB.createTreeNodeFB(
              builder,
              idOffset,
              nameOffset,
              ownerOffset
            );

           offsets[i] = treeNodeOffset;
        }

        TreeNodeArrayContainer.startNodesVector(builder, offsets.length);

        for (int offset : offsets) {
            TreeNodeArrayContainer.addNodes(builder, offset);
        }

        int container = TreeNodeArrayContainer.endTreeNodeArrayContainer(builder);

        TreeNodeArrayContainer.finishTreeNodeArrayContainerBuffer(builder, container);

        byte[] bytes = builder.sizedByteArray();

        ByteBuffer buffer = ByteBuffer.wrap(bytes);

        ByteBufferUtil.removeSizePrefix(buffer);

        TreeNodeArrayContainer arrayContainer = TreeNodeArrayContainer.getRootAsTreeNodeArrayContainer(buffer);

        System.out.println(arrayContainer.nodesLength());

        return bytes;
    }
}

@RestController
public class TreeController {

    private final TreeService treeService;

    public TreeController(TreeService treeService) {
        this.treeService = treeService;
    }

    @CrossOrigin
    @GetMapping("/tree")
    public ResponseEntity<?> getTree(@RequestParam(value = "tree", defaultValue = "false") boolean generateTree) {

        List<TreeNode> treeNodes;
        if (generateTree) {
            // 生成一个包含 20 节点的树
            treeNodes = TreeGenerator.generateTree(20, 7, 45);
        } else {
            // 返回一个空的根节点
            treeNodes = List.of(new TreeNode("root", "Root", null, new ArrayList<>()));
        }

        byte[] bytes = treeService.serializeTree(treeNodes);

        return ResponseEntity.ok(bytes);
    }

}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant