October 2016 ISO C Meeting Report

Trip Report: October 2016 WG14 Meeting

In October 2016, I attended the WG14 (C language committee) meeting in Pittsburgh, Pennsylvania. The meeting was hosted by the Computer Emergency Response Team (CERT) at the Software Engineering Institute (SEI) at Carnegie Mellon University (CMU). We had 25 representatives from 18 organizations in attendance, including CERT, Cisco, IBM, INRIA, Intel, LDRA, Oracle, Perennial, Plum Hall, Siemens, and the University of Cambridge. It was a productive four days spent on two major areas:

  • Work on C11 defect reports aimed at the upcoming C11 Technical Corrigendum (TC) expected to be finalized in 2017. This will be the last revision of C11 to be published. The next revision of C will be a “major” version that is for the time being referred to as C2X.
  • Review of proposals for the next revision of C, C2X. To meet the TC 2017 schedule some C11 defects will have to be deferred to C2X. The C2X charter is in N2086.

Below is a list of some of the interesting C2X proposals the group discussed.

Continue reading “October 2016 ISO C Meeting Report”


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 

Data Encapsulation vs. Immutability in Javascript

A while ago, I wrote a fairly long post attempting to shed some light on a few things you can do in your JavaScript classes to enforce the concept of data encapsulation – or data “hiding”. But as soon as I posted it, I got some flak from a friend who is a Clojure programmer. His first comment about the article was this.

Mutability and data encapsulation are fundamentally at odds.

Eventually, he walked that back – but only just a little bit. His point, though, was intriguing. I asked him to explain what he meant.

Why is it so wrong to return the id in your example? I’m guessing it’s not. It might be darn useful to fetch it. In fact, it might greatly enhance the data model for it to be there. But you feel you must “hide” it. Why? Because it’s mutable or because you must go to great lengths to make it immutable. Because JavaScript. But if you were returning an immutable data structure, you wouldn’t even think about it. All that stress just falls away; you no longer care about hiding your data or encapsulating it. You only care that it’s correct and that it properly conveys the essential complexity of your system.

We’ll ignore his little dig on the language itself, for now. But maybe what he’s saying has some value. I do like the idea of a bunch of “stress just falling away”. Let’s look at where we ended up in that last post about data encapsulation.

const ID = Symbol
class Product {
  constructor (name) {
    this.name = name;
    this[ID] = 2340847;
  }
  related () {
    return lookupRelatedStuff( this[ID] );
  }
}

So, here we’ve done our best to hide the id property using a Symbol as a property key. It’s not accessible within userland, and it’s barely visible unless you know about Reflect.ownKeys() or Object.getOwnPropertySymbols(). And of course, I never mentioned the name property in the last article. But the truth is, it suffers from the same issues that plague the id property. It really shouldn’t change. But to accomplish that, I have to replace every this.name with this[NAME] using a Symbol for the property key. And as my friend said, these properties are arguably useful in userland. I just don’t want them changed. I want immutability. How can I do this using JavaScript?

Is it cold in here, or is it just me?

Object.freeze() is nothing new. It’s been around forever. Let’s take a look at how we’d use it to make our Product instances immutable.

class Product {
  constructor (name) {
    this.name = name;
    this.id = 2340847;
    // make this instance immutable
    Object.freeze(this);
  }
}
const widget = new Product
// Setting the name to something else has no effect.
widget.name = something-else
widget.name; // lta-widget

There now. That wasn’t so hard, was it? We give a Product instance the deep freeze and return it. What about those situations where you really need to mutate your application state. What if, for example, there’s a price that could change over time? Normally, we’d do something super simple. Like just update the price.

this.price = getUpdatedPrice(this);

But of course, if we’re going for immutability and the safety that comes along with that, then this is clearly not the correct approach. We are mutating the Product instance when we do this.price = someValue(). What can we do about it? One strategy might be to use Object.assign() to copy properties from one object to another, always generating a new object for every data mutation. Perhaps something like this.

class Product {
  updatePrice () {
    // check DB to see if price has changed
    return Object.assign(new Product(), this, { price: getNewPrice(this) } );
  }
}

