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

Serializer/deserializer for hierarchical, multi-type data #348

Open
2 of 4 tasks
tigercosmos opened this issue Jun 6, 2024 · 12 comments
Open
2 of 4 tasks

Serializer/deserializer for hierarchical, multi-type data #348

tigercosmos opened this issue Jun 6, 2024 · 12 comments
Assignees
Labels
enhancement New feature or request performance Profiling, runtime, and memory consumption

Comments

@tigercosmos
Copy link
Collaborator

tigercosmos commented Jun 6, 2024

Implement a serializer/deserializer for hierarchical data of multiple types.

Currently the implementation of CallProfilerSerializer::serialize_caller_profile in 1f03e8e just hardcoded the serialization logic, which could be replaced by a generic JSON serializer.

Progress:

  • General Serializer/Deserializer Interface
  • JSON port
  • YAML port (Low priority)
  • Python port using pybind11
@yungyuc yungyuc added the performance Profiling, runtime, and memory consumption label Jun 6, 2024
@yungyuc
Copy link
Member

yungyuc commented Jun 6, 2024

@tigercosmos Please specify how the general serializer should look like, including supporting the existing JSON serialization in Toggle:

def test_to_json(self):

This may use more discussions. Consider to create a discussion conversion or turn this issue into one.

@tigercosmos
Copy link
Collaborator Author

@yungyuc I like the way Golang does JSON marshaling and unmarshalling, not sure if it is possible to make it in C++.

type Person struct {
    Name   string `json:"name"`
    Age    int    `json:"age"`
    Email  string `json:"email"`
}

func main() {
    person := Person{
        Name:  "Jane Doe",
        Age:   25,
        Email: "[email protected]",
    }

    // Marshal the person struct into JSON data
    jsonData, err := json.Marshal(person)
    if err != nil {
        fmt.Println("Error marshaling to JSON:", err)
        return
    }

    // Print the JSON data
    fmt.Println(string(jsonData))
}
type Person struct {
    Name   string `json:"name"`
    Age    int    `json:"age"`
    Email  string `json:"email"`
}

func main() {
    jsonData := `{"name": "John Doe", "age": 30, "email": "[email protected]"}`

    var person Person

    // Unmarshal the JSON data into the person struct
    err := json.Unmarshal([]byte(jsonData), &person)
    if err != nil {
        fmt.Println("Error unmarshaling JSON:", err)
        return
    }

    // Print the unmarshaled struct
    fmt.Printf("%+v\n", person)
}

@yungyuc
Copy link
Member

yungyuc commented Jun 7, 2024

I do not have a preference and we can follow yours, @tigercosmos . Please author a mock-up example in C++. You can add it in a comment like what you did for golang.

@yungyuc yungyuc added the enhancement New feature or request label Jun 9, 2024
@tigercosmos
Copy link
Collaborator Author

tigercosmos commented Jun 10, 2024

@yungyuc The following is the proposal for the design. There should be no problem applying the design on Toggle or CallProfilerSerializer

The interface:

class JsonSerializable {
public:
    virtual std::string to_json() const = 0;
    virtual void from_json(const std::string& json) = 0;
};

The object inherits the JsonSerializable interface:

class Person : public JsonSerializable {
    std::string name;
    int age;
    std::string email;
    Address address;
    std::vector<std::string> phoneNumbers;

public:
    // macro (to be implemented), should be able to support array, object, nested structure
    // also implement `to_json` and `from_json` in the macro.
    JSON_SERIALIZABLE(
        register("name", name);
        register("age", age);
        register("email", email);
        register("address", address);
        register("phoneNumbers", phoneNumbers);
    )
};

Usage:

Person person(...);
std::string jsonData = person.to_json();
std::cout << jsonData << std::endl; // {"name":"Bob","age":25,"email":"[email protected]", .... }

Person newPerson;
newPerson.from_json(jsonData);

@yungyuc
Copy link
Member

yungyuc commented Jun 11, 2024

@tigercosmos this looks nice! I wonder if it needs to be limited to JSON? The API seems to be applicable to any hierarchical container like YAML and Python dictionary. If that is true, maybe we can rename it from JsonSerializable to SerializableItem. What do you think?

@tigercosmos
Copy link
Collaborator Author

@yungyuc yes, you are correct. for now, let's do the json first, and we can have yaml and other later.

@tigercosmos tigercosmos changed the title General JSON Serializer/Deserilizer General Serializer/Deserilizer Jun 11, 2024
@tigercosmos tigercosmos changed the title General Serializer/Deserilizer General Serializer/Deserializer Jun 11, 2024
@yungyuc yungyuc changed the title General Serializer/Deserializer Serializer/deserializer for hierarchical, multi-type data Jun 11, 2024
@yungyuc
Copy link
Member

yungyuc commented Jun 11, 2024

Great. When do you plan to have a prototype or initial implementation for discussion, @tigercosmos ?

But I think at this stage we only need JSON I/O. YAML, Python dictionary (pickle), and other data formats can be planned as future work.

@tigercosmos
Copy link
Collaborator Author

tigercosmos commented Jun 12, 2024

I can do the JSON part soon, it shouldn't take too much time.

@yungyuc
Copy link
Member

yungyuc commented Aug 25, 2024

@tigercosmos Does any work remain with this issue?

@tigercosmos
Copy link
Collaborator Author

Serialization for Python object using pybind11 can be the next step.

@yungyuc
Copy link
Member

yungyuc commented Aug 25, 2024

Serialization for Python object using pybind11 can be the next step.

Sounds good. Could you please update the progress in the beginning of the issue?

@tigercosmos
Copy link
Collaborator Author

It's updated now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request performance Profiling, runtime, and memory consumption
Projects
Status: In Progress
Development

No branches or pull requests

2 participants