Now we are getting somewhere. We can use Object.freeze() to make our objects immutable, and then Object.assign() to generate a new object using existing properties whenever something needs to be mutated. Let’s see how well this works.

acmeWidget.updatePrice();
TypeError: Cannot assign to read only property price of object
    at repl:1:23
    at sigintHandlersWrap (vm.js:22:35)
    at sigintHandlersWrap (vm.js:96:12)
    at ContextifyScript.Script.runInThisContext (vm.js:21:12)
    at REPLServer.defaultEval (repl.js:313:29)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer. (repl.js:513:10)
    at emitOne (events.js:101:20)
    at REPLServer.emit (events.js:188:7)

Ugh! This is happening because I’ve got new Product() as the first parameter to the Object.assign() call, and once a Product is constructed, it’s frozen. I need to defer freezing the object until after it’s constructed. I could use a factory function to return frozen instances of Product. But really, why do I need the Product data type at all? Wouldn’t a simple Object be fine? For the sake of simplification and experimentation, let’s give it a shot.

// Use a factory function to return plain old JS objects
const productFactory = (name, price) = Object.freeze({ name, price });

// Always bump the price by 4%! 🙂
const updatePrice = (product) =gt Object.freeze(
      Object.assign({}, product, { price: product.price * 1.04 }));

const widget = productFactory(Acme Widget 1.00)
// ={ name: Acme Widget, price: 1 }

const updatedWidget = updatePrice(widget);
// ={ name: Acme Widget, price: 1.04 }

widget;
// = { name: Acme Widget, price: 1 }

Lingering doubts

I still have doubts, though. For one thing, making a new instance for every change seems pretty inefficient, doesn’t it? And for another, what happens when my data model has nested objects as properties? Do I have to freeze those as well? It turns out, yes I do. All of the properties on my product object are immutable. But properties of nested objects can be changed. That freeze doesn’t go very deep. Maybe I can fix that by just freezing the nested objects.

const productFactory = (name, price) =
  Object.freeze({
    name,
    price,
    metadata: Object.freeze({
      manufacturer: name.split()[0]
    })
  });

Well, that’s OK, perhaps. But there is still a problem here. Can you tell what it is? What if my data model is nested several layers deep? That’s not very uncommon, and now my factory ends up looking something like this.

const productFactory = (name, price) =
  Object.freeze({
    name,
    price,
    metadata: Object.freeze({
      manufacturer: name.split()[0],
      region: Object.freeze({
        country: Denmark
        address: Object.freeze({
          street: HCA Way
          city: Copenhagen
        })
      })
    })
  });

Ugh! This can start to get ugly real fast. And we haven’t even started to discuss collections of objects, like Arrays. Maybe my friend was right. Maybe this is a language issue.

You feel you must “hide” it. Why? Because it’s mutable or because you must go to great lengths to make it immutable. Because JavaScript.

OK, so is this it? Should I just throw in the towel and give up on immutability in my JavaScript applications? After all, I’ve gone this far without it. And I didn’t have that many bugs. Really… I promise! Well, if you want, to embrace this style fully is to write your application in Clojure or Scala or a similarly designed language where data is immutable. This is a fundamental part of the Clojure language. Instead of spending all of your time reading blog posts about fitting a square peg into a round hole, with Clojure you can just focus on writing your application and be done with it. But maybe that’s not an option. Maybe you’ve got to follow company language standards. And anyway, some of us kind of do like writing code in JavaScript, so let’s, for the sake of argument, take a look at some options. But first, let’s just review why we’re going to all of this trouble.

The case for immutability

So much of what makes software development hard (other than cache invalidation, and naming) has to do with state maintenance. Did an object change state? Does that mean that other objects need to know about it? How do we propagate that state across our system? objects, if we shift our thinking about data so that everything is simply a value, then there is no state maintenance to worry about. Don’t think of references to these values as variables. It’s just a reference to a single, unchanging value. But this shift in thinking must also affect how we structure and think about our code. Really, we need to start thinking more like a functional programmer. Any function that mutates data, should receive an input value, and return a new output value – without changing the input. When you think about it, this constraint pretty much eliminates the need for the classthis. Or at least it eliminates the use of any data type that can modify itself in the traditional sense, for example with an instance method. In this worldview, the only use for class is namespacing your functions by making them static. But to me, that seems a little weird. Wouldn’t it just be easier to stick to native data types? Especially since the module system effectively provides namespacing for us. Exports are namespaced by whatever name we choose to bind them to when require() file.

product.js

const factory = (name, price) = Object.freeze({ name, price });

const updatePrice = (product) = Object.freeze(
  Object.assign({}, product, { price: product.price * 1.04 }));

module.exports = exports = { factory, updatePrice };

app.js

const Product = require(/product.js&);
Product.factory; // = [Function: factory]
Product.updatePrice; // = [Function: updatePrice]

For now, just keep these few things in mind.

  • Think of variables (or preferably consts) as values not objects. A value cannot be changed, while objects can be.
  • Avoid the use of class and this. Use only native data types, and if you must use a class, don’t ever modify its internal properties in place.
  • Never mutate native type data in place, functions that alter the application state should always return a copy with new values.

That seems like a lot of extra work

Yeah, it is a lot of extra work, and as I noted earlier, it sure seems inefficient to make a full copy of your objects every time you need to change a value. Truthfully, to do this properly, you need to be using shared persistent data structures which employ techniques such as hash map tries and vector tries to efficiently avoid deep copying. This stuff is hard, and you probably don’t want to roll your own. I know I don’t.

Someone else has already done it

Facebook has released a popular NPM module called, strangely enough,immutable. By employing the techniques above, immutable takes care of the hard stuff for you, and provides an efficient implementation of

A mutative API, which does not update the data in-place, but instead always yields new updated data.

Rather than turning this post into an immutable module tutorial, I will just show you how it might apply to our example data model. The immutable module has a number of different data types. Since we’ve already seen our Product model as a plain old JavaScript Object, it probably makes the most sense to use the Map data type from immutable. product.js

const Immutable = require(immutable);
const factory = (name, price) =Immutable.Map({name, price});
module.exports = exports = { factory };

That’s it. Pretty simple, right? We don’t need an updatePrice function, since we can just use set(), and Immutable.Map handles the creation of a new reference. Check out some example usage. app.js

const Product = require(/product.js);

const widget = Product.factory(Acme widget, 1.00);
const priceyWidget = widget.set(price, 1.04);
const clonedWidget = priceyWidget;
const anotherWidget = clonedWidget.set(price, 1.04);

console.log(widget); // = Map {name: 1 }
console.log(priceyWidget); // = Map {Acme widget: 1.04 }
console.log(clonedWidget); // = Map { Acme widget: 1.04 }
console.log(anotherWidget); // = Map { Acme widget: 1.04 }

Things to take note of here: first, take a look at how we are creating the priceyWidget reference. We use the return value from widget.set(), which oddly enough, doesn’t actually change the widget reference. Also, I’ve cloned priceyWidget. To create a clone we just need to assign one reference to another. And then, finally, an equivalent value for price is set on clonedWidget to create yet another value.

Value comparisons

Let’s see how equality works with these values.

// everything but has a price of 1.04
// so is not equivalent to any of them
assert(widget !== priceyWidget);
assert(widget !== clonedWidget);
assert(!widget.equals(priceyWidget));
assert(!widget.equals(clonedWidget));
assert(!widget.equals(anotherWidget));

This makes intuitive sense. We create a widget and when we change a property, the return value of the mutative function provides us with a new value that is not equivalent as either a reference or value. Additional references to the new value instance priceyWidget are also not equivalent. But what about comparisons between priceyWidget and its clone. Or priceyWidget and a mutated version of the clone that actually contains all of the same property values. Whether we are comparing references with === or using the deep Map.equals, we find that equivalence holds. How cool is that?

// priceyWidget is equivalent to its clone
assert(priceyWidget === clonedWidget);
assert(priceyWidget.equals(clonedWidget));

// Its also equivalent to another, modified value
// because, unlike setting a new value for 
// to create this modification didnt
// actually change the value.
assert(priceyWidget === anotherWidget);
assert(priceyWidget.equals(anotherWidget));

This is just the beginning

When I started writing this post, it was primarily as a learning experience for me. My friend’s friendly jab got me interested in learning about immutable data in JavaScript, and how to apply these techniques to my own code. What I really learned is that, while immutable systems have benefits, there are many hurdles to jump through when writing code this way in JavaScript. Using a high-quality package like immutable.js is a good way to address these complexities. I don’t think I will immediately change all of my existing packages to use these techniques. Now I have a new tool in my toolbox, and this exploration has opened my eyes to the benefits of thinking about data in new ways. If any of this has peaked your interest, I encourage you to read further. Topics such as nested data structures, merging data from multiple values, and collections are all worth exploring. Below, you’ll find links for additional reading.

  • immutable.js documentation: http://facebook.github.io/immutable-js/docs/#/
  • Persistent data structures: http://en.wikipedia.org/wiki/Persistent_data_structure
  • Hash map tries: http://en.wikipedia.org/wiki/Hash_array_mapped_trie
  • Vector tries: http://hypirion.com/musings/understanding-persistent-vector-pt-1

Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 

Leap second – "I Belong to You"

Recently, I was working on a research topic for Red Hat Insights which is a hosted service designed to help people proactively identify and resolve technical issues of Red Hat products. During that time a Chinese romantic comedy film;  “I Belonged to You” was released. On hearing the name, I thought to myself, “that title couldn’t be any better for this post”. Just like the film goes, “I’m only a passerby in your world”. So did the leap second! And soon another leap second is coming – let’s cherish it this time. These little moments in time can be incredibly challenging, and also incredibly interesting. But, before we start talking about leap seconds, let’s introduce some background about time itself.

Continue reading “Leap second – "I Belong to You"”


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 

How To Setup Integration & SOA Tooling For JBoss Developer Studio 10

 The release of the latest JBoss Developer Studio (JBDS) brings with it the questions around how to get started with the various JBoss Integration and BPM product tool sets that are not installed out of the box.

In this series of articles we will outline for you how to install each set of tools and explain which products they are supporting. This should help you in making an informed decision about what tooling you might want to install before embarking on your next JBoss integration project.

There are four different software packs that offer tooling for various JBoss integration products:

  1. JBoss Integration and SOA Development
  2. JBoss Data Virtualization Development
  3. JBoss Business Process and Rules Development

    Tooling is available under software updates with early access enabled.
  4. JBoss Fuse Development

This article will outline how to get started with the JBoss integration and SOA development tooling and any of the JBDS 10 series of releases.

Continue reading “How To Setup Integration & SOA Tooling For JBoss Developer Studio 10”


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 

Data-hiding in ES6 (JavaScript) from an Object Oriented perspective

For a long time during my early career, I was an OO — object oriented — developer. I genuflected regularly in front of the altar of data encapsulation, object hierarchies and static typing. And the syntax. Oh the syntax!

But I have changed, of course, and so much of the dogma and ceremony that I participated in during those times has come to seem a lot less important than it was 20 years ago. Languages, and developers evolve. But that doesn’t mean there aren’t some really good lessons to learn.

Take, for instance, data encapsulation.

When I first began to seriously look at JavaScript as a language, data encapsulation – or the lack of it – was one of the things that really stuck in my old OO craw. While I loved the simplicity of the {} data structure, I hated the fact that most properties I chose to add to it were typically just there – sticking out for everyone to see and perhaps corrupt. The language didn’t make it very easy to keep this data protected. How do we handle this?

Continue reading “Data-hiding in ES6 (JavaScript) from an Object Oriented perspective”


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 

August 2016 GNU Toolchain Update

The GNU Toolchain is a collection of  programming tools produced by the GNU Project. The tools are often packaged together due to their common use for developing software applications, operating systems, and low level software for embedded systems.

This blog is part of a regular series covering the latest changes and improvements in the components that make up this Toolchain.  Apart from the announcement of new releases however, the features described here are at the very bleeding edge of software development in the tools.  This does mean that it may be a while before they make it into production releases, although interested parties can always build their own copies of the toolchain in order to try them out.

Continue reading “August 2016 GNU Toolchain Update”


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 

Keeping track of my subscriptions using the Red Hat Content Delivery Network API

In a previous post, where-have-all-my-subscriptions-gone, I mentioned that you can access the Red Hat Content Delivery Network (CDN) using its API — allowing you to query CDN for subscriptions and their usage, registered hosts, and more as well as unregistering hosts, and more.

I wanted to do some analysis for my own subscription usage, so I wrote some scripts that let me more easily tell where my subscriptions are being used.

Since Python scripting is still fairly new to me, and I wanted to learn something new, I decided I would write the primary script using Python 3.

For my use, I needed the scripts to:

  • Tell me which systems are using my subscriptions and pool IDs.
  • When did the system last check in.
  • List any systems with duplicate names. This is an indication that the systems were re-installed without first being unregistered.
  • When did the systems last check in. A system that no longer checks in may no longer exist.

After a little work, I had a script that could give me what I wanted. The script can generate 3 basic reports for me.

  • A pool/subscription usage report
  • A duplicate systems report
  • A report of when systems last checked in and can show me only reports that have not checked in longer than some determined number of days.

Here are some sample reports generated by my Python script. The script accepts the –help option to give details on its options.

Pool Usage Report

            Name                 | Pool ID      | Quantity | Consumed | Exported
--------------------------------------------------------------------------------
Subscription 1                   | 123456abcdef | 300      | 101      | 30
     Attached Systems: | System ID              | Name
                       | 12345678-abcd-1a2b3c4d | system-1 Last Checkin (days): 50
                       | 12345678-abcd-1a2eeeee | system-2 Last Checkin (days): 0

Subscription 2                   | aabbcc1122dd | 10 | 8 | 0
     Attached Systems: | System ID              | Name
                       | bcdef678-af5d-1a2cfd4d | system-3 Last Checkin (days): 9
                       | 12346fde-aeed-1a2abdce | system-4 Last Checkin (days): 5

Duplicate Systems Report

Hosts with duplicates: 197
Duplicate systems: 276
Freeable systems: 79
Count | Name         Last Checkin (EPOCH) |    ID 
-------------------------------------------------------------------
# 11  system-1         1466648032           12345678-abcd-1a2b3c4d
                       1466639184           1b2b32b3-1234-867ab210
                       1466132041           3b2ds525-abdd-a1b1c1d1
                       1465339439           3232bb32-43bc-abcdabcd
                       1464219749           423443dd-7652-12341234
# 10  system-2         1466649410           12345678-abcd-1a2eeeee
                       1466638967           3421dd11-abcd-bdcdeeed
                       1465339174           787dbb8a-42dc-abcdef11
# 10  system-3         1466649256           bcdef678-af5d-1a2cfd4d
                       1466638709           678acb26-6421-bcccad12
                       1464196357           5673ffff-ab12-123bcddd

 

Last Check-In Report

Host     | ID                     | Last Checking (Days) | Entitlements Consumed
--------------------------------------------------------------------------------------------
system-1 | 12345678-abcd-1a2b3c4d | 162                  | 1
system-2 | 12345678-abcd-1a2eeeee | 156                  | 1
system-3 | bcdef678-af5d-1a2cfd4d | 156                  | 0
system-4 | 23422323-1234-11223344 | 155                  | 0
system-5 | ababaaba-4321-aabbccdd | 153                  | 1
system-2 | 3421dd11-abcd-bdcdeeed | 153                  | 0

Now that I have my reports, I can see that I have hundreds of systems I need to remove. That is a lot of pointing and clicking in the Red Hat Content Delivery Network (CDN) portal.

API to the rescue again! It allows me to remove systems and free up the subscriptions as well. This is awesome, life is good.

I wrote a bash script to remove systems from being registered. Sorry no Python here, I am being a bit lazy and I know I can get the bash script done quicker than writing another Python script. It uses the following curl command to remove a host from being registered to CDN, I wrote a bash script that will take a list of system UUIDs from standard input.

curl --silent -X DELETE -u CDN_USER:CDN_PASSWORD -k "https://subscription.rhn.redhat.com/subscription/consumers/SYSTEM_UUID"

I went back and added an option to the Python script to tell it to not print the header information. I also modified the output of the duplicate systems report to add a hash mark in front of the most recently checked in system. This will allow me to pass the -v option to grep so it ignores the most recently checked in system in each set of duplicates. With a little help from awk, piping the output of the duplicates report through grep and then awk gives me a list of system UUIDs  that can be used as input to the list of hosts to remove.

The Last Check-In report can either display the last check-in for all the registered systems by using the –checkin option alone. Or the report can be generated to list the systems that have not registered within a certain number of days by using –checkin and –days options.

Now I can easily remove all my duplicate systems, except the most recently registered one, and I can remove all systems that have not checked in recently.

I imagine others might find these scripts useful as well, so I am making them available via GitHub.

https://github.com/jobbler/cdn_reports

The README file should be fairly explanatory on how to use the scripts, so I am not including the information here since it would make this blog post very long.

Please be careful using these scripts, they are only tested when I need to clean up my systems in CDN.

Enjoy and I hope others find them useful as well. Better yet, make something even better from them.


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 

How to run Java fat-jars in Docker, Kubernetes and Openshift

In a world where agility matters, the pursuit to reduce wasted time in environment configurations is apparent in many technologies. Some techniques, such as Virtual Machines, that enable distribution of pre-configured images have existed for decades, while others like Linux containers are more recent.

Even platforms like Java allow developers to package all dependencies, resources and configuration files in single JAR (Java Archive) file. What started initially as way to have executable Java classes in Java SE (Standard Edition), has now gained notoriety also in the Enterprise. The promise to deliver runnable servers in a “fat-jar” that contains not only your application, but also the server runtime and its resources (libraries, datasources, transaction configuration, etc); made projects like WildFly Swarm, Spring Boot and Vert.x become very popular in “Java land”.

Although these projects allow the “packaging” of the server runtime, an elastic environment like “Cloud computing” stands in need of another “layer” of wrapping, and Linux containers are perfect for it. When you wrap your “fat-jar” in a container, you can also provide a custom execution environment for you JAR file that provides an Operational System, the Java Virtual Machine, and it can also be enriched with JMX (Java Management Extensions) that enable easy monitoring of the JVM. You can also set configuration flags that enable debugging, etc.

Continue reading “How to run Java fat-jars in Docker, Kubernetes and Openshift”


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 


For more information about Red Hat OpenShift and other related topics, visit: OpenShift, OpenShift Online.

Red Hat at the ISO C++ Standards Meeting (March 2016): Library

Earlier this year I attended the WG21 C++ standards committee meeting in Jacksonville, Florida, and as usual I spent most of my time in the Library and Library Evolution Working Groups. You can read about some of the other groups’ work in Jason’s Core report and Torvald’s Parallelism & Concurrency report.

As Jason wrote, several of the Technical Specifications published in the last few years were proposed for inclusion into the next revision of the C++ standard (C++17) and most of them added new features to the Standard Library. That meant that the Library Working Group spent much of the week doing careful review of those large documents, to ensure that what was added to the standard was correctly specified and that it was coherent with the rest of the library. This blog summarizes some of the significant changes from this meeting.

Continue reading “Red Hat at the ISO C++ Standards Meeting (March 2016): Library”


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!

 

How to avoid wasting megabytes of memory a few bytes at a time

Maybe you have so much memory in your computer that you never have to worry about it — then again, maybe you find that some C or C++ application is using more memory than expected. This could be preventing you from running as many containers on a single system as you expected, it could be causing performance bottlenecks, and it could even be forcing you to pay for more memory in your servers.

You do some quick “back of the envelope” calculations to estimate the amount of memory your application should be using, based on the size of each element in some key data structures, and the number of those data structures in each array. You think to yourself, “That doesn’t add up! Why is the application using so much more memory?” The reason it doesn’t add up is that you didn’t take into account the memory space being wasted in the layout of the data structures.

Continue reading “How to avoid wasting megabytes of memory a few bytes at a time”


Join Red Hat Developers, a developer program for you to learn, share, and code faster – and get access to Red Hat software for your development.  The developer program and software are both free!